package com.example.switchyard.example; public interface ExampleService { public String sayHello(String name); }
This tutorial takes you through the steps required to create, implement, test and deploy a SwitchYard application using the Eclipse tooling. The application created provides a greeter service, implemented as a Java bean and accessible via a SOAP HTTP gateway. This tutorial illustrates how to perform the following tasks:
Create a SwitchYard project
Create a Java service interface
Create a bean component implementation
Create and execute a unit test for the service
Create a WSDL service interface
Add a SOAP gateway for accessing the service
Create a transformer
Create and execute a unit test for the transformer
Create and execute a unit test for the SOAP gateway
Deploy the application to a server
Test the deployed application
Refer to Application Basics in the User Guide for an overview of the basic building blocks of a SwitchYard application.
Before beginning you will need the SwitchYard tooling and a SwitchYard runtime.
Install the SwitchYard tooling for Eclipse. Instructions can be found here.
Install the SwitchYard runtime. Instructions can be found here.
This step describes how to create a server definition for your SwitchYard runtime. You will deploy your project to this server in a later step. The server references a runtime definition which will be used when creating your SwitchYard project.
Open the Servers view in Eclipse.
Create a new server (right-click, New→Server).
Select JBoss Enterprise Application Platform 6.1 from the JBoss Enterprise Middleware category. In this example, the Name field has been changed from its default value.
Press Next.
Specify the details for your server's runtime. Specify the path to your SwitchYard runtime installation in the Home Directory field.
Press Finish.
This step describes how to create a project for the application.
From the new menu, select SwitchYard Project. (See SwitchYard Projects for more details.)
The first page in the wizard is used for specifying the project name and location.
The next page is used for specifying various project details, including which SwitchYard components are required by the project. In this example, the default package has been modified and the Bean and SOAP components have been selected.
Notice the Target Runtime field references the runtime associated with the server created in the previous step. Also notice the Library Version corresponds with the SwitchYard version in the runtime.
Upon completion, a new project is created and the SwitchYard configuration will be open in the editor.
The Palette view may not be immediately visible. If it is missing from your workbench, it can be displayed using the Window→Show View→Other... menu
This step describes how to create a bean component using the SwitchYard editor. Upon completion of this step, you will have a component, providing a service (described by a Java interface), implemented by a bean. The following resources will be created during this step:
ExampleService.java describing the Java interface for the component's service.
ExampleServiceBean.java providing the implementation for the component.
component, component service and implementation elements in the SwitchYard configuration (i.e. the switchyard.xml file)
Refer to the Component, Implementation, and Component Service sections of Application Basics in the User Guide for general details.
Refer to the Bean topic in the Developer Guide for details specific to bean components.
In the SwitchYard editor, drag the Bean tool from the Components section of the palette onto the canvas. This opens a wizard prompting for details about the component.
Create a new interface by clicking the Interface link. This opens the standard Eclipse New Interface wizard. Specify a name for the interface (e.g. ExampleService), any other details and press Finish.
The service name field is initialized based on the type name used for the interface (e.g. ExampleService) and the class name field is initialized based on the service name (e.g. ExampleServiceBean). Look over the fields and press Finish.
A new component shape should be added to the canvas.
Save the changes to the switchyard.xml file.
If the project contains a number of XML validation errors, make sure Honour all XML schema locations is disabled in workbench preferences (under XML→XML Files→Validation).
This step describes how to flesh out the interface for the service. The Java interface created in the previous step contained no methods, so you will add them here. You will have a complete interface describing the service at the end of this step.
In the SwitchYard editor, double-click the service icon on the component (the green arrow on the left side of the component). This opens the file describing the interface (ExampleService.java).
Add a method to the interface, for example:
package com.example.switchyard.example; public interface ExampleService { public String sayHello(String name); }
In the previous step, you created the interface while we were creating the component. You could have created the interface first, using the Browse... button in the New Bean Service wizard to select it. The resulting bean class would have been created with stubs for each method on the interface.
This step implements the service logic in the bean class. There are compiler errors in the bean class because it does not implement the method you added to the interface in the previous step. The errors are resolved by creating the missing methods in the bean class. The project should have no errors at the end of this step.
In the SwitchYard editor, double-click the component (ExampleServiceBean) in the diagram. This opens the file used to implement the component (ExampleServiceBean.java).
The file contains errors, since it does not implement required methods.
Add an implementation for the missing method. (Using quick-fix, click the error icon and select, Add unimplemented methods.)
Update the implementation of the sayHello() method so it matches the following:
package com.example.switchyard.example; import org.switchyard.component.bean.Service; @Service(ExampleService.class) public class ExampleServiceBean implements ExampleService { @Override public String sayHello(String name) { return "Hello, " + name; } }
This step describes how to create a unit test to verify the implementation of the service. At the end of this step, you will have a unit test which sends a message to the service and verifies its output. You will also execute the test using the native Eclipse JUnit support. The following resources will be created during this step:
ExampleServiceTest.java
Refer to Unit Testing in the Tooling section for more details on creating unit tests with the tooling.
Refer to Testing in the Developer Guide for more details on application testing.
In the SwitchYard editor, right-click the service icon on the component (the green arrow on the left side of the component) and select New Service Test Class. This will open a wizard, which should be defaulted appropriately. Look the fields over and press Finish.
You can also access New Service Test Class from the context pad that appears when hovering over the component service and from the File→New menu.
Modify the testSayHello() method to properly exercise the service. Initialize the message variable to "Bob" and update the Assert statement to verify the return value from the service is, "Hello, Bob"
package com.example.switchyard.example; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.switchyard.component.test.mixins.cdi.CDIMixIn; import org.switchyard.test.Invoker; import org.switchyard.test.ServiceOperation; import org.switchyard.test.SwitchYardRunner; import org.switchyard.test.SwitchYardTestCaseConfig; import org.switchyard.test.SwitchYardTestKit; @RunWith(SwitchYardRunner.class) @SwitchYardTestCaseConfig(config = SwitchYardTestCaseConfig.SWITCHYARD_XML, mixins = { CDIMixIn.class }) public class ExampleServiceTest { private SwitchYardTestKit testKit; private CDIMixIn cdiMixIn; @ServiceOperation("ExampleService") private Invoker service; @Test public void testSayHello() throws Exception { // TODO Auto-generated method stub // initialize your test message String message = "Bob"; String result = service.operation("sayHello").sendInOut(message) .getContent(String.class); // validate the results Assert.assertTrue("Hello, Bob".equals(result)); } }
Run the tests by selecting Run As→JUnit Test.
This step describes how to promote a component service to a composite service so the service can be accessed by external clients. The promoted composite service will be described using a WSDL interface. You will create the WSDL file using the Java-to-WSDL capabilities in the tooling. Because the composite service exposes a different interface than the component service, you will need to create a couple of transformers to convert the between the different types (i.e. between the Java and WSDL types). The following resources will be created during this step:
ExampleService.wsdl describing the composite service interface
ExampleServiceTransformers.java providing transformation logic for converting between ExampleService.java and ExampleService.wsdl
composite service element in the SwitchYard configuration
Refer to the Composite Service section of Application Basics and Transformation in the User Guide for general details.
Refer to Java Transformer in the Developer Guide for specific details.
In the SwitchYard editor, right-click the service icon on the component and select Promote Component Service. This opens a wizard allowing you to specify the interface that will be exposed by the promoted service. By default, the interface specified matches the interface used to describe the component service.
Change the interface type from Java to WSDL. This blanks out the interface and name fields.
Press the Interface link to create a new WSDL file. This opens the Java2WSDL wizard.
The first page of the Java2WSDL wizard is used for specifying the name and location for the WSDL file. The default values should be appropriate. Look them over and press Next.
The next page is used for specifying details about the generated WSDL. The default values should be appropriate Look the values over and press Finish.
The WSDL file is created and you are back on the Promote Component Service wizard. The fields have been updated with details from the new WSDL file. Notice that the Create required transformers button is checked and press Next.
The next page is the New Transformers page allowing you to create the required transformers. Notice the two transformer type pairs checked in the table correspond to the input and output types declared on the two interfaces. Ensure both pairs are checked and Java Transformer is selected as the Transformer Type and press Next.
The next page collects information for a new Java class that will be used to implement the transformers. Specify ExampleServiceTransformers for the name and leave org.w3c.dom.Element selected as the Java type to be used to represent XML/ESB types in the transformer class. Press Finish.
The For XML/ESB types use field allows you to specify the Java type used to pass non-Java types into the transformer. The list contains commonly used types, but you can specify whatever type you like. The caveat is that SwitchYard must be able to convert the raw message content to the specified type.
A new composite service promoting the component service should have been added to the SwitchYard configuration. Save the editor.
Select the main shape in the SwitchYard editor and review the contents of the Transforms tab in the Properties view. The newly added transformers should be listed.
This step describes how to add a unit test to verify the transformer logic.
Open ExampleServiceTest.java and add the following method, which will test the transformers:
@Test public void testSayHelloTransform() throws Exception { final QName inputType = QName .valueOf("{urn:com.example.switchyard:switchyard-example:1.0}sayHello"); final QName outputType = QName .valueOf("{urn:com.example.switchyard:switchyard-example:1.0}sayHelloResponse"); // initialize your test message Object message = "<sayHello xmlns=\"urn:com.example.switchyard:switchyard-example:1.0\"><string>Bob</string></sayHello>"; String result = service.operation("sayHello").inputType(inputType) .expectedOutputType(outputType).sendInOut(message) .getContent(String.class); // validate the results String control = "<sayHelloResponse xmlns=\"urn:com.example.switchyard:switchyard-example:1.0\"><string>Hello, Bob</string></sayHelloResponse>"; Assert.assertTrue("Unexpected result: " + result, XMLUnit.compareXML(control, result).identical()); }
Notice the use of inputType() and expectedOutputType() in the operation invocation. These identify the message types specified through the interfaces in the switchyard.xml file.
Run the test and verify that it fails.
The step describes how to implement transformer class created earlier. At the end of this step, you will run the unit tests to verify they pass.
Open ExampleServiceTransformers.java and implement the transformStringToSayHelloResponse() as follows:
@Transformer(to = "{urn:com.example.switchyard:switchyard-example:1.0}sayHelloResponse") public String transformStringToSayHelloResponse(String from) { // TODO: properly escape the input string return "<sayHelloResponse xmlns=\"urn:com.example.switchyard:switchyard-example:1.0\"><string>" + from + "</string></sayHelloResponse>"; }
And implement transformSayHelloToString() as follows:
@Transformer(from = "{urn:com.example.switchyard:switchyard-example:1.0}sayHello") public String transformSayHelloToString(Element from) { return from.getTextContent(); }
Notice the return type of transformStringToSayHelloResponse() was changed from Element to String. The annotation specifies the to type as sayHelloResponse, but the data is returned as a String. SwitchYard provides low-level transformers for converting XML to/from a variety of Java accessible types (e.g. String, Element, Document, byte[]).
Run the unit tests to verify they pass.
This step describes how to add a SOAP gateway binding to the composite service. This will allow external clients to access your service using SOAP HTTP.
Refer to the Service Binding section of Application Basics in the User Guide for general details.
Refer to the SOAP section in the Developer Guide for specific details.
Add a SOAP endpoint to the service by dragging the SOAP tool under the Bindings section of the tool palette onto the new service. This will open the new binding wizard. Specify switchyard-example for the Context Path and press Finish.
Save the changes made to the switchyard.xml file.
Your application is configured with a single service, implemented using a Java bean, and exposed to clients as a SOAP HTTP service. You also have unit tests for the service and transformation logic. The view of the final state of the project and configuration:
This step describes how to deploy your project to a server using Eclipse. You will use the server you configured in one of the previous steps.
Open the Servers view.
Make sure the server is started (right-click, Start).
Right-click the project, Run As→Run On Server. Select the server and press Finish.
You can view the WSDL associated with your service by appending ?wsdl to the URL for your service, e.g. http://localhost:8080/switchyard-example/ExampleService?wsdl.
If you see a ClassNotFoundException related to SwtichYardTestKit in the console log, your test resources may be included in the deployment. To correct this, right-click the project and select Maven→Update Project... You can verify the test resources have been removed from the deployment assembly by looking at the Deployment Assembly page in the Properties for the project.
This step describes how to test the service using a SOAP HTTP clients. You will use the web services tester that ships with Eclipse, but you could use the web services test/debug tool you are most familiar with.
Right-click the WSDL file (ExampleService.wsdl) and select Web Services→Test with Web Services Explorer. Exercise the service using the tester.
Right-click the server in the Servers view and select Show In→Web Management Console. Refer to the SwitchYard management console documentation for details.