Chapter 4. Application Basics

This section introduces the basic building blocks of a SwitchYard application starting from an empty application and building up to the complete application as shown below:
Application Basics

Figure 4.1. Composite

Each topic includes a visual representation of the switchyard.xml configuration file as designed in the SwitchYard graphical editor and the corresponding source XML which is automatically generated from the visual design.

4.1. Composite

A composite is displayed as a light blue rectangle and represents the boundary between what is inside your application and what is outside your application. A SwitchYard application consists of exactly one composite that has a name and a targetNamespace. The targetNamespace value is important as it allows names defined locally in the application (for example, service names) to be qualified and unique within a SwitchYard runtime.
Composite

Figure 4.2. Composite

Example 4.1. Sample Corresponding XML

<sca:composite name="example" targetNamespace="urn:example:switchyard:1.0">
</sca:composite>

4.2. Component

A component is a modular container for application logic and consists of the following:
  • 0 or 1 component service definitions
  • 0 to many component reference definitions
  • 1 implementation
Services and references allow a component to interact with other components, while the implementation provides the actual logic for providing or consuming services.
Component

Figure 4.3. Component

Example 4.2. Sample Corresponding XML

<sca:component name="Routing">
</sca:component>

4.3. Implementation

An implementation acts as the brain of a service component and it is how implement your application logic. The following implementation options are available:
  • Bean : allows a CDI Bean to consume or provide services using annotations
  • Camel : EIP-style routing and service composition using the XML or Java DSL in Apache Camel
  • BPMN 2 : service orchestration and human task integration expressed as BPMN 2 and executed using jBPM
  • BPEL Process : web service orchestration using the OASIS Business Process Execution Language
  • Rules : decision services based on Drools
Implementations are private to a component, which means external consumers and providers are not aware of the details of a component's implementation (implementation-hiding). All interactions with other components within an application and with external services are handled through component services and references.
Implementation

Figure 4.4. Implementation

Example 4.3. Sample Corresponding XML

<sca:component name="Routing">
   <camel:implementation.camel>
      <camel:xml path="RoutingService.xml"/>
   </camel:implementation.camel>
</sca:component>

4.4. Component Service

A component service is used to expose the functionality of an implementation as a service. All component services have a contract, which can be a Java interface, WSDL portType definition, or a set of named data types (interface.esb). Component services are private to an application, which means a component service can only be invoked by other components in the same application. In order to expose a component service to consumers external to the application, a component service can be promoted to a composite service. A component service can be promoted multiple times to create different composite services.
Component Service

Figure 4.5. Component Service

Example 4.4. Sample Corresponding XML

<sca:component name="Routing">
   <camel:implementation.camel>
      <camel:xml path="route.xml"/>
   </camel:implementation.camel>
   <sca:service name="ServiceA">
      <sca:interface.java interface="org.example.ServiceA"/>
   </sca:service>
</sca:component>

4.5. Composite Service

A composite service represents an application service which is visible to other applications. A composite service can only be realized by promoting a component service within the application. The name and the interface of the composite service can be different from the component service. If the interface, or contract, of the composite service is different from the component service, be aware that a transformation may be required to map between the types defined in each interface. In our example application, the component service has a Java interface while the composite service has a WSDL interface. This means we must declare a transformer which maps between XML and Java to resolve the data type mismatch.
Composite Service

Figure 4.6. Composite Service

Example 4.5. Sample Corresponding XML

<sca:composite name="example" targetNamespace="urn:example:switchyard:1.0">
   <sca:service name="ServiceA" promote="Routing/ServiceA">
      <sca:interface.wsdl interface="ServiceA.wsdl#wsdl.porttype(ServiceAPortType)"/>
   </sca:service>
</sca:composite>

4.6. Service Binding

A service binding is used to define an access method for a composite service. Composite services can have multiple bindings, which allows a single service to be accessed in different ways. In most cases, a service binding represents a protocol or transport adapter (for example, SOAP, JMS, and REST). An important exception to this rule is the SCA binding, which allows services across applications in the same runtime to be wired together in memory. Regardless of the underlying binding details, a binding must always be used to facilitate inter-application communication in SwitchYard.
Service Binding

Figure 4.7. Service Binding

Example 4.6. Sample Corresponding XML

<sca:composite name="example" targetNamespace="urn:example:switchyard:1.0">
   <sca:service name="ServiceA" promote="Routing/ServiceA">
      <sca:interface.wsdl interface="ServiceA.wsdl#wsdl.porttype(ServiceAPortType)"/>
      <soap:binding.soap>
        <soap:wsdl>ServiceA.wsdl</soap:wsdl>
      </soap:binding.soap>
   </sca:service>
</sca:composite>

4.7. Component Reference

A component reference allows a component to consume other services. A component reference can be wired to a service offered by another component in the same application or it can be wired to services outside the application with a composite reference. Similar to component services, all component references have a contract which allows a component to invoke services without knowing implementation or binding details. The picture below shows an example of wiring a reference on the Routing component to a service offered by the Bean component.
Component Reference

Figure 4.8. Component Reference

Example 4.7. Sample Corresponding XML

<sca:component name="Routing">
   <camel:implementation.camel>
      <camel:xml path="route.xml"/>
   </camel:implementation.camel>
   <sca:service name="ServiceA">
      <sca:interface.java interface="org.example.ServiceA"/>
   </sca:service>
   <sca:reference name="ServiceC">
      <sca:interface.java interface="org.example.ServiceC"/>
   </sca:reference>
</sca:component>

4.8. Composite Reference

A composite reference allows a component reference to be wired to a service outside the application. Similar to composite services, bindings are used with composite references to specify the communication method for invoking the external service.
Composite Reference

Figure 4.9. Composite Reference

Example 4.8. Sample Corresponding XML

<sca:composite name="example" targetNamespace="urn:example:switchyard:1.0">
   <sca:reference name="ReferenceB" multiplicity="0..1" promote="Routing/ServiceB">
      <sca:interface.java interface="org.example.ServiceB"/>
   </sca:reference>
</sca:composite>

4.9. Reference Bindings

A reference binding is used to define an access method for an external service with a composite reference. Unlike service bindings, there can only be one binding for each composite reference. The set of bindings available for references is identical to the set of bindings available for services, although the configuration values for a given binding may be different depending on whether it is used as a service binding or a reference binding.
Reference Bindings

Figure 4.10. Reference Bindings

Example 4.9. Sample Corresponding XML

<sca:composite name="example" targetNamespace="urn:example:switchyard:1.0">
   <sca:reference name="ReferenceB" multiplicity="0..1" promote="Routing/ServiceB">
      <sca:interface.java interface="org.example.ServiceB"/>
         <jms:binding.jms>
         <jms:queue>MyQueue</jms:queue>
         <jms:connectionFactory>#ConnectionFactory</jms:connectionFactory>
      </jms:binding.jms>
   </sca:reference>
</sca:composite>

Note

Although endpoint configuration can be static or dynamic (depending on the component), the endpoint reference itself is static. An example of a dynamic endpoint would be a file component configuration that maps properties (like file name) from the incoming binding and carries it to the outgoing reference. In this manner, the output file can be made to share the same name (in a different directory) as the incoming file that triggered the service invocation. The user did not have to specify a filename on the outgoing reference configuration - it was 'dynamic' and specified at runtime. Dynamic addressing for HTTP-based endpoints (such as SOAP, RESTEasy, and HTTP) is not currently available.