10.07.2015 Views

Using TCP Adapters with Ensemble - InterSystems Documentation

Using TCP Adapters with Ensemble - InterSystems Documentation

Using TCP Adapters with Ensemble - InterSystems Documentation

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong><strong>Ensemble</strong> Version 2012.2 31 August 2012Copyright © 2012 <strong>InterSystems</strong> CorporationAll rights reserved.This book was assembled and formatted in Adobe Page Description Format (PDF) using tools and information from the following sources:Sun Microsystems, RenderX, Inc., Adobe Systems, and the World Wide Web Consortium at www.w3c.org.The primary document developmenttools were special-purpose XML-processing applications built by <strong>InterSystems</strong> using Caché and Java., ,Caché WEBLINK, Distributed Cache Protocol, M/SQL, M/NET, and M/PACT are registered trademarks of <strong>InterSystems</strong> Corporation., , , ,<strong>InterSystems</strong> Jalapeño Technology, Enterprise Cache Protocol, ECP, and <strong>InterSystems</strong> Zen are trademarks of <strong>InterSystems</strong> Corporation.All other brand or product names used herein are trademarks or registered trademarks of their respective companies or organizations.This document contains trade secret and confidential information which is the property of <strong>InterSystems</strong> Corporation, One Memorial Drive,Cambridge, MA 02142, or its affiliates, and is furnished for the sole purpose of the operation and maintenance of the products of <strong>InterSystems</strong>Corporation. No part of this publication is to be used for any other purpose, and this publication is not to be reproduced, copied, disclosed,transmitted, stored in a retrieval system or translated into any human or computer language, in any form, by any means, in whole or in part,<strong>with</strong>out the express prior written consent of <strong>InterSystems</strong> Corporation.The copying, use and disposition of this document and the software programs described herein is prohibited except to the limited extentset forth in the standard software license agreement(s) of <strong>InterSystems</strong> Corporation covering such programs and related documentation.<strong>InterSystems</strong> Corporation makes no representations and warranties concerning such software programs other than those set forth in suchstandard software license agreement(s). In addition, the liability of <strong>InterSystems</strong> Corporation for any losses or damages relating to or arisingout of the use of such software programs is limited in the manner set forth in such standard software license agreement(s).THE FOREGOING IS A GENERAL SUMMARY OF THE RESTRICTIONS AND LIMITATIONS IMPOSED BY INTERSYSTEMSCORPORATION ON THE USE OF, AND LIABILITY ARISING FROM, ITS COMPUTER SOFTWARE. FOR COMPLETE INFORMATIONREFERENCE SHOULD BE MADE TO THE STANDARD SOFTWARE LICENSE AGREEMENT(S) OF INTERSYSTEMS CORPORATION,COPIES OF WHICH WILL BE MADE AVAILABLE UPON REQUEST.<strong>InterSystems</strong> Corporation disclaims responsibility for errors which may appear in this document, and it reserves the right, in its sole discretionand <strong>with</strong>out notice, to make substitutions and modifications in the products and practices described 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


List of FiguresFigure 2–1: <strong>Using</strong> the <strong>TCP</strong> Counted Inbound Adapter and Business Service ........................................ 6Figure 3–1: Business Operation and <strong>Using</strong> the <strong>TCP</strong> Counted Outbound Adapter ................................ 14Figure 4–1: <strong>Using</strong> the <strong>TCP</strong> Counted XML Inbound Adapter and Business Service ............................ 22Figure 5–1: Business Operation and <strong>Using</strong> the <strong>TCP</strong> Counted XML Outbound Adapter ...................... 28Figure 6–1: <strong>Using</strong> the <strong>TCP</strong> Text Line Inbound Adapter and Business Service ..................................... 36Figure 7–1: Business Operation and <strong>Using</strong> the <strong>TCP</strong> Text Line Outbound Adapter .............................. 44<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>v


List of TablesTable 6–1: <strong>TCP</strong> Status Service Commands ........................................................................................... 42vi<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


About This Book<strong>TCP</strong> is a transport layer protocol that supports many types of higher-level communication protocol. This book providesinstructions for configuring and using the <strong>TCP</strong> adapters that <strong>Ensemble</strong> provides. These adapters support several simpletypes of <strong>TCP</strong>, <strong>with</strong> inbound and outbound versions of each type.This book contains the following sections:• “Choosing a <strong>TCP</strong> Adapter” provides information on all the <strong>TCP</strong> adapters, some of which are automatically includedin specialized <strong>Ensemble</strong> business hosts, discussed in other books.• “<strong>Using</strong> the <strong>TCP</strong> Counted Inbound Adapter” discusses the inbound adapter you use for a counted block <strong>TCP</strong> connection.• “<strong>Using</strong> the <strong>TCP</strong> Counted Outbound Adapter” discusses the outbound adapter you use for a counted block <strong>TCP</strong> connection.• “<strong>Using</strong> the <strong>TCP</strong> Counted XML Inbound Adapter” discusses the inbound adapter you use to transfer XML over acounted block <strong>TCP</strong> connection.• “<strong>Using</strong> the <strong>TCP</strong> Counted XML Outbound Adapter” discusses the outbound adapter you use to transfer XML over acounted block <strong>TCP</strong> connection.• “<strong>Using</strong> the <strong>TCP</strong> Text Line Inbound Adapter” discusses the inbound adapter you use for a text line <strong>TCP</strong> connection.• “<strong>Using</strong> the <strong>TCP</strong> Text Line Outbound Adapter” discusses the inbound adapter you use for a text line <strong>TCP</strong> connection.• “Creating Custom <strong>TCP</strong> Adapter Classes” discusses how to create custom <strong>TCP</strong> adapter classes.• “Settings for the Abstract <strong>TCP</strong> <strong>Adapters</strong>” describes the settings in the two abstract adapter classes on which all thepreceding classes are based.• “Common Tasks in the Management Portal” provides more detail on some of the tasks described in this book.For a detailed outline, see the table of contents.The following books provide related information:• Developing <strong>Ensemble</strong> Productions describes how to create <strong>Ensemble</strong> productions in general.• Configuring <strong>Ensemble</strong> Productions describes how to configure the settings for <strong>Ensemble</strong> productions, business hosts,and adapters. It provides details on settings not discussed in this book.• Monitoring <strong>Ensemble</strong> describes how to monitor the behavior of the adapter at runtime.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 1


1Choosing a <strong>TCP</strong> AdapterThis chapter discusses the following topics:• Choosing an Inbound Adapter• Choosing an Outbound Adapter1.1 Choosing an Inbound AdapterThe EnsLib.<strong>TCP</strong>.InboundAdapter is an abstract class that provides methods to allow you to establish and maintain a connectionbetween a <strong>TCP</strong> client and <strong>Ensemble</strong> as a <strong>TCP</strong> listener. No <strong>Ensemble</strong> business service references theEnsLib.<strong>TCP</strong>.InboundAdapter class directly, because this class does not have any specific methods for parsing data acrossthe <strong>TCP</strong> connection. You must either use an existing subclass or implement your own subclass.The following list describes scenarios and applicable adapters.Inbound HTTPInbound SOAPInbound <strong>TCP</strong>See <strong>Using</strong> HTTP <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>.See Creating Web Services and Web Clients <strong>with</strong> <strong>Ensemble</strong>.Consider using these adapters for inbound <strong>TCP</strong> connections:• <strong>TCP</strong> Counted Inbound Adapter• <strong>TCP</strong> Counted XML Inbound Adapter• <strong>TCP</strong> Text Line Inbound AdapterInbound <strong>TCP</strong> for ASTM message routingIf you use the built-in <strong>Ensemble</strong> business services for ASTM, a <strong>TCP</strong> adapter comes into the <strong>Ensemble</strong> configurationautomatically. See “ASTM Business Services” in the chapter “Elements of a Routing Production” in the<strong>Ensemble</strong> ASTM Development Guide.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 3


Choosing a <strong>TCP</strong> AdapterInbound <strong>TCP</strong> for HL7 message routingIf you use the built-in <strong>Ensemble</strong> business services for HL7, a <strong>TCP</strong> adapter comes into the <strong>Ensemble</strong> configurationautomatically. See “HL7 Business Services” in the chapter “Elements of a Routing Production” in the <strong>Ensemble</strong>HL7 Version 2 Development Guide.Inbound <strong>TCP</strong> for X12 message routingIf you use the built-in <strong>Ensemble</strong> business services for X12, a <strong>TCP</strong> adapter comes into the <strong>Ensemble</strong> configurationautomatically. See “X12 Business Services” in the chapter “Elements of a Routing Production” in the <strong>Ensemble</strong>HL7 Version 2 Development Guide.If your configuration uses <strong>TCP</strong> and you cannot get what you need from any of the inbound adapters provided, you candevelop a new inbound adapter class based on the EnsLib.<strong>TCP</strong>.InboundAdapter or any of its subclasses. See the chapter“Creating Custom <strong>TCP</strong> Adapter Classes.”1.2 Choosing an Outbound AdapterThe EnsLib.<strong>TCP</strong>.OutboundAdapter establishes and maintains a connection between <strong>Ensemble</strong> as a <strong>TCP</strong> client and anexternal <strong>TCP</strong> listener. No <strong>Ensemble</strong> business operation references the EnsLib.<strong>TCP</strong>.OutboundAdapter class directly, becausethis class does not have any specific methods for parsing data across the <strong>TCP</strong> connection. You must either use an existingsubclass or implement your own subclass.The following list describes scenarios and applicable adapters.Outbound <strong>TCP</strong>Consider using these adapters for outbound <strong>TCP</strong> connections:• <strong>TCP</strong> Counted Outbound Adapter• <strong>TCP</strong> Counted XML Outbound Adapter• <strong>TCP</strong> Text Line Outbound AdapterOutbound <strong>TCP</strong> for ASTM message routingIf you use the built-in <strong>Ensemble</strong> business operations for ASTM, <strong>Ensemble</strong> includes a <strong>TCP</strong> adapter in the configurationautomatically. See “ASTM Business Operations” in the chapter “Elements of a Routing Production” inthe <strong>Ensemble</strong> ASTM Development Guide.Outbound <strong>TCP</strong> for HL7 Message RoutingIf you use the built-in <strong>Ensemble</strong> business operations for HL7, <strong>Ensemble</strong> includes a <strong>TCP</strong> adapter in the configurationautomatically. See “HL7 Business Operations” in the chapter “Elements of a Routing Production” in the<strong>Ensemble</strong> HL7 Version 2 Development Guide.Outbound <strong>TCP</strong> for X12 Message RoutingIf you use the built-in <strong>Ensemble</strong> business operations for X12, <strong>Ensemble</strong> includes a <strong>TCP</strong> adapter in the configurationautomatically. See “X12 Business Operations” in the chapter “Elements of a Routing Production” in the<strong>Ensemble</strong> HL7 Version 2 Development Guide.If your configuration uses <strong>TCP</strong> and you cannot get what you need from any of the inbound adapters provided, you candevelop a new inbound adapter class based on the EnsLib.<strong>TCP</strong>.OutboundAdapter or any of its subclasses. See the chapter“Creating Custom <strong>TCP</strong> Adapter Classes.”4 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


2<strong>Using</strong> the <strong>TCP</strong> Counted Inbound AdapterEnsLib.<strong>TCP</strong>.CountedInboundAdapter is the adapter class to use for incoming <strong>TCP</strong> connections over which a <strong>TCP</strong> client and<strong>TCP</strong> listener exchange blocks of data, <strong>with</strong> the block length specified in the first 4 bytes of the block.EnsLib.<strong>TCP</strong>.CountedInboundAdapter uses the block length to acquire the meaningful portion of the data from the clientapplication. It then passes this data to the associated business service <strong>with</strong>in <strong>Ensemble</strong>.This chapter explains how to use the EnsLib.<strong>TCP</strong>.CountedInboundAdapter. It discusses the following topics:• Background Information• <strong>Using</strong> the Adapter• Creating a New Business Service Class• Sample Business Service Class Code• Adapter Settings2.1 Background InformationThe production configuration must include a business service, dedicated to the EnsLib.<strong>TCP</strong>.CountedInboundAdapter, thatknows how to receive and process the data that this adapter provides. In building your <strong>Ensemble</strong> production, you will eitherchoose or create a business service that works <strong>with</strong> the EnsLib.<strong>TCP</strong>.CountedInboundAdapter.This business service decides what to do <strong>with</strong> the incoming data stream. Generally, the business service decides to issue amessage addressed to some <strong>Ensemble</strong> business process, <strong>with</strong> instructions to perform a task using some or all of the inputdata. The details are up to the business service.If the data source expects an acknowledgment or response to its input, the business service is also responsible for formulatingthis response and relaying it back to the data source, via the EnsLib.<strong>TCP</strong>.CountedInboundAdapter. The adapter does notevaluate or supplement the response, but relays it, if it is provided.You can simply set up the EnsLib.<strong>TCP</strong>.CountedInboundAdapter as instructed in the next section, “<strong>Using</strong> the Adapter.”However, you may want more details about how the adapter communicates <strong>with</strong> its configured business service. This sectionprovides those details.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 5


<strong>Using</strong> the <strong>TCP</strong> Counted Inbound AdapterFigure 2–1: <strong>Using</strong> the <strong>TCP</strong> Counted Inbound Adapter and Business ServiceThe figure above shows the flow of a request from an external data source into <strong>Ensemble</strong> after you have set up an <strong>Ensemble</strong>business service to work <strong>with</strong> an inbound adapter. This figure shows the ingoing data stream only; any response simplyretraces this path. The sequence is as follows:1. At production startup, <strong>Ensemble</strong> creates a background process for each of the business services in the productionconfiguration. <strong>Ensemble</strong> can allocate more than one background process per business service. The business service’sconfigured PoolSize specifies the number of background processes.2. Within each background process, <strong>Ensemble</strong> creates an instance of the business service class and an instance of itsassociated inbound adapter class.3. <strong>Ensemble</strong> calls the OnInit() methods of the business service object and inbound adapter object, respectively.4. Thereafter, whenever the production is running and the business service is enabled and scheduled to be active, thefollowing cycle can occur:• Each time the adapter encounters input from its configured data source, it calls the <strong>Ensemble</strong> framework’sProcessInput() method.• The call to ProcessInput() automatically prompts the <strong>Ensemble</strong> framework to call the associated business service’sOnProcessInput() method.• Code <strong>with</strong>in OnProcessInput() determines what to do <strong>with</strong> the incoming data stream. For example, if an<strong>Ensemble</strong> business process needs to be started, the business service formulates an <strong>Ensemble</strong> request message andissues the synchronous or asynchronous call that starts the business process.If the data source expects an acknowledgment or response of some kind, it is the business service’sOnProcessInput() that constructs it. The inbound adapter simply relays this response back to the external datasource.Note:There is no default implementation of OnProcessInput(). The developer of each business service classis responsible for writing an OnProcessInput() method for that class. For instructions, see the nextsection, “<strong>Using</strong> the Adapter.”6 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


