1. Trang chủ
  2. » Công Nghệ Thông Tin

Pro BizTalk 2006 phần 4 pot

52 138 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 52
Dung lượng 490,63 KB

Nội dung

The solution to the problem is simple—just write the value to the message context using code as shown in the following snippet. Note the format of the property name and the name- space. In order to be processed by the orchestration engine, they must be named as follows: Name: The distinguished field location in XPath: "/*[local-name()='PurchaseOrder' and n amespace-uri()='http://ABC.FullFillment']/*[local-name()='UnitPrice' and namespace-uri()='']" Namespace URI: "http://schemas.microsoft.com/BizTalk/2003/ btsDistinguishedFields" //BizTalk System Properties Namespace Private Const BTSFieldXPathLocation As String = "/*[local-name()='PurchaseOrder' _ and namespace-uri()='http://ABC.FullFillment']/*[local-name()='UnitPrice' and _ namespace-uri()='']" Private Const BTSDistinguishedFieldsPropertiesNamespace As String = "_ http://schemas.microsoft.com/BizTalk/2003/btsDistinguishedFields " //Write a distinguished property message.Context.Write(BTSFieldXPathLocation, _ BTSDistinguishedFieldsPropertiesNamespace, 10); Checking for Schema Types in Components As was stated previously, pipeline components that are expecting incoming documents to conform to a particular schema should do two things: • They should probe the incoming document and determine whether they can process it based on the schema’s namespace and root node. • They should allow the developer to choose the allowed incoming schemas at design time using the Pipeline Designer. V alidating, also called pr obing the message , checks the incoming schema and simply indicates to the runtime that the component will be able to handle the schema—essentially a Boolean value. Ensuring that components validate against the schema is critical, as it often allo ws the same component code to be reused for multiple applications and also allo ws for per-instance pipeline configuration. This is done using the IProbeMessage interface. IProbeMessage The IProbeMessage interface has only one method—Probe. This method checks whether the incoming message is in a r ecognizable format. The Probe method passes in the pipeline con - text object as an IPipelineContext interface along with the message r epr esented as an IBaseMessage Interface and returns a Boolean. If the method returns False, the pipeline com- ponent cannot pr ocess the message , the current component instance stops executing, and the pipeline component execution sequence continues as defined in F igur e 4-3. I f it r etur ns True , then the pipeline component executes as normal with its primary operation (Encode, Execute, Disassemble, etc.). CHAPTER 4 ■ PIPELINING AND COMPONENTS 131 6994ch04final.qxd 10/2/06 12:32 AM Page 131 F ollowing is an example of a simple I ProbeMessage i mplementation: P ublic Class MyProber Implements Microsoft.BizTalk.Component.Interop.IProbeMessage Private _MyDocSpec As Microsoft.BizTalk.Component.Utilities.SchemaWithNone = New_ Microsoft.BizTalk.Component.Utilities.SchemaWithNone("") '<summary> 'This property is the document specification for the inbound document. Only 'documents of this type will be accepted. The SchemaWithNone allows the developer to 'select the inbound document type from a pick list. '</summary> <Description("The inbound request document specification. Only messages of this _ type will be accepted by the component.")> _ Public Property MyDocSpec() As Microsoft.BizTalk.Component.Utilities.SchemaWithNone Get Return _MyDocSpec End Get Set(ByVal Value As Microsoft.BizTalk.Component.Utilities.SchemaWithNone) _MyDocSpec = Value End Set End Property Public Function Probe(ByVal pc As _ Microsoft.BizTalk.Component.Interop.IPipelineContext, ByVal inmsg As _ Microsoft.BizTalk.Message.Interop.IBaseMessage) As Boolean Implements _ Microsoft.BizTalk.Component.Interop.IProbeMessage.Probe Dim streamReader As New streamReader(inmsg.BodyPart.Data) Dim xmlreader As New Xml.XmlTextReader(inmsg.BodyPart.Data) xmlreader.MoveToContent() If (_MyDocSpec.DocSpecName = xmlreader.NamespaceURI.Replace("http://", _ "")) Then Return True Else Return False End If End Function End Class Schema Selection in VS .NET Designer The property MyDocSpec in the pr evious section’ s MyProber class is actually of type SchemaWithNone. SchemaWithNone is a class that lives in the Microsoft.BizTalk. Component.Utilities.dll assembly. Defining a property of type SchemaWithNone will give the user a dr op-do wn list of all deplo yed schemas within the current BizTalk Management Data- base. The class has one public constructor, SchemaWithNone, which initializes a new instance CHAPTER 4 ■ PIPELINING AND COMPONENTS132 6994ch04final.qxd 10/2/06 12:32 AM Page 132 o f the S chemaWithNone c lass. Tables 4-10 and 4-11 list the public properties and methods of the class. Table 4-10. SchemaWithNone Public Properties Property Description AssemblyName (inherited from Schema) Gets or sets the schema assembly name DocSpecName (inherited from Schema) Gets or sets the document spec name for the selected schema RootName (inherited from Schema) Gets or sets the root node of the selected schema SchemaName (inherited from Schema) Gets or sets the selected schema name TargetNamespace (inherited from Schema) Gets or sets the target namespace of the selected schema Table 4-11. SchemaWithNone Public Methods Method Description Equals (inherited fr om Schema) Ov erridden. Determines whether the specified Object is equal to the current Object. GetHashCode (inherited from Schema) Overridden. Returns the hash code for this instance. GetType (inherited from System.Object) For additional information about the System name- space, see the .NET Framework documentation avail- able from Visual Studio .NET or online at http://go.microsoft.com/fwlink/?LinkID=9677. ToString (inherited from Schema) Overridden. Converts the value of this instance to its equivalent string representation using the specified for- mat. As you can see in Figure 4-11, the properties for the SchemaWithNone class are available in the IDE. If you notice the InboundDocSpec property, it is a list of all the schemas that are cur- rently deployed to the BizTalk solution. The SchemaWithNone property allows you to select one and only one schema from the deployed schemas, and this information will be used to popu- late the properties of the object as defined previously ( AssemblyName, DocSpecName, etc.). In the example from the preceding section, you want your developer to select only one schema, but what if your developer needs multiple? In many cases, your component will be able to handle a variety of schemas; in this case, you need to use the SchemaList property. I n the case wher e your property needs to select multiple schemas, you need to use the SchemaList object. Such an object will provide developers with an associate window from which they can choose multiple schemas. The selected schemas will be available as a collec- tion of schemas within a main class. The IDE will present a screen as shown in Figure 4-12. CHAPTER 4 ■ PIPELINING AND COMPONENTS 133 6994ch04final.qxd 10/2/06 12:32 AM Page 133 Decorating Your Properties I t is important to consider the usability of your components from within the Visual Studio IDE. If you simply expose a public property from within your pipeline component, two things will happen. First, the property name that is displayed in the IDE will be the name of the property (in Figure 4-10 earlier, this would be InboundDocumentList, etc.). Second, there is no public description for what the property actually does. In order to make your components usable, you can use custom attributes to decorate your properties with metadata so that the developer experience is improved. The two main attributes you can use to do this are described next. Using the DisplayName and Description Attributes The DisplayName attribute allows you to set the name for the property that will be displayed in the IDE. The Description attribute sets the description box within the VS .NET designer to CHAPTER 4 ■ PIPELINING AND COMPONENTS134 Figure 4-11. SchemaWithNone example in VS .NET Figure 4-12. SchemaList example in VS .NET 6994ch04final.qxd 10/2/06 12:32 AM Page 134 a friendly description. The effect of these attributes is shown in Figure 4-13. The following code snippet demonstrates how these attributes are to be used: '<summary> 'this property will contain a single schema ' </summary> <Description("The inbound request document specification. Only messages of this _ type will be accepted by the component.")> _ <DisplayName("Inbound Specification")> _ Public Property InboundFileDocumentSpecification() As _ Microsoft.BizTalk.Component.Utilities.SchemaWithNone Get Return _InboundFileDocumentSpecification End Get Set(ByVal Value As Microsoft.BizTalk.Component.Utilities.SchemaWithNone) _ InboundFileDocumentSpecification = Value End Set End Property Validating and Storing Properties in the Designer As in any component dev elopment model, it is necessary to store properties that a user selects for y our component so y ou can load them at runtime and also validate that the v alues chosen by the user are appropriate. To perform validation, you need to use the IComponentUI interface and implement the Validate function. To store and load information for runtime use, you use the IPersistPropertyBag inter face and implement the Load and Save functions . E xample method implementations are given in the following text. CHAPTER 4 ■ PIPELINING AND COMPONENTS 135 Figure 4-13. DisplayName and Description attributes set 6994ch04final.qxd 10/2/06 12:32 AM Page 135 Validating User Input IComponentUI.Validate is used to validate any property information and display an error mes- sage to the user when the project is compiled. Most implementations use either a collection or an ArrayList to store the errors. You then need to return the IEnumerator object from the ArrayList or collection at the end of the method with all the error messages you want dis- played populated. The following example demonstrates how you can validate a developer’s input from within the IDE. Any errors are returned to the user as errors in the IDE’s error window. '<summary> 'The Validate method is called by the BizTalk Editor during the build 'of a BizTalk project. '</summary> '<param name="obj">An Object containing the configuration 'properties.</param> '<returns>The IEnumerator enables the caller to enumerate through a collection of 'strings containing error messages. These error messages appear as compiler error 'messages. To report successful property validation, the method should return an 'empty enumerator.</returns> Public Function Validate(ByVal obj As Object) As System.Collections.IEnumerator_ Implements Microsoft.BizTalk.Component.Interop.IComponentUI.Validate 'example implementation: Dim errorArray As New ArrayList errorArray.Add("This is an error that will be shown ") return errorArray.GetEnumerator End Function Using the Property Bag to Store Property Information In order to store property information for pipeline components, you need to implement the IPersistPropertyBag interface and give an implementation to the Save and Load methods. These methods pass in the representative IPropertyBag object that will be used to store the property information. The IPropertyBag is simply a structure that will hold a set of key/value pairs. The key is a string, and the value is of type Object so it can accept any type. You may ask yourself, “Why not store the object itself rather than storing the name of the schema and con- structing a New() object in the Load method?” The answer is because the Save function of the component will fail if y ou do this. When the properties are written to the ContextPropertyBag, they are actually expressed within the BTP file as XML so that they can be used for per- instance pipeline configuration. For more information on this, see the section entitled “Custom Properties and Per-Instance Pipeline Configuration” later on in the chapter. Included within the code sample are two helper functions that encapsulate reading/writing the proper- ties to the property bag. 13 The following code snippet shows how you can use the property bag CHAPTER 4 ■ PIPELINING AND COMPONENTS136 13. As y ou can see in the sample , there are two helper methods included called ReadPropertyBag and WritePropertyBag. These are generated when using the Pipeline Component Wizard, available from www.gotdotnet.com/Workspaces/Workspace.aspx?id=1d4f7d6b-7d27-4f05-a8ee-48cfcd5abf4a. We will introduce this tool in the next chapter, but we wanted to include these helper functions here, as they are quite useful when dealing with IPropertyBag operations. 6994ch04final.qxd 10/2/06 12:32 AM Page 136 to read and write custom properties from a pipeline component: '<summary> 'Loads configuration properties for the component ' </summary> '<param name="pb">Configuration property bag</param> '<param name="errlog">Error status</param> Public Overridable Sub Load(ByVal pb As _ Microsoft.BizTalk.Component.Interop.IPropertyBag, ByVal errlog As Integer) _ Implements Microsoft.BizTalk.Component.Interop.IPersistPropertyBag.Load Dim val As Object = Nothing val = Me.ReadPropertyBag(pb, "MyDocSpec") If (Not (val) Is Nothing) Then Me._MyDocSpec = New _ Microsoft.BizTalk.Component.Utilities.SchemaWithNone(CType(val, String)) End If val = Me.ReadPropertyBag(pb, "OutboundDocumentSpecification") If (Not (val) Is Nothing) Then Me._OutboundDocumentSpecification = New _ Microsoft.BizTalk.Component.Utilities.SchemaWithNone(CType(val, String)) End If val = Me.ReadPropertyBag(pb, "FileRootNode") If (Not (val) Is Nothing) Then Me._FileRootNode = val End If val = Me.ReadPropertyBag(pb, "DataElementNode") If (Not (val) Is Nothing) Then Me._DataElementNode = val End If End Sub '<summary> 'Saves the current component configuration into the property bag '<summary> '<param name="pb">Configuration property bag</param> '<param name="fClearDirty">not used</param> '<param name="fSaveAllProperties">not used</param> Public Overridable Sub Save(ByVal pb As _ Microsoft.BizTalk.Component.Interop.IPropertyBag, ByVal fClearDirty As Boolean, _ ByVal fSaveAllProperties As Boolean) Implements _ Microsoft.BizTalk.Component.Interop.IPersistPropertyBag.Save Me.WritePropertyBag(pb, "MyDocSpec", Me.MyDocSpec.SchemaName) Me.WritePropertyBag(pb, "OutDocSpec", Me.OutboundDocumentSpecification.SchemaName Me.WritePropertyBag(pb, "FileRootNode", Me.FileRootNode) CHAPTER 4 ■ PIPELINING AND COMPONENTS 137 6994ch04final.qxd 10/2/06 12:32 AM Page 137 M e.WritePropertyBag(pb, "DataElementNode", Me.DataElementNode) End Sub ' <summary> 'Reads property value from property bag '</summary> '<param name="pb">Property bag</param> '<param name="propName">Name of property</param> '<returns>Value of the property</returns> Private Function ReadPropertyBag(ByVal pb As _ Microsoft.BizTalk.Component.Interop.IPropertyBag, ByVal propName As String) As _ Object Dim val As Object = Nothing Try pb.Read(propName, val, 0) Catch e As System.ArgumentException Return val Catch e As System.Exception Throw New System.ApplicationException(e.Message) End Try Return val End Function '<summary> 'Writes property values into a property bag. '</summary> '<param name="pb">Property bag.</param> '<param name="propName">Name of property.</param> '<param name="val">Value of property.</param> Private Sub WritePropertyBag(ByVal pb As _ Microsoft.BizTalk.Component.Interop.IPropertyBag, ByVal propName As String, ByVal _ val As Object) Try pb.Write(propName, val) Catch e As System.Exception Throw New System.ApplicationException(e.Message) End Try End Sub Custom Properties and Per-Instance Pipeline Configuration As w e discussed earlier in the chapter , per-instance pipeline configuration allows you to change the values of custom properties using the BizTalk Administration Tools. The user inter- face provides you with a mechanism to set the values for pipeline properties dynamically for a receiv e location without having to cr eate a new custom pipeline for every new receive loca- tion. A few points of interest when attempting to use this feature with a custom pipeline and pipeline components are described here. CHAPTER 4 ■ PIPELINING AND COMPONENTS138 6994ch04final.qxd 10/2/06 12:32 AM Page 138 Custom pipeline component properties for per-instance pipeline configuration are actu- ally stored within the .btp file for the pipeline definition. A sample of the file follows. If you find that your custom properties are not appearing in the per-instance pipeline configuration document, you can manually add them to the XML of the .btp file and they will appear. < ?xml version="1.0" encoding="utf-16"?> <Document xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" PolicyFilePath="BTSReceivePolicy.xml" MajorVersion="1" MinorVersion="0"> <Description /> <Stages> <Stage CategoryId="9d0e4103-4cce-4536-83fa-4a5040674ad6"> <Components /> </Stage> <Stage CategoryId="9d0e4105-4cce-4536-83fa-4a5040674ad6"> <Components /> </Stage> <Stage CategoryId="9d0e410d-4cce-4536-83fa-4a5040674ad6"> <Components> <Component> <Name>ABC.BizTalk.PipelineComponents.Decoder</Name> <Properties> <Property Name="MyUnTypedProperty" /> <Property Name="MyStringProperty"> <Value xsi:type="xsd:string">My String Value</Value> </Property> </Properties> <CachedDisplayName>Decoding Component</CachedDisplayName> <CachedIsManaged>true</CachedIsManaged> </Component> </Components> </Stage> <Stage CategoryId="9d0e410e-4cce-4536-83fa-4a5040674ad6"> <Components /> </Stage> </Stages> </Document> • In the .btp file for the pipeline definition, you can set the default data of the pipeline component property by inserting a value in the property’s <Value> element. • The <Value> that you insert must be an XSD type. For example, the type must be xsd:string for a string value, or xsd:int for an integer value. Custom Disassemblers It’s important to call special attention to Disassembler components, as they are often what most dev elopers end up writing. Disassemblers were intended to allow the pipeline to exam- CHAPTER 4 ■ PIPELINING AND COMPONENTS 139 6994ch04final.qxd 10/2/06 12:32 AM Page 139 ine the incoming document and break it up into smaller, more manageable documents. The classic example of this is an envelope file. The large document is received that contains an envelope with multiple smaller documents inside it. The envelope is removed, and each of the contained documents is validated against its schema and ends up being a distinct and unique message within BizTalk. This is shown in Figure 4-14. The Disassembler component has one key interface, IDisassemblerComponent. IDisassemblerComponent has two methods, Disassemble and GetNext, which are listed in Table 4-12. What happens is the BizTalk runtime calls the Disassemble method first and passes the original message and the pipeline context. It then calls the GetNext method after the Dis- assemble method. The GetNext method returns new messages of type IBaseMessage until the component decides that all messages are created and then it returns Null. Returning Null from GetNext signals the end of the component’s execution and signals the runtime that all mes- sages have been properly created. Table 4-12. Public Methods of IDisassemblerComponent Method Description Disassemble Performs the disassembling of incoming document GetNext Gets the next message from the message set resulting from the Disassembler execution A couple of design patterns exist that you can use when creating Disassemblers. One patter n is to use the Disassemble method to pr ime any instance variables, setup, and data, and then retur n and essentially cr eate no messages . The messages will be created in the GetNext method, and new messages will be created each time the method is called. Another patter n is to cr eate all messages in the Disassemble stage, enqueue them to a queue struc- ture, and then dequeue the messages fr om the queue each time GetNext is called. E ither strategy will work; the second strategy can be more efficient especially if expensive resources need to be instantiated each time a message is cr eated. Using the second method, you only CHAPTER 4 ■ PIPELINING AND COMPONENTS140 Figure 4-14. Logical view of a Disassembler 6994ch04final.qxd 10/2/06 12:32 AM Page 140 [...]... implemented.") End Sub Public Sub Load(ByVal propertyBag As IPropertyBag, ByVal errorLog As Integer) Dim prop As Object = Nothing Dim nm As Object = Nothing Dim xp As Object = Nothing Try propertyBag.Read("Namespace", nm, 0) propertyBag.Read("PropertyName", prop, 0) propertyBag.Read("XPATH", xp, 0) Catch Finally If Not (prop Is Nothing) Then PropertyName = prop.ToString End If If Not (nm Is Nothing)... xp.ToString End If End Try End Sub Public Sub Save(ByVal propertyBag As IPropertyBag, ByVal clearDirty As Boolean_ , ByVal saveAllProperties As Boolean) Dim prop As Object = PropertyName Dim nm As Object = Namespace Dim xp As Object = XPath propertyBag.Write("PropertyName", prop) propertyBag.Write("Namespace", nm) propertyBag.Write("XPATH", xp) End Sub 151 6994ch05final.qxd 152 10/2/06 12:33 AM Page 152 CHAPTER... _InboundDocumentSpecification.DocSpecName + _ "#" + _FileRootNode message.Context.Promote("MessageType", BTSSystemPropertiesNamespace,_ messageType) message.AddPart("body", bodyPart, True) Return message End Function 143 6994ch04final.qxd 10/2/06 12:32 AM Page 144 6994ch05final.qxd 10/2/06 12:33 AM CHAPTER Page 145 5 sss Pipeline Component Best Practices and Examples C hapter 4 outlined the “advanced basics” of creating custom... Class PropPromoteComponent Implements IComponent Implements IComponentUI Implements IBaseComponent 6994ch05final.qxd 10/2/06 12:33 AM Page 149 CHAPTER 5 s PIPELINE COMPONENT BEST PRACTICES AND EXAMPLES Implements IPersistPropertyBag Private _PropertyName As String Private _Namespace As String Private _XPath As String Public Property PropertyName() As String Get Return _PropertyName End Get Set _PropertyName... ByVal fSaveAllProperties As Boolean) Implements_ Microsoft .BizTalk. Component.Interop.IPersistPropertyBag.Save End Sub ' 'Reads property value from property bag ' 'Property bag 'Name of property 6994ch05final.qxd 10/2/06 12:33 AM Page 159 CHAPTER 5 s PIPELINE COMPONENT BEST PRACTICES AND EXAMPLES 'Value of the property... Implements_ Microsoft .BizTalk. Component.Interop.IPersistPropertyBag.GetClassID classid = New System.Guid("4f1c7d50-e66f -45 1b-8e 94- 2f8d599cd013") End Sub ' 'not implemented ' Public Sub InitNew() Implements_ 163 6994ch05final.qxd 1 64 10/2/06 12:33 AM Page 1 64 CHAPTER 5 s PIPELINE COMPONENT BEST PRACTICES AND EXAMPLES Microsoft .BizTalk. Component.Interop.IPersistPropertyBag.InitNew End... Function 6994ch05final.qxd 10/2/06 12:33 AM Page 165 CHAPTER 5 s PIPELINE COMPONENT BEST PRACTICES AND EXAMPLES ' 'Writes property values into a property bag ' 'Property bag. 'Name of property. 'Value of property. Private Sub WritePropertyBag(ByVal pb As_ Microsoft .BizTalk. Component.Interop.IPropertyBag,... streambased XPath queries Each of these classes is explained in the following sections 147 6994ch05final.qxd 148 10/2/06 12:33 AM Page 148 CHAPTER 5 s PIPELINE COMPONENT BEST PRACTICES AND EXAMPLES VirtualStream Included in the BizTalk SDK under the \Program Files\Microsoft BizTalk Server 2006\ SDK\ Samples\Pipelines\ArbitraryXPathPropertyHandler directory is a class file called VirtualStream.cs This class is... property values into a property bag ' 'Property bag. 'Name of property. 'Value of property. Private Sub WritePropertyBag(ByVal pb As_ Microsoft .BizTalk. Component.Interop.IPropertyBag,_ ByVal propName As String, ByVal val As Object) Try pb.Write(propName, val) Catch e As System.Exception Throw New System.ApplicationException(e.Message)... "Description" End Get End Property Public ReadOnly Property Name() As String Get Return "Property Promote" End Get End Property 6994ch05final.qxd 10/2/06 12:33 AM Page 151 CHAPTER 5 s PIPELINE COMPONENT BEST PRACTICES AND EXAMPLES Public ReadOnly Property Version() As String Get Return "1" End Get End Property Public Sub GetClassID(ByRef classID As Guid) Dim g As Guid = New Guid("FE537918-327B-4a0c-9ED7-E1B993B7897E") . /> <Stages> <Stage CategoryId="9d0e4103-4cce -45 36-83fa-4a5 040 674ad6"> <Components /> </Stage> <Stage CategoryId="9d0e4105-4cce -45 36-83fa-4a5 040 674ad6"> <Components. CategoryId="9d0e410d-4cce -45 36-83fa-4a5 040 674ad6"> <Components> <Component> <Name>ABC .BizTalk. PipelineComponents.Decoder</Name> <Properties> <Property Name="MyUnTypedProperty". PIPELINING AND COMPONENTS 143 6994ch04final.qxd 10/2/06 12:32 AM Page 143 6994ch04final.qxd 10/2/06 12:32 AM Page 144 Pipeline Component Best Practices and Examples Chapter 4 outlined the “advanced

Ngày đăng: 14/08/2014, 11:21

TỪ KHÓA LIÊN QUAN