Figure 9.5 illustrates a composite, which is an assembled, logical unit that solves a business problem. The definition of the composite is in a single composite file in most cases but can be distributed across a set of such files.
Figure 9.5: Composite
A composite can be invoked as a peer, whether from an independent composite in the same SCA system or from outside the SCA system altogether; or (as described later) a composite can be included as an implementation in a higher-level composite. In either case, a company benefits from having an inventory of composites that were previously tested and deployed.
Listing 9.6 shows an outline of a composite definition.
Listing 9.6: Composite definition outline
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" targetNamespace="http://www.ibm.com/HighlightInsurance" name="myComposite" requires="confidentiality" local="false"> <service> </service> <property> </property> <reference> </reference> <wire> </wire> <component> <implementation/> <service/> <property/> <reference/> </component> <component> <implementation/> <service/> <property/> <reference/> </component> </composite>
Here are two of the attributes in the composite element:
targetNameSpace specifies the namespace for names (such as the composite and component names) being assigned in the composite definition.
local indicates whether all components in the composite definition are required to run in the same operating-system process. The default value is false, which means that the composite can include components whose implementations are written in different languages and may even run on different machines.
The excerpt shown in Listing 9.7 includes a composite service.
Listing 9.7: Excerpt showing a composite service
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" targetNamespace="http://www.ibm.com/HighlightInsurance" name="QuoteComposite" requires="confidentiality"> <service name="ProcessQuote" promote="ProcessQuoteComponent/ProcessQuote"> <binding.ws port="http://www.highlight.com/ProcessQuote# wsdl.endpoint(ProcessQuote/ProcessQuoteSOAP)" /> </service> . . <component name="ProcessQuoteComponent"> . . <service name="ProcessQuote"> <interface.partnerLinkType type="ProcessQuotePLT" serviceRole="ProcessQuoteRole" /> </service> . . </component> </composite>
A composite service such as ProcessQuote makes a component service (also called ProcessQuote in this case) available to a requester. We say that the composite service promotes the component service. Here's the meaning:
The SCA runtime uses the endpoint details in the composite service to oversee the connection. If the composite service lacks a binding element, the SCA runtime takes the endpoint details from the component service or (if necessary) from the component type. In most cases (as in the example), endpoint details are only in the composite service.
Similarly, the SCA runtime reviews the binding element (among others) to determine the required interaction policies such as confidentiality. Again, the definitions in the composite service take precedence, but details in the component service and component type may be used.
Last, the SCA runtime uses the interface details in the composite service, if those details are present there. The hierarchy of component service and component type applies here as well.
You can use multiple composite services to promote the same component service - for example, to present the same set of operations with a different quality of service.
When you define a composite service, you must identify the promoted service by giving a value to the promote attribute. To set the value of the promote attribute, specify the component name followed by a virgule (/) and the component-service name, as in the following example value:
ProcessQuoteService/ProcessQuoteComponent
If the component includes only one service, you can specify the component name alone.
The excerpt shown in Listing 9.8 includes a composite property.
Listing 9.8: Composite property
<composite name="QuoteComposite"> <property name="theDiscount" type="xsd:string" many="true" mustSupply="false"> Auto Club </property> <component name="policyQuote"> . . <property name=availableDiscount source="$theDiscount"/> . . </component> </composite>
In this case, a composite property (theDiscount) sets the property of a component inside the composite. The source attribute of the component property (in this case, the attribute in property availableDiscount) indicates that the component-property value comes from a composite property.
Here are some of the attributes in the composite-level property element:
type (or element) specifies the XSD type (or element).
many indicates whether a list of values is acceptable.
mustSupply indicates whether an assembler must supply a value for this property when embedding the composite in a higher-level composite. We say more about this issue later. The default value for the mustSupply attribute is false, which is appropriate if the composite is invoked directly rather than as an implementation.
A set of same-named composite properties is possible, as shown in Listing 9.9.
Listing 9.9: Same-named composite properties
<composite name="QuoteComposite"> <property name="theDiscount" type="xsd:string" many="true"> <value>Auto Club</value> <value>Employee</value> </property> <component name="policyQuote"> . . <property name=availableDiscount source="$theDiscount"/> . . </component> </composite>
For details on setting values for properties, see the OSOA document SCA Assembly Model Specification.
The excerpt shown in Listing 9.10 includes a composite reference.
Listing 9.10: Composite reference
<composite name="QuoteComposite"> . . . <reference name="MainframeQuoteMgr" multiplicity="1..n" promote= "ConvertQuoteComponent/ProcessQuoteReference"> <binding.ws port="http://www.highlight.com/QuoteManagement# wsdl.endpoint(QuoteManagement/QuoteManSOAP)" /> </reference> <component name="ConvertQuoteComponent"> . . <reference name="ProcessQuoteReference" target="ProcessQuoteComponent/ProcessQuote" /> </component> <component name="ProcessQuoteComponent"> . . <service name="ProcessQuote"> <interface.partnerLinkType type="ProcessQuotePLT" serviceRole="ProcessQuoteRole" /> </service> </component> </composite>
A composite reference provides access to the logic that resides in other composites or in code that is external to an SCA system. We say that the composite reference promotes a component reference. Here's the meaning:
The SCA runtime takes the endpoint details in the composite reference and provides them to the component implementation. If the composite reference lacks a binding element, the SCA runtime takes the endpoint details from the component reference or (if necessary) from the component type. In most cases (as in the example), endpoint details are only in the composite reference.
Similarly, the SCA runtime reviews the binding element (among others) to guide the runtime use of interaction policies such as confidentiality. Again, the definitions in the composite reference take precedence, but details in the component reference and component type may be used.
Interface and multiplicity details in the composite reference are used for validation, if those details are present there. The hierarchy of component reference and component type applies here as well.
In the current example, the composite reference MainframeQuoteMgr promotes the component reference ProcessQuoteReference. The example also shows that for a multi-valued reference, the component can access not only logic that is outside the composite but also logic in another component. In this case, reference ProcessQuoteReference also refers to the only service in ProcessQuoteComponent.
When you define a composite reference, you must identify the promoted reference by giving a value to the promote attribute. To set the value of the promote attribute, specify the component name followed by a virgule and the component-reference name, as in the following example value:
ConvertQuoteComponent/ProcessQuoteReference
If the component includes only one reference, you can specify the component name alone.
Each wire provides the detail needed to connect a component reference to a component service within a composite. (Figure 9.2 illustrates wires by lines.) The wire is not itself a binding, which is provided by the composite service or reference. The default binding is the SCA binding, as described earlier.
You can set a wire by setting the target attribute of the component reference, as shown in Listing 9.11.
Listing 9.11: Setting a wire
<composite name="QuoteComposite"> . . . <component name="ConvertQuoteComponent"> . . <reference name="ProcessQuoteReference" target="ProcessQuoteComponent/ProcessQuote" /> </component> <component name="ProcessQuoteComponent"> . . <service name="ProcessQuote"> <interface.partnerLinkType type="ProcessQuotePLT" serviceRole="ProcessQuoteRole" /> </service> </component> </composite>
An alternative technique is most appropriate when an SCA assembler wants to isolate the wire declarations into a separate file for separate maintenance. Let's leave the multiple-file issue for later and show the wiring syntax, which involves a wire element (Listing 9.12). The source attribute of that element identifies a component reference, and the target attribute identifies a component service.
Listing 9.12: Alternative technique for setting a wire
<composite> . . <component name="ConvertQuoteComponent"> . . <reference name="ProcessQuoteReference"/> </component> <component name="ProcessQuoteComponent"> . . <service name="ProcessQuote"> <interface.partnerLinkType type="ProcessQuotePLT" serviceRole="ProcessQuoteRole" /> </service> </component> <wire source="ConvertQuoteComponent/ProcessQuoteReference" target="ProcessQuoteComponent/ProcessQuote" /> </composite>
The syntax for specifying a source or target is equivalent to a syntax described earlier:
For a source, specify the component name followed by a virgule and the component-reference name, as in the example value ConvertQuoteComponent/ProcessQuoteReference. If the component includes only one reference, you can specify the component name alone.
For a target, specify the component name followed by a virgule and the component-service name, as in the example value ProcessQuoteComponent/ProcessQuote. If the component includes only one service, you can specify the component name alone.
Instead of setting a wire explicitly (by either of the two techniques described earlier), you can request the SCA runtime to wire component references to component services automatically. This SCA capability, called autowire, is available only for component references that otherwise have no target. Specifically, the component reference must lack a target attribute and must not be promoted by any composite reference.
In Listing 9.13, the autowire attribute in the component element causes the SCA runtime to wire the reference ProcessQuoteReference to the service ProcessQuote.
Listing 9.13: Autowire example
<composite> . . <component name="ConvertQuoteComponent" autowire="true"> . . <reference name="ProcessQuoteReference"/> </component> <component name="ProcessQuoteComponent"> . . <service name="ProcessQuote"> . . </service> </component> </composite>
When the SCA autowire capability is in effect, the SCA runtime creates a missing wire by judging the compatibility of the component reference in relation to each of the available component services. The most important compatibility rules concern the interface that was specified for the component reference and for each component service. The SCA runtime also considers policy and multiplicity characteristics.
To enable the autowire capability, add the autowire attribute to any of three kinds of elements - composite, component, or component reference - and set that attribute to true. (The default is false.) The setting in a component reference is determined by the attribute value in the reference element or (if no setting is there) by the attribute value in the nearest enclosing component or composite element.