<strong>Using</strong> the AdapterAn <strong>Ensemble</strong> production continues running until it is stopped, either programmatically or by an administrator using theManagement Portal. When a production stops, the following events related to inbound adapters occur:1. <strong>Ensemble</strong> disables each business service; no more incoming requests are accepted for this production.2. The OnTearDown() method in each inbound adapter is called.3. All inbound adapter and business service objects are destroyed and their background processes are killed.4. Each business service’s OnProductionStop class method is called, once for each configured item of that class in theproduction.When a business service is disabled by a system administrator, or becomes inactive according to its configured schedule,the production continues to run but the associated inbound adapter is shut down, and its OnTearDown() method is executed,as described above.2.2 <strong>Using</strong> the AdapterOnce you determine that your production needs the EnsLib.<strong>TCP</strong>.CountedInboundAdapter, you can include it in the productionconfiguration as follows:1. Choose or create a business service class that uses the EnsLib.<strong>TCP</strong>.CountedInboundAdapter.2. If you create a new business service class, be sure to:• Implement its OnProcessInput() method.• Compile the class.3. Configure the production. Add a business service of the chosen class.4. Configure the new business service. To do so, click it and specify values for the settings on the right.To enable it, select the Enabled box.The next sections provide details.2.3 Creating a New Business Service ClassThe simplest way to deploy the EnsLib.<strong>TCP</strong>.CountedInboundAdapter is to choose an existing business service class thatalready uses it.If no existing class has the functionality you need, create a business service class that uses theEnsLib.<strong>TCP</strong>.CountedInboundAdapter. Create the new class in Studio as follows:1. From the File menu, choose New. A dialog pops up. Edit it as follows:• Click on the Production tab.• Select the Business Service icon and click OK.• Enter a package and class name and click Next.Important:Be sure to avoid reserved package names; see “Reserved Package Names” in Developing<strong>Ensemble</strong> Productions.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 7


<strong>Using</strong> the <strong>TCP</strong> Counted Inbound Adapter• Choose EnsLib.<strong>TCP</strong>.CountedInboundAdapter from the drop-down list.• Click Finish.The result is a template class like the following:Class Dev.Test.NewService1Extends Ens.BusinessService [ ProcedureBlock ]{Parameter ADAPTER = "EnsLib.<strong>TCP</strong>.CountedInboundAdapter";Method OnProcessInput(pInput As %RegisteredObject,pOutput As %RegisteredObject) As %Status{Quit $$$ERROR($$$NotImplemented)}}2. Implement the OnProcessInput() method in your new business service class. This is the method that uses the inputdata gathered by the EnsLib.<strong>TCP</strong>.CountedInboundAdapter.You can implement the OnProcessInput() method by replacing the following line in the template class <strong>with</strong> your owncode:Quit $$$ERROR($$$NotImplemented)Your OnProcessInput() method must know the types of incoming and outgoing data for communicating <strong>with</strong> theEnsLib.<strong>TCP</strong>.CountedInboundAdapter. However, the New Business Service Wizard specifies both types in theOnProcessInput() method signature as the generic object type %RegisteredObject.<strong>InterSystems</strong> suggests that, as your first action in coding the new business service, you change each OnProcessInput()argument to its specific type passed from the adapter:Method OnProcessInput(pInput As %Library.GlobalCharacterStream,Output pOutput As %Library.AbstractStream) As %StatusWhere:• pInput is of type %Library.GlobalCharacterStream and contains the incoming data stream that the <strong>TCP</strong> client hasdirected to the adapter.• pOutput is of type %Library.AbstractStream and contains any response that the business service might provide tothe <strong>TCP</strong> client.Keep in mind that the method must quit by returning a %Status object. See the code sample in the next section,“Sample Business Service Class Code.”3. Optionally, you may implement the OnConnect() callback method in your business service class.OnConnect() is available for a <strong>TCP</strong> inbound adapter to call back to its associated business service. If present in thebusiness service, this method is called each time the <strong>TCP</strong> inbound adapter establishes a new connection to or from aremote system.If you add an OnConnect() method to your business service class, it must have the following signature:Method OnConnect(pTimeout As %Numeric) As %StatusImplement an OnConnect() method in your business service if you need to take some action each time a new connectionis established, for example to send a logon sequence or a handshake token. The timeout argument is automaticallyprovided by the <strong>TCP</strong> inbound adapter. It takes its value from the ReadTimeout adapter setting. For details aboutReadTimeout, see “Adapter Settings.”Returning an error status from OnConnect() causes the new connection to fail and be disconnected. If an untrappedexception occurs <strong>with</strong>in OnConnect(), the adapter catches it and continues as if OnConnect() were not implemented.8 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


