...
We continue from part 4 where we have the routing in place. However as you might have noticed that we aren't quiet there yet with a nice solution.
These issues are still there as we:
- is creating and starting Camel manually
- is starting the routing by manually sending a message to direct:start
Of course for both issues there is a more convienient solution with Camel. But as this tutorial is very much about showing how things is done manually and also peeks how Camel does this internally for you. So let's get rocking
, we are still coding to much. In this part we will look into to address these two concerns:
- Staring Camel automatically
- Using CXF in routing
Starting Camel automatically
...
Code Block | ||||
---|---|---|---|---|
| ||||
<camelContext id="camel" xmlns="http://activemq.apache.org/camel/schema/spring">
<package>org.apache.camel.example.reportincident</package>
</camelContext>
|
Using CXF directly
Now we have seen how you can leverage Spring to start Camel, in fact it handles the lifecycle of Camel, so you can say Camel is embedded with Spring in your application.
From the very start of this tutorial we have used CXF as the webservice framework and we haven't integrated it directly with Camel as it can do out-of-the-box. Camel ships with a camel-cxf component for integrating CXF directly within Camel routing. In our tutorial we are exposing a webservice so we want continue to do this. Before we continue let's recap at what the webservice implementation we have from part 4
Code Block | ||||
---|---|---|---|---|
| ||||
/**
* The webservice we have implemented.
*/
public class ReportIncidentEndpointImpl implements ReportIncidentEndpoint {
private CamelContext context;
public ReportIncidentEndpointImpl() throws Exception {
// create the context
context = new DefaultCamelContext();
// append the routes to the context
context.addRoutes(new ReportIncidentRoutes());
// at the end start the camel context
context.start();
}
public OutputReportIncident reportIncident(InputReportIncident parameters) {
// create the producer template to use for sending messages
ProducerTemplate producer = context.createProducerTemplate();
// send the body and the filename defined with the special header key
Object mailBody = producer.sendBody("direct:start", parameters);
System.out.println("Body:" + mailBody);
// return an OK reply
OutputReportIncident out = new OutputReportIncident();
out.setCode("OK");
return out;
}
}
|
We have already seen how we can get Spring starting Camel so the constructor method can be removed. What next is that the CamelContext needed in this code should be the one from our camel-context.xml file. So we change the code to use a plain setter injection (we can use Spring annotations and whatelse but we keep it simple with a setter):
Code Block | ||||
---|---|---|---|---|
| ||||
/**
* The webservice we have implemented.
*/
public class ReportIncidentEndpointImpl implements ReportIncidentEndpoint {
private CamelContext context;
public void setCamelContext(CamelContext context) {
this.context = context;
}
public OutputReportIncident reportIncident(InputReportIncident parameters) {
// create the producer template to use for sending messages
ProducerTemplate producer = context.createProducerTemplate();
// send the body and the filename defined with the special header key
Object mailBody = producer.sendBody("direct:start", parameters);
System.out.println("Body:" + mailBody);
// return an OK reply
OutputReportIncident out = new OutputReportIncident();
out.setCode("OK");
return out;
}
}
|
And then we need to instruct Spring to set this property. Turning back to cxf-config.xml from part 4 we can add a reference to our camel context
Code Block | ||||
---|---|---|---|---|
| ||||
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
<!-- implementation of the webservice, and we refer to our camel context with the id = camel from camel-context.xml -->
<bean id="reportIncidentEndpoint" class="org.apache.camel.example.reportincident.ReportIncidentEndpointImpl">
<property name="context" ref="camel"/>
</bean>
<!-- export the webservice using jaxws -->
<jaxws:endpoint id="reportIncident"
implementor="#reportIncidentEndpoint"
address="/incident"
wsdlLocation="/WEB-INF/wsdl/report_incident.xml"
endpointName="s:ReportIncidentPort"
serviceName="s:ReportIncidentService"
xmlns:s="http://reportincident.example.camel.apache.org"/>
</beans>
So now we have two spring XML files
- cxf-config.xml
- camel-config.xml
And since cxf-config.xml is dependent on camel-config.xml we need to have correct ordering in our web.xml where we have defined the XML files to load by Spring. So we set the camel-config.xml before the cxf-config.xml so Spring have created the SpringCamelContext and registered it in its registry with the id = camel.
{code:xml}
<!-- location of spring xml files -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:camel-config.xml</param-value>
<param-value>classpath:cxf-config.xml</param-value>
</context-param>
|