Hi,
We now have three interface contracts on a RuntimeEndpoint or
RuntimeEndpointReference.
Let's use an example to illustrate this:
There are two components: Payment and CreditCardPayment. Payment has a
reference to CreditCardPayment. Both are implemented in Java. We decide to
use binding.ws to connect these two components. A WSDL portType is created
to define the interface. To facilitate the java implementations, we run
"wsimport" to generate the JAX-WS interface (say scatours.CreditCardPayment)
and use it in the Payment and CreditCardPayment implementations.
The Payment implementation class would have:
@Reference
protected scatours.CreditCardPayment creditCardPayment
In the composite file, we can configure the Payment component reference with
a interface.wsdl:
<component name="Payment" ...>
<reference name="creditCardPayment">
<interface.wsdl interface="...">
<binding.ws .../>
</reference>
</component>
Now we can have up to three interface contracts for the "creditCardPayment"
reference.
1) componentType.reference.interfaceContract: This is the interface contract
that the business logic uses to call the service provider. In our example,
it's introspected from @Reference and the interface is a Java interface:
scatours.CreditCardPayment.
2) component.reference.interfaceContract: This is the interface contract
that is specified using the component/reference/interface.??? element. If no
interface.??? is not present, then it inherits from the componentType which
is 1).
3) component.reference.binding. interfaceContract: This is the interface
contract that binding layer expects. For Web Service binding, it is the WDSL
that Web Service is published. The construction of this interface contract
is binding-specific. For binding.ws, we use the following order:
* Check if the binding.ws element has wsdlElement attribute that points
to a WSDL
* Check if the component/reference/interface.wsdl is present
* Generate the WSDL from the component/componentType reference interface
(java2wsdl in this example).
Going back to the RuntimeEndpointReference SPI, we now have three methods to
represent 1, 2 and 3:
getReferenceInterfaceContract() --> 1 (For reference promotions, it uses the
componentType.reference.interfaceContract of the atomic component)
getInterfaceContract() --> 2
getBindingInterfaceContract --> 3
From data transformation perspective, the source contract is 1 and the
target contract is 3. Interface contract 2 is mostly for the wiring
compatibility checking.
The RuntimeEndpoint has similar methods:
getServiceInterfaceContract() --> 1 (For service promotions, it uses the
componentType.service.interfaceContract of the atomic component)
getInterfaceContract() --> 2
getBindingInterfaceContract --> 3
Thanks,
Raymond
---
Raymond Feng
Apache Tuscany PMC Member: http://tuscany.apache.org
Co-author of Tuscany In Action (A book on Tuscany SCA):
http://tuscanyinaction.com/