Sample Business Service Class Code4. Compile your new business service class. Compiling also saves it.5. After creating and compiling the business service class in Studio, add an instance of the business service to the productionand configure it using the Management Portal. See the appendix “Common Tasks in the Management Portal.”When you configure the adapter, you specify a value for the AllowedIPAddresses settings, along other settings. Notethat AllowedIPAddresses provides a way to enable the adapter to initiate the connection; see “Adapter Settings.”2.4 Sample Business Service Class CodeThe following is an example of a business service class that references the EnsLib.<strong>TCP</strong>.CountedInboundAdapter.Class Test.HL7v3.InterfaceEngine.Service.HL7<strong>TCP</strong>InExtends Ens.BusinessService [ ProcedureBlock ]{Parameter ADAPTER = "EnsLib.<strong>TCP</strong>.CountedInboundAdapter";Parameter SINGLEPOOLJOB = 1;Parameter SETTINGS = "TargetConfigNames";/// Configuration item to which to send messagesProperty TargetConfigNames As %String;Method OnProcessInput(pInput As %GlobalCharacterStream,pOutput As %RegisteredObject) As %Status{Set $ZTrap = "OnProcessInputET"Set tRequest =##class(Test.HL7v3.InterfaceEngine.Request.Message).%New()Set tRequest.Stream = pInputSet tRequest.DocType = $Case(pInput.Size < 10000, 1:"MCOA", :"CDAR2")If (..TargetConfigNames '= "") {For tCount = 1:1:$Length(..TargetConfigNames, ",") {Set tTarget =$ZStrip($Piece(..TargetConfigNames, ",", tCount), "W")Set tStatus = ..SendRequestAsync(tTarget, tRequest)}}Quit $$$OKOnProcessInputETSet $ZTrap = ""Quit $$$ERROR($$$GeneralError,"Error in OnProcessInput: "_$ZError)}/// Return an array of connections for/// drawing lines on the config diagramClassMethod OnGetConnections(Output pArray As %String,item As Ens.Config.Item){Set (tValue,tIndex)=""For {Set tIndex = item.Settings.Next(tIndex) Quit:tIndex=""Set tSetting = item.Settings.GetAt(tIndex)If tSetting.Name="TargetConfigNames" Set tValue=tSetting.Value}For i=1:1:$L(tValue,",") {Set tOne=$P(tValue,",",i)Continue:""=tOneSet pArray(tOne)=""}Quit}}<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 9


<strong>Using</strong> the <strong>TCP</strong> Counted Inbound Adapter2.5 Adapter SettingsThis topic describes the settings that are specific to the EnsLib.<strong>TCP</strong>.CountedInboundAdapter associated <strong>with</strong> the businessservice. For settings not listed here, see “Business Service Settings” in the chapter “Configuration” in Managing<strong>Ensemble</strong> Productions.AllowedIPAddressesCallIntervalCharsetA comma-separated list of remote IP addresses from which to accept connections. The adapter accepts named IPaddresses, IPV4 addresses, or IPV6 addresses. An optional :port designation is supported; so, for example, bothof the following address formats are acceptable: 192.168.1.22 or 192.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, onlyone address may be given, and if a port is specified, it supersedes the value of the Port setting; otherwise, the Portsetting is used.Number of seconds that the adapter will listen for incoming data from its configured source, before checking fora shutdown signal from the <strong>Ensemble</strong> framework.If the adapter finds input, it acquires the data and passes it to the business service. The business service processesthe data, and then the adapter immediately begins waiting for new input. This cycle continues whenever the productionis running and the business service is enabled and scheduled to be active.The default CallInterval is 5 seconds. The minimum is 0.1 seconds.Specifies the text character set to use to translate characters for the input file. The string is not case-sensitive. Thedefault is Binary. Use Binary for binary files, or for any data in which newline and linefeed characters aredistinct or must remain unchanged, for example in HL7 Version 2 or EDI messages. Other settings may be usefulwhen transferring text documents. Choices include:• Binary — Binary transfer (the default)• Ascii — Ascii mode FTP transfer but no character encoding translation• Default — The default character encoding of the local <strong>Ensemble</strong> server• Latin1 — The ISO Latin1 8-bit encoding• ISO-8859-1 — The ISO Latin1 8-bit encoding• UTF-8 — The Unicode 8-bit encoding• UCS2 — The Unicode 16-bit encoding• UCS2-BE — The Unicode 16-bit encoding (Big-Endian)• Any other alias from an international character encoding standard for which NLS (National Language Support)is installed in <strong>Ensemble</strong>.10 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


Adapter SettingsEndianA choice of Big or Little indicates the byte order of the 4-byte block count prefix. Big endian means the mostsignificant byte (MSB) goes over the wire first; Little endian means the least significant byte (LSB) goes overthe wire first. The default value for this string is Big.JobPerConnectionLocalInterfacePortQSizeReadTimeoutSSLConfigWhen True, the adapter spawns a new job to handle each incoming <strong>TCP</strong> connection and allows simultaneoushandling of multiple connections. When False, it does not spawn a new job for each connection. False is usuallythe appropriate choice for HL7 or X12 connections. The default is True.For <strong>TCP</strong> services, JobPerConnection causes each new incoming socket connection to be handled by a freshlyspawned job rather than by the listener job itself. Only one job at a time can be the listener, and one job must bethe listener, so <strong>TCP</strong> services configured <strong>with</strong> PoolSize greater than 1 still only start one listener job. However, thislistener can spawn an unlimited number of connection jobs if JobPerConnection is set to True. This release of<strong>Ensemble</strong> makes the PoolSize setting, if configured to a value greater than 1, serve as a limit on the number ofsimultaneous connection jobs that can exist. When this limit is reached, the listener does not accept any moreconnections until one or more of the existing connection jobs quits or dies. An Event Log warning appears whenit first reaches the limit.Specifies the network interface through which the <strong>TCP</strong> connection should go. Select a value from the list or typea value. An empty value means use any interface.Identifies the <strong>TCP</strong> port to connect to. <strong>TCP</strong> port numbers have a maximum value of 65535.How many incoming connections the operating system should hold in reserve on behalf of this business service.Set to 0 if only 1 connection at a time is expected. Set to a large number if many clients will connecting rapidly.The default is 100. The range is 0–1000.Number of seconds to wait for each successive incoming <strong>TCP</strong> read operation, following receipt of initial datafrom the remote <strong>TCP</strong> port. The default is 5 seconds. The range is 0–600 seconds (a maximum of 10 minutes).The name of an existing Secure Socket Layer (SSL) or Transport Layer Security (TLS) configuration to use toauthenticate this connection.You can create and manage SSL/TLS configurations using the Management Portal. See the “<strong>Using</strong> SSL/TLS <strong>with</strong>Caché” chapter in the Caché Security Administration Guide.The first field on the Edit SSL/TLS Configuration form is Configuration Name. This is the string to use in the adapter’sSSLConfig field. The SSLConfig string may also add a | (vertical bar) character followed by the private keypassword. The | character is unique because it is not allowed as part of a Configuration Name.StayConnectedIf StayConnected is a positive value, the adapter stays connected to the remote system for this number of secondsbetween input events. A zero value means to disconnect immediately after every input event. The default of –1means to stay permanently connected, even during idle times. <strong>Adapters</strong> are assumed idle at startup and thereforeonly auto-connect if they are configured <strong>with</strong> a StayConnected value of –1.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 11


3<strong>Using</strong> the <strong>TCP</strong> Counted Outbound AdapterEnsLib.<strong>TCP</strong>.CountedOutboundAdapter contains methods that an <strong>Ensemble</strong> business operation can call to read or write blocksof data across the <strong>TCP</strong> connection. <strong>Ensemble</strong> acts as a <strong>TCP</strong> client exchanging blocks of data <strong>with</strong> a <strong>TCP</strong> listener. The blocklength specified in the first 4 bytes of the block. This convention allows an <strong>Ensemble</strong> business operation to send requeststo an external <strong>TCP</strong> server for fulfillment. The adapter makes no decisions about the data it relays out to the external system.It simply maps the request from the business operation to a format that is acceptable to the external system.This chapter explains how to use the EnsLib.<strong>TCP</strong>.CountedOutboundAdapter. It discusses the following topics:• Background Information• <strong>Using</strong> the Adapter• Creating a New Business Operation Class• Sample Business Operation Class Code• Available Helper Methods• Adapter Settings3.1 Background InformationYou can simply set up the EnsLib.<strong>TCP</strong>.CountedOutboundAdapter as instructed in the next section, “<strong>Using</strong> the Adapter.”However, some developers want more details about how a business operation communicates <strong>with</strong> its configured adapter.This section provides those details.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 13


<strong>Using</strong> the <strong>TCP</strong> Counted Outbound AdapterFigure 3–1: Business Operation and <strong>Using</strong> the <strong>TCP</strong> Counted Outbound AdapterThe figure above shows the flow of a request from <strong>Ensemble</strong> out to an external system after you have set up an <strong>Ensemble</strong>business operation to work <strong>with</strong> an outbound adapter. The sequence is as follows:1. At production startup, <strong>Ensemble</strong> creates a background process for each business operation in the production configuration.<strong>Ensemble</strong> can allocate more than one background process per business operation. The business operation’sconfigured PoolSize specifies the number of background processes.2. Within each background process, <strong>Ensemble</strong> creates an instance of the business operation class and an instance of itsassociated outbound adapter class.3. <strong>Ensemble</strong> calls the OnInit() methods of the business operation object and outbound adapter object, respectively.4. Thereafter, whenever the production is running and the business operation is enabled and scheduled to be active, thefollowing sequence can occur:• The business operation receives an <strong>Ensemble</strong> request message.• The business operation’s message map matches the <strong>Ensemble</strong> request type <strong>with</strong> a business operation method.Note:The developer of each business operation class is responsible for writing its message map and methods.For instructions, see the next section, “<strong>Using</strong> the Adapter.”• The business operation method calls a method in the associated outbound adapter object.• The adapter method sends a request to the external system. If this request generates an acknowledgment or responseof some kind, the outbound adapter relays that data back to the business operation method that invoked it.• If the original <strong>Ensemble</strong> request message requires a response, the business operation returns it.14 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


<strong>Using</strong> the AdapterAn <strong>Ensemble</strong> production continues running until it is stopped, either programmatically or by an administrator using theManagement Portal. When a production stops, the following events related to outbound adapters occur:1. <strong>Ensemble</strong> waits for each business operation to reach a quiescent state (that is, <strong>Ensemble</strong> waits until each businessoperation has completed all of its synchronous requests).2. The OnTearDown() method in each outbound adapter is called.3. All outbound adapter and business operation objects are destroyed and their background processes are killed.4. Each business operation’s OnProductionStop class method is called, once for each configured item of that class inthe production.When a business operation is disabled by a system administrator, or becomes inactive according to its configured schedule,the production continues to run but the associated outbound adapter is shut down, and its OnTearDown() method is executed,as described above.3.2 <strong>Using</strong> the AdapterOnce you determine that your production needs the EnsLib.<strong>TCP</strong>.CountedOutboundAdapter, you can include it in the productionconfiguration as follows:1. Choose or create a business operation class that uses the EnsLib.<strong>TCP</strong>.CountedOutboundAdapter.2. If you create a new business operation class, be sure to:• Add at least one method to the method map.• Implement each method in the method map.• Write the business operation methods so that they call methods from the EnsLib.<strong>TCP</strong>.CountedOutboundAdapterclass.• Compile the new class.3. Configure the production. Add a business operation of the chosen class.4. Configure the new business operation. To do so, click it and specify values for the settings on the right.To enable it, select the Enabled box.The next sections provide details.3.3 Creating a New Business Operation ClassThe simplest way to deploy the EnsLib.<strong>TCP</strong>.CountedOutboundAdapter is to choose an existing business operation class thatalready uses it.If no existing class has the functionality you need, create a business operation class that uses theEnsLib.<strong>TCP</strong>.CountedOutboundAdapter. Create the new class in Studio as follows:1. From the File menu, choose New. A dialog pops up. Edit it as follows:• Click on the Production tab.• Select the Business Operation icon and click OK.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 15


<strong>Using</strong> the <strong>TCP</strong> Counted Outbound Adapter• Enter a package and class name and click Next.Important:Be sure to avoid reserved package names; see “Reserved Package Names” in Developing<strong>Ensemble</strong> Productions.• Choose EnsLib.<strong>TCP</strong>.CountedOutboundAdapter from the drop-down list of adapter classes.• Choose the default invocation style Queue. The alternative is InProc, but generally you want Queue. The differencesare as follows:– Queue means the message is created <strong>with</strong>in one background job and placed on a queue, at which time theoriginal job is released. Later, when the message is processed, a different background job will be allocatedfor the task.– InProc means the message will be formulated, sent, and delivered in the same job in which it was created.The job will not be released to the sender’s pool until the message is delivered to the target. This is onlysuitable for special cases.• Add at least one entry to the method map as follows:–Click the Add icon.– Enter the method name.– Choose a request type and a response type.– Click OK.Repeat these steps as needed to add entries to the method map.• Click Finish.The result is a template class like the following:Class Dev.Test.NewOperation1Extends Ens.BusinessOperation [ ProcedureBlock ]{Parameter ADAPTER = "EnsLib.<strong>TCP</strong>.CountedOutboundAdapter";Parameter INVOCATION = "Queue";Method SampleCall(pRequest As Ens.Request,Output pResponse As Ens.Response) As %Status{Quit $$$ERROR($$$NotImplemented)}XData MessageMap{SampleCall}}2. Implement the method(s) in your new business operation class.Where the following line appears, replace it <strong>with</strong> your own code:Quit $$$ERROR($$$NotImplemented)Keep in mind that the method must quit by returning a %Status object. See the code sample in the next section,“Sample Business Operation Class Code.”16 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


Sample Business Operation Class Code3. When you want to call one of the methods in EnsLib.<strong>TCP</strong>.CountedOutboundAdapter, use the Adapter property to identifythe adapter object. The following example calls the EnsLib.<strong>TCP</strong>.CountedOutboundAdapter method WriteCountedStreamfrom a business operation method:Set tSC=..Adapter.WriteCountedStream(myAbstractStream)You can use similar syntax to call any of the EnsLib.<strong>TCP</strong>.CountedOutboundAdapter methods described in “AvailableHelper Methods. ”4. Optionally, you may implement the OnConnect() callback method in your business operation class.OnConnect() is available for a <strong>TCP</strong> outbound adapter to call back to its associated business operation. If present inthe business operation, this method is called each time the <strong>TCP</strong> outbound adapter establishes a new connection to orfrom a remote system.If you add an OnConnect() method to your business operation class, it must have the following signature:Method OnConnect(pTimeout As %Numeric) As %StatusImplement an OnConnect() method in your business operation if you need to take some action each time a new connectionis established, for example to send a logon sequence or a handshake token. The timeout argument is automaticallyprovided by the <strong>TCP</strong> outbound adapter. It takes its value from the ConnectTimeout adapter setting. For details, see“Adapter Settings.”Returning an error status from OnConnect() causes the new connection to fail and be disconnected. If an untrappedexception occurs <strong>with</strong>in OnConnect(), the adapter catches it and continues as if OnConnect() were not implemented.5. Compile your new business operation class. Compiling also saves it.6. After creating and compiling the business operation class in Studio, add an instance of the business operation to theproduction and configure it using the Management Portal. See the appendix “Common Tasks in the ManagementPortal.”3.4 Sample Business Operation Class CodeThe following is an example of a business operation class that references the EnsLib.<strong>TCP</strong>.CountedOutboundAdapter.Class Test.General<strong>TCP</strong>Operation Extends Ens.BusinessOperation [ ProcedureBlock ]{Parameter ADAPTER = "EnsLib.<strong>TCP</strong>.CountedOutboundAdapter";Parameter MAXREAD=30000;Method OnMessage(pReq As Test.GeneralSendRequest,Output pResponse As Test.GeneralSendResponse) As %Status{Set str=pRq.Hr_pRq.DataLth_pRq.BID_pRq.Hr2_pRq.HrVacant_pRq.Cat_pRq.Hr3_pRq.Hr4Set tTextStream= ##class(%GlobalCharacterStream).%New()Set tSC=tTextStream.Write(str)Do pReq.Body2.Read(32) // Throw it awaySet len=..#MAXREADSet token= pReq.Body2.Read(.len)Set i=0While(len>0) {Set i=i+1Do tTextStream.Write(token)Set len=..#MAXREADSet token= pReq.Body2.Read(.len)}Set tSC=..Adapter.SendMessageStream(tTextStream,.tStreamReply) Quit:$$$ISERR(tSC) tSCSet pResponse=##class(Test.GeneralSendResponse).%New()Do tStreamReply.Rewind()Set pResponse.Body = tStreamReply.Read(,.tSC)<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 17


<strong>Using</strong> the <strong>TCP</strong> Counted Outbound AdapterQuit tSC}}3.5 Available Helper MethodsWhen your business operation class references the EnsLib.<strong>TCP</strong>.CountedOutboundAdapter, the following adapter methodsbecome available. You can call these adapter methods from the methods in your business operation class using the Adapterproperty as described in the previous section:Connect()Disconnect()Method Connect(pTimeout As %Numeric) As %StatusConnect() opens a <strong>TCP</strong> socket to a port on the <strong>TCP</strong> listener machine. Connect() has one input argument, a%Numeric value that identifies the number of seconds to wait for the connection attempt to succeed. A typical callto the Connect() method gives this input argument the value of the configurable ConnectTimeout property.If the StayConnected adapter setting is set to –1, the <strong>Ensemble</strong> framework will create the connection automaticallyat startup time, from <strong>with</strong>in the OnInit() method.Method Disconnect()Disconnect() takes down the connection to the <strong>TCP</strong> listener.SendMessageStream()Method SendMessageStream(pRequestStream As %Stream.Object,ByRef pResponseStream As %CharacterStream = "%GlobalCharacterStream")As %StatusSendMessageStream() sends the stream contents as a counted block on the <strong>TCP</strong> socket.SendMessageString()Method SendMessageString(pRequestString As %String,Output pResponseString As %String) As %StatusSendMessageString() sends the string contents as a counted block on the <strong>TCP</strong> socket.TestConnection()Method TestConnection()TestConnection() corrects the properties reflecting the connection state. If the adapter is connected,TestConnection() returns True. If not, TestConnection() calls Disconnect() and returns False.3.6 Adapter SettingsThis topic describes the settings that are specific to the EnsLib.<strong>TCP</strong>.CountedOutboundAdapter associated <strong>with</strong> the businessoperation. For settings not listed here, see “Business Operation Settings” in the chapter “Configuration” in Managing<strong>Ensemble</strong> Productions.18 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


Adapter SettingsCharsetSpecifies the text character set to use to translate characters for the input file. The string is not case-sensitive. Thedefault is Binary. Use Binary for binary files, or for any data in which newline and linefeed characters aredistinct or must remain unchanged, for example in HL7 Version 2 or EDI messages. Other settings may be usefulwhen transferring text documents. Choices include:• Binary — Binary transfer (the default)• Ascii — Ascii mode FTP transfer but no character encoding translation• Default — The default character encoding of the local <strong>Ensemble</strong> server• Latin1 — The ISO Latin1 8-bit encoding• ISO-8859-1 — The ISO Latin1 8-bit encoding• UTF-8 — The Unicode 8-bit encoding• UCS2 — The Unicode 16-bit encoding• UCS2-BE — The Unicode 16-bit encoding (Big-Endian)• Any other alias from an international character encoding standard for which NLS (National Language Support)is installed in <strong>Ensemble</strong>.ConnectTimeoutEndianGetReplyIPAddressLocalInterfaceNumber of seconds to wait on each attempt to connect to the remote <strong>TCP</strong> listener. The default is 5 seconds.A choice of Big or Little indicates the byte order of the 4-byte block count prefix. Big endian means the mostsignificant byte (MSB) goes over the wire first; Little endian means the least significant byte (LSB) goes overthe wire first. The default value for this string is Big.If 1 (true) wait to read a reply message back from the socket before returning. If 0 (false) do not wait. The defaultvalue is 1.IP address to make a <strong>TCP</strong> connection to. The adapter accepts a named IP address, an IPV4 address, or an IPV6address.If the address starts <strong>with</strong> a ! character, the adapter waits for a connection from a remote system. In this case, followthe exclamation point <strong>with</strong> a comma-separated list of remote IP addresses from which to accept connections. Theadapter accepts named IP addresses, IPV4 addresses, or IPV6 addresses. An optional :port designation is supported;so, for example, both of the following address formats are acceptable: 192.168.1.22 or 192.168.1.22:3298.If no IP address follows the ! character, any remote system may connect; otherwise only the listed IP addresses(and ports) are allowed to connect.Specifies the network interface through which the <strong>TCP</strong> connection should go. Select a value from the list or typea value. An empty value means use any interface.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 19


<strong>Using</strong> the <strong>TCP</strong> Counted Outbound AdapterPortQSizeReadTimeoutThis setting allows you to specify that a virtual IP address should be used to send outbound traffic, which is usefulin the case of mirroring. If a remote application is configured to accept traffic from the virtual IP address, and boththe primary and the secondary use that IP address to connect to the remote application, then everything continuesto work when the secondary starts sending.Identifies the <strong>TCP</strong> port to connect to. <strong>TCP</strong> port numbers have a maximum value of 65535.How many incoming connections the operating system should hold in reserve on behalf of this business operation.There is generally no reason to change the default value of 0. Either the connection is outbound, or the businessoperation is using '!' inbound mode, in which case only 1 client is allowed at a time, per business operation pooljob.Number of seconds to wait for each successive incoming <strong>TCP</strong> read operation, following receipt of initial datafrom the remote <strong>TCP</strong> port. The default is 5 seconds. The range is 0–600 seconds (a maximum of 10 minutes).ReconnectRetryNumber of retries at which to drop the connection and try reconnecting again. A value of 0 (zero) means neverdisconnect. The default value is 5.ResponseTimeoutSSLConfigNumber of seconds to wait for a response to begin arriving back from the remote system after sending a request.The default is 15 seconds.The name of an existing Secure Socket Layer (SSL) or Transport Layer Security (TLS) configuration to use toauthenticate this connection.You can create and manage SSL/TLS configurations using the Management Portal. See the “<strong>Using</strong> SSL/TLS <strong>with</strong>Caché” chapter in the Caché Security Administration Guide.The first field on the Edit SSL/TLS Configuration form is Configuration Name. This is the string to use in the adapter’sSSLConfig field. The SSLConfig string may also add a | (vertical bar) character followed by the private keypassword. The | character is unique because it is not allowed as part of a Configuration Name.StayConnectedIf StayConnected is a positive value, the adapter stays connected to the remote system for this number of secondsafter completing an operation. A zero value means to disconnect immediately after every operation. The defaultof –1 means to stay permanently connected, even during idle times. <strong>Adapters</strong> are assumed idle at startup andtherefore only auto-connect if they are configured <strong>with</strong> a StayConnected value of –1.20 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


4<strong>Using</strong> the <strong>TCP</strong> Counted XML InboundAdapterThe EnsLib.<strong>TCP</strong>.CountedXMLInboundAdapter acts as a <strong>TCP</strong> listener for an XTE server. The adapter receives XML data incounted <strong>TCP</strong> format and imports the XML data into <strong>Ensemble</strong>. The result is an instantiated <strong>Ensemble</strong> object.This chapter explains how to use the EnsLib.<strong>TCP</strong>.CountedXMLInboundAdapter. It discusses the following topics:• Background Information• <strong>Using</strong> the Adapter• Creating a New Business Service Class• Adapter Settings4.1 Background InformationYou can simply set up the EnsLib.<strong>TCP</strong>.CountedXMLInboundAdapter as instructed in the next section, “<strong>Using</strong> the Adapter.”However, some developers want more details about how the adapter communicates <strong>with</strong> its configured business service.This section provides those details.If you look at the EnsLib.<strong>TCP</strong>.CountedXMLInboundAdapter class code, you see that it contains a call to an <strong>Ensemble</strong>framework method called ProcessInput(). However, the code for the business service class provides a method calledOnProcessInput(). This section explains the relationship between the two methods. If you want to view <strong>Ensemble</strong> classcode, try the following:• In Studio, from the Tools menu choose Class Browser. The Class Browser dialog displays. In the window at left, navigatethe hierarchy to find the class of interest. In the window at right, display details about class members and theclass hierarchy by clicking the tabs along the lower edge of the display: All, Properties, Methods, Parameters, and soon.• In Studio, from the Help menu choose On-line <strong>Documentation</strong>. The documentation home page displays. Scroll downand choose Class Reference Information. The Caché Class Reference home page displays. At top left, for Classes inchoose an <strong>Ensemble</strong>-enabled namespace. Navigate the hierarchy of package names to find the class of interest.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 21


<strong>Using</strong> the <strong>TCP</strong> Counted XML Inbound AdapterFigure 4–1: <strong>Using</strong> the <strong>TCP</strong> Counted XML Inbound Adapter and Business ServiceThe figure above shows the flow of a request from an external data source into <strong>Ensemble</strong> after you have set up an <strong>Ensemble</strong>business service to work <strong>with</strong> an inbound adapter. This figure shows the ingoing data stream only; any response simplyretraces this path. The sequence is as follows:1. At production startup, <strong>Ensemble</strong> creates a background process for each of the business services in the productionconfiguration. <strong>Ensemble</strong> can allocate more than one background process per business service. The business service’sconfigured PoolSize specifies the number of background processes.2. Within each background process, <strong>Ensemble</strong> creates an instance of the business service class and an instance of itsassociated inbound adapter class.3. <strong>Ensemble</strong> calls the OnInit() methods of the business service object and inbound adapter object, respectively.4. Thereafter, whenever the production is running and the business service is enabled and scheduled to be active, thefollowing cycle can occur:• Each time the adapter encounters input from its configured data source, it calls the <strong>Ensemble</strong> framework’sProcessInput() method.• The call to ProcessInput() automatically prompts the <strong>Ensemble</strong> framework to call the associated business service’sOnProcessInput() method.• Code <strong>with</strong>in OnProcessInput() determines what to do <strong>with</strong> the incoming data stream. For example, if an<strong>Ensemble</strong> business process needs to be started, the business service formulates an <strong>Ensemble</strong> request message andissues the synchronous or asynchronous call that starts the business process.If the data source expects an acknowledgment or response of some kind, it is the business service’sOnProcessInput() that constructs it. The inbound adapter simply relays this response back to the external datasource.Note:There is no default implementation of OnProcessInput(). The developer of each business service classis responsible for writing an OnProcessInput() method for that class. For instructions, see the nextsection, “<strong>Using</strong> the Adapter.”22 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


<strong>Using</strong> the AdapterAn <strong>Ensemble</strong> production continues running until it is stopped, either programmatically or by an administrator using theManagement Portal. When a production stops, the following events related to inbound adapters occur:1. <strong>Ensemble</strong> disables each business service; no more incoming requests are accepted for this production.2. The OnTearDown() method in each inbound adapter is called.3. All inbound adapter and business service objects are destroyed and their background processes are killed.4. Each business service’s OnProductionStop class method is called, once for each configured item of that class in theproduction.When a business service is disabled by a system administrator, or becomes inactive according to its configured schedule,the production continues to run but the associated inbound adapter is shut down, and its OnTearDown() method is executed,as described above.4.2 <strong>Using</strong> the AdapterOnce you determine that your production needs the EnsLib.<strong>TCP</strong>.CountedXMLInboundAdapter, you can include it in theproduction configuration as follows:1. Choose or create a business service class that uses the EnsLib.<strong>TCP</strong>.CountedXMLInboundAdapter.2. If you create a new business service class, be sure to:• Implement its OnProcessInput() method.• Compile the class.3. Configure the production. Add a business service of the chosen class.4. Configure the new business service. To do so, click it and specify values for the settings on the right.To enable it, select the Enabled box.The next sections provide details.4.3 Creating a New Business Service ClassThe simplest way to deploy the EnsLib.<strong>TCP</strong>.CountedXMLInboundAdapter is to choose an existing business service classthat already uses it.If no existing class has the functionality you need, create a business service class that uses theEnsLib.<strong>TCP</strong>.CountedXMLInboundAdapter. Create the new class in Studio as follows:1. From the File menu, choose New. A dialog pops up. Edit it as follows:• Click on the Production tab.• Select the Business Service icon and click OK.• Enter a package and class name and click Next.Important:Be sure to avoid reserved package names; see “Reserved Package Names” in Developing<strong>Ensemble</strong> Productions.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 23


<strong>Using</strong> the <strong>TCP</strong> Counted XML Inbound Adapter• Choose EnsLib.<strong>TCP</strong>.CountedXMLInboundAdapter from the drop-down list of adapter classes.• Click Finish.The result is a template class like the following:Class Dev.Test.NewService1Extends Ens.BusinessService [ ProcedureBlock ]{Parameter ADAPTER = "EnsLib.<strong>TCP</strong>.CountedXMLInboundAdapter";Method OnProcessInput(pInput As %RegisteredObject,pOutput As %RegisteredObject) As %Status{Quit $$$ERROR($$$NotImplemented)}}2. Implement the OnProcessInput() method in your new business service class. This is the method that uses the inputdata gathered by the EnsLib.<strong>TCP</strong>.CountedXMLInboundAdapter.You can implement the OnProcessInput() method by replacing the following line in the template class <strong>with</strong> your owncode:Quit $$$ERROR($$$NotImplemented)Your OnProcessInput() method must know the types of incoming and outgoing data for communicating <strong>with</strong> theEnsLib.<strong>TCP</strong>.CountedXMLInboundAdapter. However, the New Business Service Wizard specifies both types in theOnProcessInput() method signature as the generic object type %RegisteredObject.<strong>InterSystems</strong> suggests that, as your first action in coding the new business service, you change each OnProcessInput()argument to its specific type passed from the adapter:Method OnProcessInput(pInput As %RegisteredObject,Output pOutput As %RegisteredObject) As %StatusWhere:• pInput is of type %RegisteredObject and can be any of the objects specified by the AcceptClassNames adaptersetting.For details about AcceptClassNames, see “Adapter Settings.”• pOutput is of type %RegisteredObject and contains any response that you might need to return to the XTE server.Keep in mind that the method must quit by returning a %Status object.3. Optionally, you may implement the OnConnect() callback method in your business service class.OnConnect() is available for a <strong>TCP</strong> inbound adapter to call back to its associated business service. If present in thebusiness service, this method is called each time the <strong>TCP</strong> inbound adapter establishes a new connection to or from aremote system.If you add an OnConnect() method to your business service class, it must have the following signature:Method OnConnect(pTimeout As %Numeric) As %StatusImplement an OnConnect() method in your business service if you need to take some action each time a new connectionis established, for example to send a logon sequence or a handshake token. The timeout argument is automaticallyprovided by the <strong>TCP</strong> inbound adapter. It takes its value from the ReadTimeout adapter setting.For details about ReadTimeout, see “Adapter Settings.”Returning an error status from OnConnect() causes the new connection to fail and be disconnected. If an untrappedexception occurs <strong>with</strong>in OnConnect(), the adapter catches it and continues as if OnConnect() were not implemented.4. Compile your new business service class. Compiling also saves it.24 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


Adapter Settings5. After creating and compiling the business service class in Studio, add an instance of the business service to the productionand configure it using the Management Portal. See the appendix “Common Tasks in the Management Portal.”When you configure the adapter, you specify a value for the AllowedIPAddresses settings, along other settings. Notethat AllowedIPAddresses provides a way to enable the adapter to initiate the connection; see “Adapter Settings.”4.4 Adapter SettingsThis topic describes the settings that are specific to the EnsLib.<strong>TCP</strong>.CountedXMLInboundAdapter associated <strong>with</strong> the businessservice. For settings not listed here, see “Business Service Settings” in the chapter “Configuration” in Managing<strong>Ensemble</strong> Productions.AcceptClassnamesComma-separated list, giving the names of classes that this adapter will instantiate from XML blocks received.AllowedIPAddressesCallIntervalCharsetA comma-separated list of remote IP addresses from which to accept connections. The adapter accepts named IPaddresses, IPV4 addresses, or IPV6 addresses. An optional :port designation is supported; so, for example, bothof the following address formats are acceptable: 192.168.1.22 or 192.168.1.22:3298.If the string starts <strong>with</strong> a !, the adapter will initiate a connection to the specified address. In this case only oneaddress may be given. If a port is included, it will supersede the value of the Port setting; otherwise the Port settingwill be used to connect to the remote system.Number of seconds that the adapter will listen for incoming data from its configured source, before checking fora shutdown signal from the <strong>Ensemble</strong> framework.If the adapter finds input, it acquires the data and passes it to the business service. The business service processesthe data, and then the adapter immediately begins waiting for new input. This cycle continues whenever the productionis running and the business service is enabled and scheduled to be active.The default CallInterval is 5 seconds. The minimum is 0.1 seconds.Specifies the text character set to use to translate characters for the input file. The string is not case-sensitive. Thedefault is Binary. Use Binary for binary files, or for any data in which newline and linefeed characters aredistinct or must remain unchanged, for example in HL7 Version 2 or EDI messages. Other settings may be usefulwhen transferring text documents. Choices include:• Binary — Binary transfer (the default)• Ascii — Ascii mode FTP transfer but no character encoding translation• Default — The default character encoding of the local <strong>Ensemble</strong> server• Latin1 — The ISO Latin1 8-bit encoding• ISO-8859-1 — The ISO Latin1 8-bit encoding• UTF-8 — The Unicode 8-bit encoding• UCS2 — The Unicode 16-bit encoding<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 25


<strong>Using</strong> the <strong>TCP</strong> Counted XML Inbound Adapter• UCS2-BE — The Unicode 16-bit encoding (Big-Endian)• Any other alias from an international character encoding standard for which NLS (National Language Support)is installed in <strong>Ensemble</strong>.EndianA choice of Big or Little indicates the byte order of the 4-byte block count prefix. Big endian means the mostsignificant byte (MSB) goes over the wire first; Little endian means the least significant byte (LSB) goes overthe wire first. The default value for this string is Big.JobPerConnectionLocalInterfacePortQSizeWhen True, the adapter spawns a new job to handle each incoming <strong>TCP</strong> connection and allows simultaneoushandling of multiple connections. When False, it does not spawn a new job for each connection; False is usuallythe appropriate choice for HL7 or X12 connections. The default is True.Specifies the network interface through which the <strong>TCP</strong> connection should go. Select a value from the list or typea value. An empty value means use any interface.<strong>TCP</strong> Port to connect to.How many incoming connections the operating system should hold in reserve on behalf of this business service.Set to 0 if only 1 connection at a time is expected. Set to a large number if many clients will connecting rapidly.The default is 100. The range is 0–1000.StayConnectedReadTimeoutSSLConfigIf StayConnected is a positive value, the adapter stays connected to the remote system for this number of secondsbetween input events. A zero value means to disconnect immediately after every input event. The default of –1means to stay permanently connected, even during idle times. <strong>Adapters</strong> are assumed idle at startup and thereforeonly auto-connect if they are configured <strong>with</strong> a StayConnected value of –1.Number of seconds to wait for each successive incoming <strong>TCP</strong> read, following receipt of initial data from remote<strong>TCP</strong> port. The default value is 5. The range is from 0 to 600.The name of an existing Secure Socket Layer (SSL) or Transport Layer Security (TLS) configuration to use toauthenticate this connection.You can create and manage SSL/TLS configurations using the Management Portal. See the “<strong>Using</strong> SSL/TLS <strong>with</strong>Caché” chapter in the Caché Security Administration Guide.The first field on the Edit SSL/TLS Configuration form is Configuration Name. This is the string to use in the adapter’sSSLConfig field. The SSLConfig string may also add a | (vertical bar) character followed by the private keypassword. The | character is unique because it is not allowed as part of a Configuration Name.26 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


5<strong>Using</strong> the <strong>TCP</strong> Counted XML OutboundAdapterEnsLib.<strong>TCP</strong>.CountedXMLOutboundAdapter is a <strong>TCP</strong> adapter that sends XML exported objects out as a counted block ofbytes over a <strong>TCP</strong> connection and imports a response object. The adapter makes no decisions about the data it relays out tothe external system. It simply maps the request from the business operation to a format that is acceptable to the externalsystem.This chapter explains how to use the EnsLib.<strong>TCP</strong>.CountedXMLOutboundAdapter. It discusses the following topics:• Background Information• <strong>Using</strong> the Adapter• Creating a New Business Operation Class• Available Helper Methods• Adapter Settings5.1 Background InformationYou can simply set up the EnsLib.<strong>TCP</strong>.CountedXMLOutboundAdapter as instructed in the next section, “<strong>Using</strong> the Adapter.”However, some developers want more details about how a business operation communicates <strong>with</strong> its configured adapter.This section provides those details.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 27


<strong>Using</strong> the <strong>TCP</strong> Counted XML Outbound AdapterFigure 5–1: Business Operation and <strong>Using</strong> the <strong>TCP</strong> Counted XML Outbound AdapterThe figure above shows the flow of a request from <strong>Ensemble</strong> out to an external system after you have set up a <strong>Ensemble</strong>business operation to work <strong>with</strong> an outbound adapter. The sequence is as follows:1. At production startup, <strong>Ensemble</strong> creates a background process for each of the business operations in the productionconfiguration. <strong>Ensemble</strong> can allocate more than one background process per business operation. The business operation’sconfigured PoolSize specifies the number of background processes.2. Within each background process, <strong>Ensemble</strong> creates an instance of the business operation class and an instance of itsassociated outbound adapter class.3. <strong>Ensemble</strong> calls the OnInit() methods of the business operation object and outbound adapter object, respectively.4. Thereafter, whenever the production is running and the business operation is enabled and scheduled to be active, thefollowing sequence can occur:• The business operation receives an <strong>Ensemble</strong> request message.• The business operation’s message map matches the <strong>Ensemble</strong> request type <strong>with</strong> a business operation method.Note:The developer of each business operation class is responsible for writing its message map and methods.For instructions, see the next section, “<strong>Using</strong> the Adapter.”• The business operation method calls a method in the associated outbound adapter object.• The adapter method sends a request to the external system. If this request generates an acknowledgment or responseof some kind, the outbound adapter relays that data back to the business operation method that invoked it.• If the original <strong>Ensemble</strong> request message requires a response, the business operation returns it.28 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


<strong>Using</strong> the AdapterAn <strong>Ensemble</strong> production continues running until it is stopped, either programmatically or by an administrator using theManagement Portal. When a production stops, the following events related to outbound adapters occur:1. <strong>Ensemble</strong> waits for each business operation to reach a quiescent state (that is, <strong>Ensemble</strong> waits until each businessoperation has completed all of its synchronous requests).2. The OnTearDown() method in each outbound adapter is called.3. All outbound adapter and business operation objects are destroyed and their background processes are killed.4. Each business operation’s OnProductionStop class method is called, once for each configured item of that class inthe production.When a business operation is disabled by a system administrator, or becomes inactive according to its configured schedule,the production continues to run but the associated outbound adapter is shut down, and its OnTearDown() method is executed,as described above.5.2 <strong>Using</strong> the AdapterOnce you determine that your production needs the EnsLib.<strong>TCP</strong>.CountedXMLOutboundAdapter, you can include it in theproduction configuration as follows:1. Choose or create a business operation class that uses the EnsLib.<strong>TCP</strong>.CountedXMLOutboundAdapter.2. If you create a new business operation class, be sure to:• Add at least one method to the method map.• Implement each method in the method map.• Write the business operation methods so that they call methods from the EnsLib.<strong>TCP</strong>.CountedXMLOutboundAdapterclass.• Compile the new class.3. Configure the production. Add a business operation of the chosen class.4. Configure the new business operation. To do so, click it and specify values for the settings on the right.To enable it, select the Enabled box.The next sections provide details.5.3 Creating a New Business Operation ClassThe simplest way to deploy the EnsLib.<strong>TCP</strong>.CountedXMLOutboundAdapter is to choose an existing business operation classthat already uses it.If no existing class has the functionality you need, create a business operation class that uses theEnsLib.<strong>TCP</strong>.CountedXMLOutboundAdapter. Create the new class in Studio as follows:1. From the File menu, choose New. A dialog pops up. Edit it as follows:• Click on the Production tab.• Select the Business Operation icon and click OK.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 29


<strong>Using</strong> the <strong>TCP</strong> Counted XML Outbound Adapter• Enter a package and class name and click Next.Important:Be sure to avoid reserved package names; see “Reserved Package Names” in Developing<strong>Ensemble</strong> Productions.• Choose EnsLib.<strong>TCP</strong>.CountedXMLOutboundAdapter from the drop-down list of adapter classes.• Choose the default invocation style Queue. The alternative is InProc, but generally you want Queue. The differencesare as follows:– Queue means the message is created <strong>with</strong>in one background job and placed on a queue, at which time theoriginal job is released. Later, when the message is processed, a different background job will be allocatedfor the task.– InProc means the message will be formulated, sent, and delivered in the same job in which it was created.The job will not be released to the sender’s pool until the message is delivered to the target. This is onlysuitable for special cases.• Add at least one entry to the method map as follows:–Click the Add icon.– Enter the method name.– Choose a request type and a response type.– Click OK.Repeat these steps as needed to add entries to the method map.• Click Finish.The result is a template class like the following:Class Dev.Test.NewOperation1 Extends Ens.BusinessOperation [ ProcedureBlock ]{Parameter ADAPTER = "EnsLib.<strong>TCP</strong>.CountedXMLOutboundAdapter";Parameter INVOCATION = "Queue";Method SampleCall(pRequest As Ens.Request,Output pResponse As Ens.Response) As %Status{Quit $$$ERROR($$$NotImplemented)}XData MessageMap{SampleCall}}2. Implement the method(s) in your new business operation class.Where the following line appears, replace it <strong>with</strong> your own code:Quit $$$ERROR($$$NotImplemented)Keep in mind that the method must quit by returning a %Status object.3. When you want to call one of the methods in EnsLib.<strong>TCP</strong>.CountedXMLOutboundAdapter, use the Adapter property toidentify the adapter object, <strong>with</strong> dot syntax to refer to the adapter method. See “Available Helper Methods.”4. Optionally, you may implement the OnConnect() callback method in your business operation class.30 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


Available Helper MethodsOnConnect() is available for a <strong>TCP</strong> outbound adapter to call back to its associated business operation. If present inthe business operation, this method is called each time the <strong>TCP</strong> outbound adapter establishes a new connection to orfrom a remote system.If you add an OnConnect() method to your business operation class, it must have the following signature:Method OnConnect(pTimeout As %Numeric) As %StatusImplement an OnConnect() method in your business operation if you need to take some action each time a new connectionis established, for example to send a logon sequence or a handshake token. The timeout argument is automaticallyprovided by the <strong>TCP</strong> outbound adapter. It takes its value from the ConnectTimeout adapter setting. For details, see“Adapter Settings.”Returning an error status from OnConnect() causes the new connection to fail and be disconnected. If an untrappedexception occurs <strong>with</strong>in OnConnect(), the adapter catches it and continues as if OnConnect() were not implemented.5. Compile your new business operation class. Compiling also saves it.6. After creating and compiling the business operation class in Studio, add an instance of the business operation to theproduction and configure it using the Management Portal. See the appendix “Common Tasks in the ManagementPortal.”5.4 Available Helper MethodsWhen your business operation class references the EnsLib.<strong>TCP</strong>.CountedXMLOutboundAdapter, the following adaptermethods become available. You can call these adapter methods from the methods in your business operation class usingthe Adapter property as described in the previous section:Connect()Disconnect()Method Connect(pTimeout As %Numeric) As %StatusConnect() opens a <strong>TCP</strong> socket to a port on the <strong>TCP</strong> listener machine. Connect() has one input argument, a%Numeric value that identifies the number of seconds to wait for the connection attempt to succeed. A typical callto the Connect() method gives this input argument the value of the configurable ConnectTimeout property.If the StayConnected adapter setting is set to –1, the <strong>Ensemble</strong> framework will create the connection automaticallyat startup time, from <strong>with</strong>in the OnInit() method.Method Disconnect()Disconnect() takes down the connection to the <strong>TCP</strong> listener.SendMessageXMLObj()Method SendMessageXMLObj(pRequest As %RegisteredObject,Output pResponse As %RegisteredObject) As %StatusSendMessageXMLObj() sends the request object to the <strong>TCP</strong> listener as a counted XML block. If the GetReplyadapter setting is True, SendMessageXMLObj() also gets a reply from the <strong>TCP</strong> listener as a counted XML block,which it imports as an <strong>Ensemble</strong> object.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 31


<strong>Using</strong> the <strong>TCP</strong> Counted XML Outbound AdapterTestConnection()Method TestConnection()TestConnection() corrects the properties reflecting the connection state. If the adapter is connected,TestConnection() returns True. If not, TestConnection() calls Disconnect() and returns False.5.5 Adapter SettingsThis topic describes the settings that are specific to the EnsLib.<strong>TCP</strong>.CountedXMLOutboundAdapter associated <strong>with</strong> thebusiness operation. For settings not listed here, see “Business Operation Settings” in the chapter “Configuration” inManaging <strong>Ensemble</strong> Productions.CharsetSpecifies the text character set to use to translate characters for the input file. The string is not case-sensitive. Thedefault is Binary. Use Binary for binary files, or for any data in which newline and linefeed characters aredistinct or must remain unchanged, for example in HL7 Version 2 or EDI messages. Other settings may be usefulwhen transferring text documents. Choices include:• Binary — Binary transfer (the default)• Ascii — Ascii mode FTP transfer but no character encoding translation• Default — The default character encoding of the local <strong>Ensemble</strong> server• Latin1 — The ISO Latin1 8-bit encoding• ISO-8859-1 — The ISO Latin1 8-bit encoding• UTF-8 — The Unicode 8-bit encoding• UCS2 — The Unicode 16-bit encoding• UCS2-BE — The Unicode 16-bit encoding (Big-Endian)• Any other alias from an international character encoding standard for which NLS (National Language Support)is installed in <strong>Ensemble</strong>.ConnectTimeoutEndianIPAddressNumber of seconds to wait on each connection attempt. The default value is 5.A choice of Big or Little indicates the byte order of the 4-byte block count prefix. Big endian means the mostsignificant byte (MSB) goes over the wire first; Little endian means the least significant byte (LSB) goes overthe wire first. The default value for this string is Big.IP address to make a <strong>TCP</strong> connection to. The adapter accepts a named IP address, an IPV4 address, or an IPV6address.If the address starts <strong>with</strong> a ! character, the adapter waits for a connection from a remote system. In this case, followthe exclamation point <strong>with</strong> a comma-separated list of remote IP addresses from which to accept connections. Theadapter accepts named IP addresses, IPV4 addresses, or IPV6 addresses. An optional :port designation is supported;so, for example, both of the following address formats are acceptable: 192.168.1.22 or 192.168.1.22:3298.32 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


Adapter SettingsGetReplyLocalInterfacePortQSizeReadTimeoutIf no IP address follows the ! character, any remote system may connect; otherwise only the listed IP addresses(and ports) are allowed to connect.If 1 (true) wait to read a reply message back from the socket before returning. If 0 (false) do not wait. The defaultvalue is 1.Specifies the network interface through which the <strong>TCP</strong> connection should go. Select a value from the list or typea value. An empty value means use any interface.This setting allows you to specify that a virtual IP address should be used to send outbound traffic, which is usefulin the case of mirroring. If a remote application is configured to accept traffic from the virtual IP address, and boththe primary and the secondary use that IP address to connect to the remote application, then everything continuesto work when the secondary starts sending.<strong>TCP</strong> port to connect to.How many incoming connections the operating system should hold in reserve on behalf of this business operation.There is generally no reason to change the default value of 0. Either the connection is outbound, or the businessoperation is using '!' inbound mode, in which case only 1 client is allowed at a time, per business operation pooljob.Number of seconds to wait for each successive incoming <strong>TCP</strong> read, following receipt of initial data from remote<strong>TCP</strong> port. The default value is 5. The range is from 0 to 600.ReconnectRetryNumber of retries at which to drop the connection and try reconnecting again. A value of 0 (zero) means neverdisconnect. The default value is 5.ResponseTimeoutSSLConfigNumber of seconds to wait for a response to begin arriving back from the remote system after sending a request.The default value is 15.The name of an existing Secure Socket Layer (SSL) or Transport Layer Security (TLS) configuration to use toauthenticate this connection.You can create and manage SSL/TLS configurations using the Management Portal. See the “<strong>Using</strong> SSL/TLS <strong>with</strong>Caché” chapter in the Caché Security Administration Guide.The first field on the Edit SSL/TLS Configuration form is Configuration Name. This is the string to use in the adapter’sSSLConfig field. The SSLConfig string may also add a | (vertical bar) character followed by the private keypassword. The | character is unique because it is not allowed as part of a Configuration Name.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 33


<strong>Using</strong> the <strong>TCP</strong> Counted XML Outbound AdapterStayConnectedIf StayConnected is a positive value, the adapter stays connected to the remote system for this number of secondsafter completing an operation. A zero value means to disconnect immediately after every operation. The defaultof –1 means to stay permanently connected, even during idle times. <strong>Adapters</strong> are assumed idle at startup andtherefore only auto-connect if they are configured <strong>with</strong> a StayConnected value of –1.34 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


6<strong>Using</strong> the <strong>TCP</strong> Text Line Inbound AdapterEnsLib.<strong>TCP</strong>.TextLineInboundAdapter is the adapter class to use for incoming <strong>TCP</strong> connections over which a <strong>TCP</strong> client and<strong>TCP</strong> listener exchange data as text strings that end <strong>with</strong> a line terminator character. The default terminator is the newlinecharacter (ASCII 10).This chapter explains how to use the EnsLib.<strong>TCP</strong>.TextLineInboundAdapter. It discusses the following topics:• Background Information• <strong>Using</strong> the Adapter• Creating a New Business Service Class• Sample Business Service Class Code• Adapter Settings• Adding a <strong>TCP</strong> Status ServiceAn important example of a business service that uses the EnsLib.<strong>TCP</strong>.TextLineInboundAdapter is the built-in business serviceclass EnsLib.<strong>TCP</strong>.StatusService. This class provides a command-line interface that allows a console user or command-linescript to retrieve basic status information from a running <strong>Ensemble</strong> production. For more information, see “<strong>TCP</strong> StatusService” at the end of this chapter.6.1 Background InformationYou can simply set up the EnsLib.<strong>TCP</strong>.TextLineInboundAdapter as instructed in the next section, “<strong>Using</strong> the Adapter.”However, some developers want more details about how the adapter communicates <strong>with</strong> its configured business service.This section provides those details.If you look at the EnsLib.<strong>TCP</strong>.TextLineInboundAdapter class code, you see that it contains a call to an <strong>Ensemble</strong> frameworkmethod called ProcessInput(). However, the code for the business service class provides a method called OnProcessInput().This section explains the relationship between the two methods. If you want to view <strong>Ensemble</strong> class code, try the following:• In Studio, from the Tools menu choose Class Browser. The Class Browser dialog displays. In the window at left, navigatethe hierarchy to find the class of interest. In the window at right, display details about class members and theclass hierarchy by clicking the tabs along the lower edge of the display: All, Properties, Methods, Parameters, and soon.• In Studio, from the Help menu choose On-line <strong>Documentation</strong>. The documentation home page displays. Scroll downand choose Class Reference Information. The Caché Class Reference home page displays. At top left, for Classes inchoose an <strong>Ensemble</strong>-enabled namespace. Navigate the hierarchy of package names to find the class of interest.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 35


<strong>Using</strong> the <strong>TCP</strong> Text Line Inbound AdapterFigure 6–1: <strong>Using</strong> the <strong>TCP</strong> Text Line Inbound Adapter and Business ServiceThe figure above shows the flow of a request from an external data source into <strong>Ensemble</strong> after you have set up an <strong>Ensemble</strong>business service to work <strong>with</strong> an inbound adapter. This figure shows the ingoing data stream only; any response simplyretraces this path. The sequence is as follows:1. At production startup, <strong>Ensemble</strong> creates a background process for each of the business services in the productionconfiguration. <strong>Ensemble</strong> can allocate more than one background process per business service. The business service’sconfigured PoolSize specifies the number of background processes.2. Within each background process, <strong>Ensemble</strong> creates an instance of the business service class and an instance of itsassociated inbound adapter class.3. <strong>Ensemble</strong> calls the OnInit() methods of the business service object and inbound adapter object, respectively.4. Thereafter, whenever the production is running and the business service is enabled and scheduled to be active, thefollowing cycle can occur:• Each time the adapter encounters input from its configured data source, it calls the <strong>Ensemble</strong> framework’sProcessInput() method.• The call to ProcessInput() automatically prompts the <strong>Ensemble</strong> framework to call the associated business service’sOnProcessInput() method.• Code <strong>with</strong>in OnProcessInput() determines what to do <strong>with</strong> the incoming data stream. For example, if an<strong>Ensemble</strong> business process needs to be started, the business service formulates an <strong>Ensemble</strong> request message andissues the synchronous or asynchronous call that starts the business process.If the data source expects an acknowledgment or response of some kind, it is the business service’sOnProcessInput() that constructs it. The inbound adapter simply relays this response back to the external datasource.Note:There is no default implementation of OnProcessInput(). The developer of each business service classis responsible for writing an OnProcessInput() method for that class. For instructions, see the nextsection, “<strong>Using</strong> the Adapter.”36 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


<strong>Using</strong> the AdapterAn <strong>Ensemble</strong> production continues running until it is stopped, either programmatically or by an administrator using theManagement Portal. When a production stops, the following events related to inbound adapters occur:1. <strong>Ensemble</strong> disables each business service; no more incoming requests are accepted for this production.2. The OnTearDown() method in each inbound adapter is called.3. All inbound adapter and business service objects are destroyed and their background processes are killed.4. Each business service’s OnProductionStop class method is called, once for each configured item of that class in theproduction.When a business service is disabled by a system administrator, or becomes inactive according to its configured schedule,the production continues to run but the associated inbound adapter is shut down, and its OnTearDown() method is executed,as described above.6.2 <strong>Using</strong> the AdapterOnce you determine that your production needs the EnsLib.<strong>TCP</strong>.TextLineInboundAdapter, you can include it in the productionconfiguration as follows:1. Choose or create a business service class that uses the EnsLib.<strong>TCP</strong>.TextLineInboundAdapter.2. If you create a new business service class, be sure to:• Implement its OnProcessInput() method.• Compile the class.3. Configure the production. Add a business service of the chosen class.4. Configure the new business service. To do so, click it and specify values for the settings on the right.To enable it, select the Enabled box.The next sections provide details.6.3 Creating a New Business Service ClassThe simplest way to deploy the EnsLib.<strong>TCP</strong>.TextLineInboundAdapter is to choose an existing business service class thatalready uses it. You can choose any business service class that uses the EnsLib.<strong>TCP</strong>.TextLineInboundAdapter, for examplethis built-in business service:• EnsLib.<strong>TCP</strong>.StatusService — Parses a string request to determine what type of production status information is beingrequested. Produces a reply string suitable for writing out to a console screen.If no existing class has the functionality you need, create a new business service class that uses theEnsLib.<strong>TCP</strong>.TextLineInboundAdapter. Create the new class in Studio as follows:1. From the File menu, choose New. A dialog pops up. Edit it as follows:• Click on the Production tab.• Select the Business Service icon and click OK.• Enter a package and class name and click Next.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 37


<strong>Using</strong> the <strong>TCP</strong> Text Line Inbound AdapterImportant:Be sure to avoid reserved package names; see “Reserved Package Names” in Developing<strong>Ensemble</strong> Productions.• Choose EnsLib.<strong>TCP</strong>.TextLineInboundAdapter from the drop-down list of adapter classes.• Click Finish.The result is a template class like the following:Class Dev.Test.NewService1Extends Ens.BusinessService [ ProcedureBlock ]{Parameter ADAPTER = "EnsLib.<strong>TCP</strong>.TextLineInboundAdapter";Method OnProcessInput(pInput As %RegisteredObject,pOutput As %RegisteredObject) As %Status{Quit $$$ERROR($$$NotImplemented)}}2. Implement the OnProcessInput() method in your new business service class. This is the method that uses the inputdata gathered by the EnsLib.<strong>TCP</strong>.TextLineInboundAdapter.You can implement the OnProcessInput() method by replacing the following line in the template class <strong>with</strong> your owncode:Quit $$$ERROR($$$NotImplemented)Your OnProcessInput() method must know the types of incoming and outgoing data for communicating <strong>with</strong> theEnsLib.<strong>TCP</strong>.TextLineInboundAdapter. However, the New Business Service Wizard specifies both types in theOnProcessInput() method signature as the generic object type %RegisteredObject.<strong>InterSystems</strong> suggests that, as your first action in coding the new business service, you change each OnProcessInput()argument to its specific type passed from the adapter:Method OnProcessInput(pInput As Ens.StringContainer,Output pOutput As Ens.StringContainer) As %StatusWhere:• pInput is of type Ens.StringContainer and contains the incoming line of text.• pOutput is of type Ens.StringContainer and contains the outgoing response string (if any).Keep in mind that the method must quit by returning a %Status object. See the code sample in “Sample BusinessService Class Code.”3. Optionally, you may implement the OnConnect() callback method in your business service class.OnConnect() is available for a <strong>TCP</strong> inbound adapter to call back to its associated business service. If present in thebusiness service, this method is called each time the <strong>TCP</strong> inbound adapter establishes a new connection to or from aremote system.If you add an OnConnect() method to your business service class, it must have the following signature:Method OnConnect(pTimeout As %Numeric) As %StatusImplement an OnConnect() method in your business service if you need to take some action each time a new connectionis established, for example to send a logon sequence or a handshake token. The timeout argument is automaticallyprovided by the <strong>TCP</strong> inbound adapter. It takes its value from the ReadTimeout adapter setting. For details, see “AdapterSettings.”38 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


Sample Business Service Class CodeReturning an error status from OnConnect() causes the new connection to fail and be disconnected. If an untrappedexception occurs <strong>with</strong>in OnConnect(), the adapter catches it and continues as if OnConnect() were not implemented.4. Compile your new business service class. Compiling also saves it.5. After creating and compiling the business service class in Studio, add an instance of the business service to the productionand configure it using the Management Portal. See the appendix “Common Tasks in the Management Portal.”When you configure the adapter, you specify a value for the AllowedIPAddresses settings, along other settings. Notethat AllowedIPAddresses provides a way to enable the adapter to initiate the connection; see “Adapter Settings.”6.4 Sample Business Service Class CodeThe following is an example of a business service class that references the EnsLib.<strong>TCP</strong>.TextLineInboundAdapter.Class Test<strong>TCP</strong>TextLine.Authorization<strong>TCP</strong>ServiceExtends Ens.BusinessService [ ProcedureBlock ]{/// Name of the adapter classParameter ADAPTER = "EnsLib.<strong>TCP</strong>.TextLineInboundAdapter";Method OnProcessInput(pInput As Ens.StringContainer,pOutput As Ens.StringContainer) As %Status{set $ZT = "EXCEPTION"set st = $$$OKdo {if ('$isobject($get(pInput))) { quit }// Input must have the following format: 'PatientCode:ProcedureCode'set tSubject = pInput.StringValue$$$TRACE("received line "_tSubject)set req = ##class(Test<strong>TCP</strong>TextLine.AuthorizationRequest).%New()set req.PatientCode = $piece(tSubject,":",1)set req.ProcedureCode = $piece(tSubject,":",2)set st = ..SendRequestSync("AuthorizationProcess", req, .resp)quit:$$$ISERR(st)set pOutput=##class(Ens.StringContainer).%New(resp.AuthorizationFlag_":"_resp.AuthorizationCode)} while (0)EXIT//do ..Adapter.Disconnect()quit stEXCEPTIONset $ZT = ""set st = $$$EnsSystemErrorgoto EXIT}}6.5 Adapter SettingsThis topic describes the settings that are specific to the EnsLib.<strong>TCP</strong>.TextLineInboundAdapter associated <strong>with</strong> the businessservice. For settings not listed here, see “Business Service Settings” in the chapter “Configuration” in Managing<strong>Ensemble</strong> Productions.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 39


<strong>Using</strong> the <strong>TCP</strong> Text Line Inbound AdapterAllowedIPAddressesCallIntervalCharsetA comma-separated list of remote IP addresses from which to accept connections. The adapter accepts named IPaddresses, IPV4 addresses, or IPV6 addresses. An optional :port designation is supported; so, for example, bothof the following address formats are acceptable: 192.168.1.22 or 192.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, onlyone address may be given, and if a port is specified, it supersedes the value of the Port setting; otherwise, the Portsetting is used.Number of seconds that the adapter will listen for incoming data from its configured source, before checking fora shutdown signal from the <strong>Ensemble</strong> framework.If the adapter finds input, it acquires the data and passes it to the business service. The business service processesthe data, and then the adapter immediately begins waiting for new input. This cycle continues whenever the productionis running and the business service is enabled and scheduled to be active.The default CallInterval is 5 seconds. The minimum is 1 second.Specifies the text character set to use to translate characters for the input file. The string is not case-sensitive. Thedefault is Binary. Use Binary for binary files, or for any data in which newline and linefeed characters aredistinct or must remain unchanged, for example in HL7 Version 2 or EDI messages. Other settings may be usefulwhen transferring text documents. Choices include:• Binary — Binary transfer (the default)• Ascii — Ascii mode FTP transfer but no character encoding translation• Default — The default character encoding of the local <strong>Ensemble</strong> server• Latin1 — The ISO Latin1 8-bit encoding• ISO-8859-1 — The ISO Latin1 8-bit encoding• UTF-8 — The Unicode 8-bit encoding• UCS2 — The Unicode 16-bit encoding• UCS2-BE — The Unicode 16-bit encoding (Big-Endian)• Any other alias from an international character encoding standard for which NLS (National Language Support)is installed in <strong>Ensemble</strong>.JobPerConnectionLocalInterfaceWhen True, the adapter spawns a new job to handle each incoming <strong>TCP</strong> connection and allows simultaneoushandling of multiple connections. When False, it does not spawn a new job for each connection; False is usuallythe appropriate choice for HL7 or X12 connections. The default is True.Specifies the network interface through which the <strong>TCP</strong> connection should go. Select a value from the list or typea value. An empty value means use any interface.40 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


Adding a <strong>TCP</strong> Status ServicePortIdentifies the <strong>TCP</strong> port to connect to. <strong>TCP</strong> port numbers have a maximum value of 65535.QSizeReadTimeoutSSLConfigHow many incoming connections the operating system should hold in reserve on behalf of this business service.Set to 0 if only 1 connection at a time is expected. Set to a large number if many clients will connecting rapidly.The default is 100. The range is 0–1000.Number of seconds to wait for each successive incoming <strong>TCP</strong> read operation, following receipt of initial datafrom the remote <strong>TCP</strong> port. The default is 5 seconds. The range is 0–600 seconds (a maximum of 10 minutes).The name of an existing Secure Socket Layer (SSL) or Transport Layer Security (TLS) configuration to use toauthenticate this connection.You can create and manage SSL/TLS configurations using the Management Portal. See the “<strong>Using</strong> SSL/TLS <strong>with</strong>Caché” chapter in the Caché Security Administration Guide.The first field on the Edit SSL/TLS Configuration form is Configuration Name. This is the string to use in the adapter’sSSLConfig field. The SSLConfig string may also add a | (vertical bar) character followed by the private keypassword. The | character is unique because it is not allowed as part of a Configuration Name.StayConnectedIf StayConnected is a positive value, the adapter stays connected to the remote system for this number of secondsbetween input events. A zero value means to disconnect immediately after every input event. The default of –1means to stay permanently connected, even during idle times. <strong>Adapters</strong> are assumed idle at startup and thereforeonly auto-connect if they are configured <strong>with</strong> a StayConnected value of –1.6.6 Adding a <strong>TCP</strong> Status ServiceThe EnsLib.<strong>TCP</strong>.StatusService parses an incoming text string to determine what type of production status information isbeing requested, and then produces a reply string suitable for writing out to the console screen. A user can interact <strong>with</strong> thestatus service directly, or write a command script that contacts the status service, issues commands, and writes the repliesto a text file for later analysis.A developer enables interactions via the status service as follows:1. Add an instance of EnsLib.<strong>TCP</strong>.StatusService to the production.2. Configure the instance of EnsLib.<strong>TCP</strong>.StatusService to accept communications via a particular <strong>TCP</strong> port. Set a Portnumber and a list of AllowedIPAddresses from which to accept connections. These are only two of the several settingsthat are available to configure the <strong>TCP</strong> text line inbound adapter associated <strong>with</strong> the status service. For details, see“Adapter Settings.”Once you have completed these steps, any time the status service is enabled and running, a user or command-line scriptcan initiate a Telnet connection to the configured Port and send commands to the status service. Each command must be atext string that ends <strong>with</strong> the newline character (ASCII 10). The reply strings will also terminate <strong>with</strong> a newline.The following table describes the supported command lines and the contents of the text string returned in each case.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 41


<strong>Using</strong> the <strong>TCP</strong> Text Line Inbound AdapterTable 6–1:<strong>TCP</strong> Status Service CommandsCommand Linebuildconfigitemstatus nameexitlocalstarttimelocaltimenamespaceproductionquitutcstarttimeutctimeversionxText String ReturnedThe full name of the <strong>Ensemble</strong> software version, for example Cache forWindows (x86-32) 2007.1.2 (Build 514U) Mon Aug 13 2007 11:30:37EDTWhen you enter this command <strong>with</strong> the configured name of any business hostin the currently running production, the status service returns a string thatexpresses the current state of that business host.A host that has currently running jobs, or active connections, records thoseactivities in the returned string. If the identified host is not a member of the currentlyrunning production, the returned string indicates this.No string is returned. This command disconnects from the status service. Youmay enter x instead of exitIf <strong>Ensemble</strong> is running, this returns the start time of the currently runningproduction, expressed in local time coordinates. Otherwise, it returns a string<strong>with</strong> the message The current time, in local time coordinates.The <strong>Ensemble</strong> namespace where the currently running production resides.The configured name of the currently running production.No string is returned. This command disconnects from the status service. Youmay enter q instead of quitIf <strong>Ensemble</strong> is running, this returns the start time of the currently runningproduction, is expressed in universal time coordinates (UTC). Otherwise, it returnsa string <strong>with</strong> the message The current time, in universal time coordinates (UTC).The abbreviated name of the <strong>Ensemble</strong> software version, for example2007.1.0.514/2171Same as exit42 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


7<strong>Using</strong> the <strong>TCP</strong> Text Line OutboundAdapterEnsLib.<strong>TCP</strong>.TextLineOutboundAdapter contains methods that an <strong>Ensemble</strong> business operation can call to read or write textstrings across a <strong>TCP</strong> connection. <strong>Ensemble</strong> acts as a <strong>TCP</strong> client exchanging blocks of data <strong>with</strong> a <strong>TCP</strong> listener. The defaultterminator for the text strings is the newline character (ASCII 10). The adapter makes no decisions about the data it relaysout to the external system. It simply maps the request from the business operation to a format that is acceptable to theexternal system.This chapter explains how to use the EnsLib.<strong>TCP</strong>.TextLineOutboundAdapter. It discusses the following topics:• Background Information• <strong>Using</strong> the Adapter• Creating a New Business Operation Class• Available Helper Methods• Adapter Settings7.1 Background InformationYou can simply set up the EnsLib.<strong>TCP</strong>.TextLineOutboundAdapter as instructed in the next section, “<strong>Using</strong> the Adapter.”However, some developers want more details about how a business operation communicates <strong>with</strong> its configured adapter.This section provides those details.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 43


<strong>Using</strong> the <strong>TCP</strong> Text Line Outbound AdapterFigure 7–1: Business Operation and <strong>Using</strong> the <strong>TCP</strong> Text Line Outbound AdapterThe figure above shows the flow of a request from <strong>Ensemble</strong> out to an external system after you have set up an <strong>Ensemble</strong>business operation to work <strong>with</strong> an outbound adapter. The sequence is as follows:1. At production startup, <strong>Ensemble</strong> creates a background process for each of the business operations in the productionconfiguration. <strong>Ensemble</strong> can allocate more than one background process per business operation. The business operation’sconfigured PoolSize specifies the number of background processes.2. Within each background process, <strong>Ensemble</strong> creates an instance of the business operation class and an instance of itsassociated outbound adapter class.3. <strong>Ensemble</strong> calls the OnInit() methods of the business operation object and outbound adapter object, respectively.4. Thereafter, whenever the production is running and the business operation is enabled and scheduled to be active, thefollowing sequence can occur:• The business operation receives an <strong>Ensemble</strong> request message.• The business operation’s message map matches the <strong>Ensemble</strong> request type <strong>with</strong> a business operation method.Note:The developer of each business operation class is responsible for writing its message map and methods.For instructions, see the next section, “<strong>Using</strong> the Adapter.”• The business operation method calls a method in the associated outbound adapter object.• The adapter method sends a request to the external system. If this request generates an acknowledgment or responseof some kind, the outbound adapter relays that data back to the business operation method that invoked it.• If the original <strong>Ensemble</strong> request message requires a response, the business operation returns it.44 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


<strong>Using</strong> the AdapterAn <strong>Ensemble</strong> production continues running until it is stopped, either programmatically or by an administrator using theManagement Portal. When a production stops, the following events related to outbound adapters occur:1. <strong>Ensemble</strong> waits for each business operation to reach a quiescent state (that is, <strong>Ensemble</strong> waits until each businessoperation has completed all of its synchronous requests).2. The OnTearDown() method in each outbound adapter is called.3. All outbound adapter and business operation objects are destroyed and their background processes are killed.4. Each business operation’s OnProductionStop class method is called, once for each configured item of that class inthe production.When a business operation is disabled by a system administrator, or becomes inactive according to its configured schedule,the production continues to run but the associated outbound adapter is shut down, and its OnTearDown() method is executed,as described above.7.2 <strong>Using</strong> the AdapterOnce you determine that your production needs the EnsLib.<strong>TCP</strong>.TextLineOutboundAdapter, you can include it in the productionconfiguration as follows:1. Choose or create a business operation class that uses the EnsLib.<strong>TCP</strong>.TextLineOutboundAdapter.2. If you create a new business operation class, be sure to:• Add at least one method to the method map.• Implement each method in the method map.• Write the business operation methods so that they call methods from the EnsLib.<strong>TCP</strong>.TextLineOutboundAdapterclass.• Compile the new class.3. Configure the production. Add a business operation of the chosen class.4. Configure the new business operation. To do so, click it and specify values for the settings on the right.To enable it, select the Enabled box.The next sections provide details.7.3 Creating a New Business Operation ClassThe simplest way to deploy the EnsLib.<strong>TCP</strong>.TextLineOutboundAdapter is to choose an existing business operation class thatalready uses it.If no existing class has the functionality you need, create a business operation class that uses theEnsLib.<strong>TCP</strong>.TextLineOutboundAdapter. Create the new class as follows:1. From the File menu, choose New. A dialog pops up. Edit it as follows:• Click on the Production tab.• Select the Business Operation icon and click OK.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 45


<strong>Using</strong> the <strong>TCP</strong> Text Line Outbound Adapter• Enter a package and class name and click Next.Important:Be sure to avoid reserved package names; see “Reserved Package Names” in Developing<strong>Ensemble</strong> Productions.• Choose EnsLib.<strong>TCP</strong>.TextLineOutboundAdapter from the drop-down list of adapter classes.• Choose the default invocation style Queue. The alternative is InProc, but generally you want Queue. The differencesare as follows:– Queue means the message is created <strong>with</strong>in one background job and placed on a queue, at which time theoriginal job is released. Later, when the message is processed, a different background job will be allocatedfor the task.– InProc means the message will be formulated, sent, and delivered in the same job in which it was created.The job will not be released to the sender’s pool until the message is delivered to the target. This is onlysuitable for special cases.• Add at least one entry to the method map as follows:–Click the Add icon.– Enter the method name.– Choose a request type and a response type.– Click OK.Repeat these steps as needed to add entries to the method map.• Click Finish.The result is a template class like the following:Class Dev.Test.NewOperation1 Extends Ens.BusinessOperation [ ProcedureBlock ]{Parameter ADAPTER = "EnsLib.<strong>TCP</strong>.TextLineOutboundAdapter";Parameter INVOCATION = "Queue";Method SampleCall(pRequest As Ens.Request,Output pResponse As Ens.Response) As %Status{Quit $$$ERROR($$$NotImplemented)}XData MessageMap{SampleCall}}2. Implement the method(s) in your new business operation class.Where the following line appears, replace it <strong>with</strong> your own code:Quit $$$ERROR($$$NotImplemented)Keep in mind that the method must quit by returning a %Status object.46 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


Available Helper Methods3. When you want to call one of the methods in EnsLib.<strong>TCP</strong>.TextLineOutboundAdapter, use the Adapter property to identifythe adapter object. In the following example, the Demo.Loan.FindRate<strong>TCP</strong>Operation class calls theEnsLib.<strong>TCP</strong>.TextLineOutboundAdapter method SendMessageString:/// Send an approval to the output <strong>TCP</strong> listenerMethod <strong>TCP</strong>SendReply(pRequest As Demo.Loan.Msg.SendReply,Output pResponse As Ens.Response) As %Status{Set tSC=..Adapter.SendMessageString(pRequest.Text)}Quit tSCYou can use similar syntax to call any of the EnsLib.<strong>TCP</strong>.TextLineOutboundAdapter methods described in “AvailableHelper Methods.”4. Optionally, you may implement the OnConnect() callback method in your business operation class.OnConnect() is available for a <strong>TCP</strong> outbound adapter to call back to its associated business operation. If present inthe business operation, this method is called each time the <strong>TCP</strong> outbound adapter establishes a new connection to orfrom a remote system.If you add an OnConnect() method to your business operation class, it must have the following signature:Method OnConnect(pTimeout As %Numeric) As %StatusImplement an OnConnect() method in your business operation if you need to take some action each time a new connectionis established, for example to send a logon sequence or a handshake token. The timeout argument is automaticallyprovided by the <strong>TCP</strong> outbound adapter. It takes its value from the ConnectTimeout adapter setting. For details, see“Adapter Settings.”Returning an error status from OnConnect() causes the new connection to fail and be disconnected. If an untrappedexception occurs <strong>with</strong>in OnConnect(), the adapter catches it and continues as if OnConnect() were not implemented.5. Compile your new business operation class. Compiling also saves it.6. After creating and compiling the business operation class in Studio, add an instance of the business operation to theproduction and configure it using the Management Portal. See the appendix “Common Tasks in the ManagementPortal.”7.4 Available Helper MethodsWhen your business operation class references the EnsLib.<strong>TCP</strong>.TextLineOutboundAdapter, the following adapter methodsbecome available. You can call these adapter methods from the methods in your business operation class using the Adapterproperty as described in the previous section:Connect()Method Connect(pTimeout As %Numeric) As %StatusConnect() opens a <strong>TCP</strong> socket to a port on the <strong>TCP</strong> listener machine. Connect() has one input argument, a%Numeric value that identifies the number of seconds to wait for the connection attempt to succeed. A typical callto the Connect() method gives this input argument the value of the configurable ConnectTimeout property.If the StayConnected adapter setting is set to –1, the <strong>Ensemble</strong> framework will create the connection automaticallyat startup time, from <strong>with</strong>in the OnInit() method.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 47


<strong>Using</strong> the <strong>TCP</strong> Text Line Outbound AdapterDisconnect()Method Disconnect()Disconnect() takes down the connection to the <strong>TCP</strong> listener.SendMessageStringMethod SendMessageString(pRequestString As %String,Output pResponseString As %String) As %StatusSendMessageString sends the string contents as a text line on the <strong>TCP</strong> socket.TestConnection()Method TestConnection()TestConnection() corrects the properties reflecting the connection state. If the adapter is connected,TestConnection() returns True. If not, TestConnection() calls Disconnect() and returns False.7.5 Adapter SettingsThis topic describes the settings that are specific to the EnsLib.<strong>TCP</strong>.TextLineOutboundAdapter associated <strong>with</strong> the businessoperation. For settings not listed here, see “Business Operation Settings” in the chapter “Configuration” in Managing<strong>Ensemble</strong> Productions.CharsetSpecifies the text character set to use to translate characters for the input file. The string is not case-sensitive. Thedefault is Binary. Use Binary for binary files, or for any data in which newline and linefeed characters aredistinct or must remain unchanged, for example in HL7 Version 2 or EDI messages. Other settings may be usefulwhen transferring text documents. Choices include:• Binary — Binary transfer (the default)• Ascii — Ascii mode FTP transfer but no character encoding translation• Default — The default character encoding of the local <strong>Ensemble</strong> server• Latin1 — The ISO Latin1 8-bit encoding• ISO-8859-1 — The ISO Latin1 8-bit encoding• UTF-8 — The Unicode 8-bit encoding• UCS2 — The Unicode 16-bit encoding• UCS2-BE — The Unicode 16-bit encoding (Big-Endian)• Any other alias from an international character encoding standard for which NLS (National Language Support)is installed in <strong>Ensemble</strong>.ConnectTimeoutNumber of seconds to wait on each attempt to connect to the remote <strong>TCP</strong> listener. The default is 5 seconds.48 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


Adapter SettingsGetReplyIPAddressLocalInterfacePortQSizeReadTimeoutSSLConfigIf 1 (true) wait to read a reply message back from the socket before returning. If 0 (false) do not wait. The defaultvalue is 1.IP address to make a <strong>TCP</strong> connection to. The adapter accepts a named IP address, an IPV4 address, or an IPV6address.If the address starts <strong>with</strong> a ! character, the adapter waits for a connection from a remote system. In this case, followthe exclamation point <strong>with</strong> a comma-separated list of remote IP addresses from which to accept connections. Theadapter accepts named IP addresses, IPV4 addresses, or IPV6 addresses. An optional :port designation is supported;so, for example, both of the following address formats are acceptable: 192.168.1.22 or 192.168.1.22:3298.If no IP address follows the ! character, any remote system may connect; otherwise only the listed IP addresses(and ports) are allowed to connect.Specifies the network interface through which the <strong>TCP</strong> connection should go. Select a value from the list or typea value. An empty value means use any interface.This setting allows you to specify that a virtual IP address should be used to send outbound traffic, which is usefulin the case of mirroring. If a remote application is configured to accept traffic from the virtual IP address, and boththe primary and the secondary use that IP address to connect to the remote application, then everything continuesto work when the secondary starts sending.Identifies the <strong>TCP</strong> port to connect to. <strong>TCP</strong> port numbers have a maximum value of 65535.How many incoming connections the operating system should hold in reserve on behalf of this business operation.There is generally no reason to change the default value of 0. Either the connection is outbound, or the businessoperation is using '!' inbound mode, in which case only 1 client is allowed at a time, per business operation pooljob.Number of seconds to wait for each successive incoming <strong>TCP</strong> read operation, following receipt of initial datafrom the remote <strong>TCP</strong> port. The default is 5 seconds. The range is 0–600 seconds (a maximum of 10 minutes).The name of an existing Secure Socket Layer (SSL) or Transport Layer Security (TLS) configuration to use toauthenticate this connection.You can create and manage SSL/TLS configurations using the Management Portal. See “<strong>Using</strong> SSL/TLS <strong>with</strong>Caché” in the Caché Security Administration Guide.The first field on the Edit SSL/TLS Configuration form is Configuration Name. This is the string to use in the adapter’sSSLConfig field. The SSLConfig string may also add a | (vertical bar) character followed by the private keypassword. The | character is unique because it is not allowed as part of a Configuration Name.ReconnectRetryNumber of retries at which to drop the connection and try reconnecting again. A value of 0 (zero) means neverdisconnect. The default value is 5.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 49


<strong>Using</strong> the <strong>TCP</strong> Text Line Outbound AdapterResponseTimeoutNumber of seconds to wait for a response to begin arriving back from the remote system after sending a request.The default is 15 seconds.StayConnectedIf StayConnected is a positive value, the adapter stays connected to the remote system for this number of secondsafter completing an operation. A zero value means to disconnect immediately after every operation. The defaultof –1 means to stay permanently connected, even during idle times. <strong>Adapters</strong> are assumed idle at startup andtherefore only auto-connect if they are configured <strong>with</strong> a StayConnected value of –1.50 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


8Creating Custom <strong>TCP</strong> Adapter ClassesThis chapter discusses how to create custom <strong>TCP</strong> adapter classes. It discusses the following topics:• Creating a Custom Subclass• Common Customizations in <strong>TCP</strong> Adapter Subclasses• Customizing Callbacks of Inbound <strong>TCP</strong> <strong>Adapters</strong>• Customizing Callbacks of Outbound <strong>TCP</strong> <strong>Adapters</strong>8.1 Creating a Custom SubclassTo create a custom subclass of an adapter class, do the following in Studio:1. On the File menu, click New, and then click the General tab.2. Start the New Class Wizard by clicking Caché Class Definition and clicking OK.a. Enter a package and class name and click Next.Important:Be sure to avoid reserved package names; see “Reserved Package Names” in Developing<strong>Ensemble</strong> Productions.b. Click Extends for the Class type.c. Click Browse next to Name of super class and navigate to the class that you want to subclass.d. Click OK.e. Click Finish.The result is a template class like the following, depending on the class you chose:Class MyTest.NewClass1 Extends EnsLib.<strong>TCP</strong>.InboundAdapter [ ProcedureBlock ]{}3. You can override any property, method, class parameter, or other class member inherited from the class or its parentclasses, or you can add new class members. The only requirements are as follows:• An inbound adapter class must implement the OnConnected() method.In your implementation, use helper methods inherited by your class.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 51


Creating Custom <strong>TCP</strong> Adapter Classes• An outbound adapter class define methods that create a <strong>TCP</strong> connection, read or write over the connection, anddisconnect.To define these methods, use helper methods inherited by your class.4. Compile the class, which also saves it.8.2 Common Customizations in <strong>TCP</strong> Adapter SubclassesThe following list suggests some common customizations in <strong>TCP</strong> adapter subclasses, in addition to implementing themethods that the adapter needs:• The Terminators property is a common property to edit. You can specify an initial expression for this property.Your adapter class can set a value for Terminators using the ObjectScript function $CHAR or $C to identify the ASCIIvalue for the character. The following example from EnsLib.<strong>TCP</strong>.TextLineInboundAdapter sets Terminators to thenewline character (ASCII 10):Property Terminators As %String [ InitialExpression = {$C(10)} ];For more information about functions like $CHAR, see “Caché ObjectScript Functions” in the Caché ObjectScriptReference.You can set Terminators to a single character or to a multi-character string. If you supply a string for the Terminatorsvalue, <strong>Ensemble</strong> uses the string as follows:– Any one of the characters in the string serves to terminate the input.– The complete string of characters is appended to the output.• You can expose additional properties for runtime configuration by providing a SETTINGS parameter whose value isa comma-separated list of the properties that you want to expose. For example:/// The full pathname for a transaction log file on the local computerProperty LogPath As %String(MAXLEN = 200) [ Required ];/// The simple file name for the logProperty LogSpec As %String(MAXLEN = 60) [ InitialExpression = "*" ];/// These properties are exposed for runtime configuration via the portalParameter SETTINGS = "LogPath,LogSpec";At runtime, properties from this SETTINGS list appear in the display on the [<strong>Ensemble</strong>] > [Production Configuration]page as additional settings.• If you need to require login credentials for the connection, simply add the property name Credentials to theSETTINGS list. The Credentials property is already defined as a %String in the base class Ens.Adapter.For background information, see “Username and Password Credentials” in the chapter “Production Concepts” inDeveloping <strong>Ensemble</strong> Productions.• (For inbound adapters) You can also enforce a pool size of 1 by setting the parameter SINGLEPOOLJOB = 1:/// Force a single listener job regardless of PoolSize settingParameter SINGLEPOOLJOB = 1;Any subclass of this adapter class or a business service class that uses such an adapter class can use this parameter inits class code to better control the pool size.52 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


Customizing Callbacks of Inbound <strong>TCP</strong> <strong>Adapters</strong>8.3 Customizing Callbacks of Inbound <strong>TCP</strong> <strong>Adapters</strong>If you subclass or copy an inbound <strong>TCP</strong> adapter, you can override these methods <strong>with</strong> unique behaviors:OnConnected()OnInit()Method OnConnected() As %StatusWhenever a connection exists to the configured <strong>TCP</strong> client, the adapter calls OnConnected() to read a streamfrom the <strong>TCP</strong> data source. This read operation is controlled by adapter settings.OnConnected() uses helper methods to parse the data.Upon successfully reading data, OnConnected() calls the <strong>Ensemble</strong> framework’s ProcessInput() method to passthe received data stream to the associated business service. If this call returns an outbound stream, OnConnected()writes that data as a reply to the <strong>TCP</strong> client.If no data is available to read from the <strong>TCP</strong> connection during the CallInterval time, OnConnected() returns<strong>with</strong>out doing anything.Also see the OnTask() method.Method OnInit() As %StatusThe <strong>Ensemble</strong> framework calls OnInit() after creating the inbound adapter instance and setting its configurableproperty values. The OnInit() method provides a way for the inbound adapter to perform any special setup actions.Depending on the values of the relevant adapter settings, one of these actions might be to initiate a connectionbetween the adapter and the <strong>TCP</strong> client it will listen to, or to construct any object properties that the adapter willuse.OnTearDown()OnTask()Method OnTearDown() As %StatusThe <strong>Ensemble</strong> framework calls OnTearDown() during shutdown, before destroying the inbound adapter object.The OnTearDown() method provides a way for an inbound adapter to perform any special cleanup actions suchas disconnecting from the <strong>TCP</strong> client.Method OnTask() As %StatusAll inbound adapters have an OnTask() method, where the bulk of the adapter work is done. Once a productionstarts, each business service calls the OnTask() method of its associated inbound adapter class, at the time intervaldetermined by the adapter’s CallInterval setting. For details, see “Business Service Life Cycle” in the “BusinessServices” in Developing <strong>Ensemble</strong> Productions.For more detailed information about adapter class internals, open the class in Studio or use the <strong>InterSystems</strong> Class Reference.8.4 Customizing Callbacks of Outbound <strong>TCP</strong> <strong>Adapters</strong>If you subclass or copy an outbound <strong>TCP</strong> adapter, you can override these methods <strong>with</strong> unique behaviors:<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 53


Creating Custom <strong>TCP</strong> Adapter ClassesOnInit()Method OnInit() As %StatusThe <strong>Ensemble</strong> framework calls OnInit() after creating the outbound adapter object and setting its configurableproperty values. The OnInit() method provides a way for an outbound adapter to perform any special setup actions.Depending on the values of the relevant adapter settings, one of these actions might be to open a socket to a porton the <strong>TCP</strong> listener.OnTearDown()Method OnTearDown() As %StatusThe <strong>Ensemble</strong> framework calls OnTearDown() during shutdown, before destroying the outbound adapter object.The OnTearDown() method provides a way for an outbound adapter to perform any special cleanup actions suchas disconnecting from the <strong>TCP</strong> listener.54 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


ASettings for the Abstract <strong>TCP</strong> <strong>Adapters</strong>For reference, this appendix describes the settings defined in the two abstract <strong>TCP</strong> adapters:• Settings for EnsLib.<strong>TCP</strong>.InboundAdapter• Settings for EnsLib.<strong>TCP</strong>.OutboundAdapterA.1 Settings for EnsLib.<strong>TCP</strong>.InboundAdapterThis topic describes the settings that are specific to the EnsLib.<strong>TCP</strong>.InboundAdapter or any subclass.AllowedIPAddressesCallIntervalA comma-separated list of remote IP addresses from which to accept connections. The adapter accepts named IPaddresses, IPV4 addresses, or IPV6 addresses. An optional :port designation is supported; so, for example, bothof the following address formats are acceptable: 192.168.1.22 or 192.168.1.22:3298.If a port number is specified, <strong>Ensemble</strong> refuses connections from other ports.If the string starts <strong>with</strong> an exclamation point (!) character, the adapter initiates a connection to the specified address.In this case, you can only provide one address, and if you specify a port, it supersedes the value of the Port setting.Number of seconds that the adapter listens for incoming data from its configured source, before checking for ashutdown signal from the <strong>Ensemble</strong> framework.If the adapter finds input, it acquires the data and passes it to the business service. The business service processesthe data, and then the adapter immediately begins waiting for new input. This cycle continues whenever the productionis running and the business service is enabled and scheduled to be active.The default CallInterval is 5 seconds. The minimum is 1 second.JobPerConnectionWhen True, the adapter spawns a new job to handle each incoming <strong>TCP</strong> connection and allows simultaneoushandling of multiple connections. When False, it does not spawn a new job for each connection; False is usuallythe appropriate choice for HL7 or X12 connections. The default is True.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 55


Settings for the Abstract <strong>TCP</strong> <strong>Adapters</strong>LocalInterfacePortFor <strong>TCP</strong> services, when JobPerConnection is True, a freshly spawned job handles each new incoming socketconnection rather than the listener job itself. Only one job at a time can be the listener, and one job must be thelistener, so a <strong>TCP</strong> service configured <strong>with</strong> a PoolSize greater than 1 still only starts one listener job. However, thislistener can spawn an unlimited number of connection jobs if JobPerConnection is set to True. If you set thePoolSize to a value greater than 1, it serves as a limit on the number of simultaneous connection jobs that can exist.When this limit is reached, the listener does not accept any more connections until one or more of the existingconnection jobs quits or dies. An Event Log warning appears when it first reaches the limit.Specifies the network interface through which the <strong>TCP</strong> connection should go. Select a value from the list or typea value. An empty value means use any interface.Identifies the <strong>TCP</strong> port to which to connect. <strong>TCP</strong> port numbers have a maximum value of 65535.OSAcceptConnectionQueueSizeReadTimeoutHow many incoming connections the operating system should hold in reserve on behalf of this business service.Set to 0 if only 1 connection at a time is expected. Set to a large number if you expect many clients to connectrapidly. The default is 100. The range is 0–1000.Number of seconds to wait for each successive incoming <strong>TCP</strong> read operation, following receipt of initial datafrom the remote <strong>TCP</strong> port. The default is 5 seconds. The range is 0–600 seconds (a maximum of 10 minutes).StayConnectedSSLConfigIf StayConnected is a positive value, the adapter stays connected to the remote system for this number of secondsbetween input events. A zero value means to disconnect immediately after every input event. The default of -1means to stay permanently connected, even during idle times. <strong>Adapters</strong> are assumed idle at startup and thereforeonly auto-connect if you set StayConnected to a value of -1.The name of an existing Secure Socket Layer (SSL) or Transport Layer Security (TLS) configuration to use toauthenticate this connection.You can create and manage SSL/TLS configurations using the System Management Portal. See the “<strong>Using</strong>SSL/TLS <strong>with</strong> Caché” chapter in the Caché Security Administration Guide.The first field on the Edit SSL/TLS Configuration form is Configuration Name. This is the string to use in the adapter’sSSLConfig setting. The SSLConfig string may also add a | (vertical bar) character followed by the private keypassword. The | character is unique because it is not allowed as part of a Configuration Name.A.2 Settings for EnsLib.<strong>TCP</strong>.OutboundAdapterThis topic describes the settings that are specific to the EnsLib.<strong>TCP</strong>.OutboundAdapter or any subclass.GetReplyIf True, wait to read a reply message back from the socket before returning. If False, do not wait. The default valueis True.56 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>


Settings for EnsLib.<strong>TCP</strong>.OutboundAdapterIPAddressPortIP address to make a <strong>TCP</strong> connection to. The adapter accepts a named IP address, an IPV4 address, or an IPV6address.If the address starts <strong>with</strong> a ! character, the adapter waits for a connection from a remote system. In this case, followthe exclamation point <strong>with</strong> a comma-separated list of remote IP addresses from which to accept connections. Theadapter accepts named IP addresses, IPV4 addresses, or IPV6 addresses. An optional :port designation is supported;so, for example, both of the following address formats are acceptable: 192.168.1.22 or 192.168.1.22:3298.If no IP address follows the ! character, any remote system may connect; otherwise only the listed IP addresses(and ports) are allowed to connect.Identifies the <strong>TCP</strong> port to which to connect. <strong>TCP</strong> port numbers have a maximum value of 65535.StayConnectedIf StayConnected is a positive value, the adapter stays connected to the remote system for this number of secondsafter completing an operation. A zero value means to disconnect immediately after every operation. The defaultof -1 means to stay permanently connected, even during idle times. <strong>Adapters</strong> are assumed idle at startup andtherefore only auto-connect if they are configured <strong>with</strong> a StayConnected value of -1.ConnectTimeoutLocalInterfaceNumber of seconds to wait on each attempt to connect to the remote <strong>TCP</strong> listener. The default is 5 seconds.Specifies the network interface through which the <strong>TCP</strong> connection should go. Select a value from the list or typea value. An empty value means use any interface.This setting allows you to specify that a virtual IP address should be used to send outbound traffic, which is usefulin the case of mirroring. If a remote application is configured to accept traffic from the virtual IP address, and boththe primary and the secondary use that IP address to connect to the remote application, then everything continuesto work when the secondary starts sending.ReconnectRetryNumber of retries at which to drop the connection and try reconnecting again. A value of 0 (zero) means neverdisconnect. The default value is 5.ResponseTimeoutReadTimeoutSSLConfigNumber of seconds to wait for a response to begin arriving back from the remote system after sending a request.The default is 15 seconds.Number of seconds to wait for each successive incoming <strong>TCP</strong> read operation, following receipt of initial datafrom the remote <strong>TCP</strong> port. The default is 5 seconds. The range is 0–600 seconds (a maximum of 10 minutes).The name of an existing Secure Socket Layer (SSL) or Transport Layer Security (TLS) configuration to use toauthenticate this connection.<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 57


BCommon Tasks in the Management PortalThis appendix provides a little more detail on some of the tasks described in this book. It discusses:• Accessing a Production• Adding a Business Host to a Production• Editing Runtime Settings of a Business HostB.1 Accessing a ProductionTo access a production, do the following:1. In the Management Portal, switch to the appropriate namespace.To do so, click Switch in the title bar, click the namespace, and click OK.2. Click <strong>Ensemble</strong>.3. Click Configure.4. Click Production and then click Go.<strong>Ensemble</strong> then displays the last production you accessed, <strong>with</strong>in the [<strong>Ensemble</strong>] > [Production Configuration] page.5. To display a different production:a. Click Actions.b. Click Open.c. Click the name of the production and then click OK.B.2 Adding a Business Host to a ProductionTo add a business service, process, or operation to a production, do the following:1. Access the production, as described earlier in this appendix.2.In the Services, Processes, or Operations column, as appropriate, click the Add button .<strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong> 59


Common Tasks in the Management Portal<strong>Ensemble</strong> displays a dialog box.3. In the first drop-down list, choose the class on which to base the new business host.4. Optionally specify the other items as follows:• Service Name (or Business Process Name or Operation Name) — Type the name of this business host. The nameshould be unique <strong>with</strong>in this category of business host. Do not use periods or spaces.The default is the name of the class on which the host is based.• Display Category — Choose or type the name of the display category to which this business host belongs. Youcan use this to display different sets of business hosts in the Production Configuration page. If a production has alarge number of business hosts, it can be helpful to display only a subset. This setting does not affect how theproduction works.Display Category names are case-sensitive, and space characters are allowed. To place an item in multiple categories,list them in the Display Category field separated by commas (do not allow spaces around these commas).• Comment — Type a comment.• Enable Now — Select this to enable the host immediately.5. Click OK.B.3 Editing Runtime Settings of a Business HostTo edit the settings of a business service, process, or operation, use the following general process:1. Access the production in which this host is defined, as described earlier in this appendix.2. Click the business service, process, or operation in the main area of the page.3. Click the Settings tab in the right area.This tab displays settings in groups, which you can display or hide separately.The setting names that appear in the right pane are, in many cases, localized descriptions of the class property names.You can hover the cursor over any setting name to display its help text as it appears in the Class Reference or click thesetting name to display the help text in a separate pop-up window.4. Make edits as needed.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 currently running.60 <strong>Using</strong> <strong>TCP</strong> <strong>Adapters</strong> <strong>with</strong> <strong>Ensemble</strong>

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

Saved successfully!

Ooh no, something went wrong!