Integracja usług sieciowych z użyciem Apache Camel – praktyczny przykład – część 3

Integracja usług sieciowych z użyciem Apache Camel – praktyczny przykład – część 3

Zanim zaczniesz czytać ten wpis koniecznie zobacz pierwszą i drugą część:

W tej części zajmiemy się modułem/komponentem WireTap.

W pliku \src\main\webapp\WEB-INF\camel-context.xml definiujemy beana:

<bean id="logAudit" class="com.sample.processor.AuditLog" />

Klasa AuditLog:

public class AuditLog implements Processor {
	private static final Logger LOGGER = Logger
			.getLogger(AuditLog.class);
 
	@Override
	public void process(Exchange exchange) throws Exception {
		LOGGER.debug("AuditLog::process()::enters");
		CxfPayload<SoapHeader> requestPayload = exchange.getIn().getBody(CxfPayload.class);
		LOGGER.debug("AuditLog::process()::exits");
	}
}

oraz definiujemy wpis:

<camel:wireTap uri="direct:logInfo"/>

w miejscu:

<camel:camelContext id="camelContext">
 
	<camel:route id="airLineQuoteRoute">
 
		<camel:from uri="cxf:bean:reservationService" />
 
		<camel:wireTap uri="direct:logInfo"/>
 
                ...
 
		<camel:log message="*********** After receving the inbound request ************ " />
 
	</camel:route>
 
	<camel:route id = "auditLogging">
		<camel:from uri="direct:logInfo"/>
		<camel:to uri="bean:logAudit"/>   
	</camel:route>
 
</camel:camelContext>

co oznacza, że za każdym razem kiedy zdefiniujemy podczas routingu np logowanie:

<camel:log message="*********** After receving the inbound request ************ " />

zostaniemy przekierowani do routingu o id = auditLogging. Routing ten kieruje logowanie camela do zdefiniowanego wcześniej beana:

<bean id="logAudit" class="com.sample.processor.AuditLog" />

Kompletny plik \src\main\webapp\WEB-INF\camel-context.xml który zawiera informacje logujące przedstawia się następująco:

<?xml version="1.0" encoding="UTF-8"?>
 
<!-- Configures the Camel Context -->
 
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:broker="http://activemq.apache.org/schema/core"
	xmlns:cxf="http://camel.apache.org/schema/cxf" xmlns:camel="http://camel.apache.org/schema/spring"
	xsi:schemaLocation="
       http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://activemq.apache.org/schema/core 
       http://activemq.apache.org/schema/core/activemq-core.xsd
       http://camel.apache.org/schema/spring 
       http://camel.apache.org/schema/spring/camel-spring.xsd
	   http://camel.apache.org/schema/cxf 
	   http://camel.apache.org/schema/cxf/camel-cxf.xsd">
 
 
	<!-- Needed Apache CXF imports -->
	<import resource="classpath:META-INF/cxf.xml" />
 
	<!-- beans -->
	<bean id="requestValidator" class="com.sample.processor.RequestValidator" />
	<bean id="getXMLStreamSource" class="com.sample.processor.PrepareXMLStreamProcessor" />
	<bean id="aggregateData" class="com.sample.aggregate.AggregateResponse" />
	<bean id="processResponse" class="com.sample.processor.ProcessResponse" />
	<bean id="exceptionHandler" class="com.sample.processor.ExceptionHandler" />
	<bean id="logAudit" class="com.sample.processor.AuditLog" />
 
	<!-- Endpoint of MockService for Airline A -->
	<cxf:cxfEndpoint id="airlineAEndpoint"
		address="http://localhost:8080/cxf-sample-airlineA-1.0/services/AirLineAQuote" serviceClass="com.sample.aira.quote.AirLineAQuote"
		wsdlURL="wsdl/ReservationServiceAirlineA.wsdl">
		<cxf:properties>
			<entry key="dataFormat" value="PAYLOAD" />
		</cxf:properties>
	</cxf:cxfEndpoint>
 
	<!-- Endpoint of MockService for Airline B -->
	<cxf:cxfEndpoint id="airlineBEndpoint"
		address="http://localhost:8080/cxf-sample-airlineB-1.0/services/AirLineBQuote" serviceClass="com.sample.airb.quote.AirLineBQuote"
		wsdlURL="wsdl/ReservationServiceAirlineB.wsdl">
		<cxf:properties>
			<entry key="dataFormat" value="PAYLOAD" />
		</cxf:properties>
	</cxf:cxfEndpoint>
 
	<!-- Endpoint of Reservation Service -->
	<cxf:cxfEndpoint id="reservationService" address="/QuoteService"
		serviceClass="com.sample.air.quote.AirLineQuote" wsdlURL="wsdl/ReservationService.wsdl">
		<cxf:properties>
			<entry key="dataFormat" value="PAYLOAD" />
			<entry key="schema-validation-enabled" value="true" />
		</cxf:properties>
	</cxf:cxfEndpoint>
 
<camel:camelContext id="camelContext">
 
	<camel:route id="airLineQuoteRoute">
 
		<camel:from uri="cxf:bean:reservationService" />
 
		<camel:wireTap uri="direct:logInfo"/>
 
			<camel:log
				message="*********** After receving the inbound request ************ " />
 
			<camel:log
				message="*********** Validating the request - Starts ************ " />
 
			<camel:to uri="bean:requestValidator" />
 
			<camel:log message="*********** Validating the request - Ends ************ " />
 
			<camel:choice>
				<camel:when>
					<camel:simple>${header.airLines} == 'AirLineA'</camel:simple>
					<camel:to uri="direct:getQuoteA"></camel:to>
				</camel:when>
				<camel:when>
					<camel:simple>${header.airLines} == 'AirLineB'</camel:simple>
					<camel:to uri="direct:getQuoteB"></camel:to>
				</camel:when>
				<camel:when>
					<camel:simple>${header.airLines} == 'All'</camel:simple>
					<camel:to uri="direct:getQuoteMulticast"></camel:to>
				</camel:when>
			</camel:choice>
 
			<!-- To handle exceptions occurred -->
			<camel:onException>
				<camel:exception>java.lang.Exception</camel:exception>
				<camel:log message="Exception occured ${exception.message}" />
			</camel:onException>
		</camel:route>
 
 
		<camel:route id="getQuoteMultiCastRoute">
			<camel:from uri="direct:getQuoteMulticast" />
 
			<camel:log message="Route getQuoteMultiCastRoute Starts .... " />
 
			<camel:multicast strategyRef="aggregateData"
				parallelProcessing="true">
				<camel:to uri="direct:getQuoteA" />
				<camel:to uri="direct:getQuoteB" />
			</camel:multicast>
 
			<camel:to uri="bean:processResponse" />
 
			<camel:to uri="xslt://process_response.xsl" />
			<camel:onException>
				<camel:exception>java.lang.Exception</camel:exception>
				<camel:log message="Exception occured ${exception.message}" />
				<camel:to uri="bean:exceptionHandler" />
			</camel:onException>
 
			<camel:log message="Route getQuoteMultiCastRoute Ends .... "
				loggingLevel="DEBUG" />
		</camel:route>
 
		<camel:route id="getQuoteAirLineARoute">
			<camel:from uri="direct:getQuoteA" />
			<camel:log message="Route getQuoteAirLineARoute Starts .... " />
 
			<camel:to uri="bean:getXMLStreamSource" />
 
			<camel:log message="*********** Transforming the request ************ " />
			<camel:to uri="xslt://airlineA_req_transform.xsl" />
 
 
			<camel:setHeader headerName="operationNamespace">
				<camel:simple>http://aira.sample.com/quote/</camel:simple>
			</camel:setHeader>
 
			<camel:setHeader headerName="SOAPAction">
				<camel:simple>http://aira.sample.com/quote/getQuoteOperation</camel:simple>
			</camel:setHeader>
 
			<camel:log
				message="Before calling Airline A Endpoint for Operation: ${header.operationName}" />
 
			<camel:to uri="cxf:bean:airlineAEndpoint" />
 
			<camel:log
				message="After calling Airline A Endpoint for Operation: ${header.operationName}" />
 
			<camel:log message="*********** Transforming the response Airline A ************ " />
			<camel:to uri="xslt://airline_resp_transform.xsl" />
 
			<camel:onException>
				<camel:exception>java.lang.Exception</camel:exception>
				<camel:log message="Exception occured ${exception.message}" />
				<camel:to uri="bean:exceptionHandler" />
			</camel:onException>
			<camel:log message="Route getQuoteAirLineARoute Ends .... " />
		</camel:route>
 
		<camel:route id="getQuoteAirLineBRoute">
			<camel:from uri="direct:getQuoteB" />
 
			<camel:log message="Route getQuoteAirLineBRoute Starts .... " />
 
			<camel:to uri="bean:getXMLStreamSource" />
 
			<camel:log message="*********** Transforming the request Airline B ************ " />
			<camel:to uri="xslt://airlineB_req_transform.xsl" />
 
			<camel:setHeader headerName="operationNamespace">
				<camel:simple>http://airb.sample.com/quote/</camel:simple>
			</camel:setHeader>
 
			<camel:setHeader headerName="SOAPAction">
				<camel:simple>http://airb.sample.com/quote/getQuoteOperation</camel:simple>
			</camel:setHeader>
 
			<camel:log
				message="Before calling Airline B Endpoint for Operation: ${header.operationName}" />
 
			<camel:to uri="cxf:bean:airlineBEndpoint" />
 
			<camel:log
				message="After calling Airline B Endpoint for Operation: ${header.operationName}" />
 
			<camel:log message="*********** Transforming the response ************ " />
			<camel:to uri="xslt://airline_resp_transform.xsl" />
 
			<camel:onException>
				<camel:exception>java.lang.Exception</camel:exception>
				<camel:log message="Exception occured ${exception.message}" />
				<camel:to uri="bean:exceptionHandler" />
			</camel:onException>
 
			<camel:log message="Route getQuoteAirLineBRoute Ends .... "
				loggingLevel="DEBUG" />
		</camel:route>
 
		<camel:route id = "auditLogging">
			<camel:from uri="direct:logInfo"/>
			<camel:to uri="bean:logAudit"/>   
		</camel:route>
 
	</camel:camelContext>
</beans>

w wyniku wywołania dla WSDLa:

http://localhost:8080/ReservationService-1.0-SNAPSHOT/QuoteService?wsdl

requestu:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:quot="http://air.sample.com/quote/">
   <soapenv:Header/>
   <soapenv:Body>
      <quot:getQuote>
         <getQuote>
            <source>HYD</source>
            <destination>CHN</destination>
            <date>25/09/2013</date>
            <airline>All</airline>
         </getQuote>
      </quot:getQuote>
   </soapenv:Body>
</soapenv:Envelope>

w logach Apache Tomcata otrzymujemy:

[          http-nio-8080-exec-6] airLineQuoteRoute              INFO  *********** After receving the inbound request ************
[          http-nio-8080-exec-6] airLineQuoteRoute              INFO  *********** Validating the request - Starts ************
[          http-nio-8080-exec-6] XPathReaderUtil                INFO  XPathReaderUtil::getNodeValue()::Node Value : HYD
[          http-nio-8080-exec-6] XPathReaderUtil                INFO  XPathReaderUtil::getNodeValue()::Node Value : CHN
[          http-nio-8080-exec-6] XPathReaderUtil                INFO  XPathReaderUtil::getNodeValue()::Node Value : 25/09/2013
[          http-nio-8080-exec-6] XPathReaderUtil                INFO  XPathReaderUtil::getNodeValue()::Node Value : All
[          http-nio-8080-exec-6] airLineQuoteRoute              INFO  *********** Validating the request - Ends ************
[          http-nio-8080-exec-6] getQuoteMultiCastRoute         INFO  Route getQuoteMultiCastRoute Starts ....
[Context) thread #2 - Multicast] getQuoteAirLineARoute          INFO  Route getQuoteAirLineARoute Starts ....
[Context) thread #3 - Multicast] getQuoteAirLineBRoute          INFO  Route getQuoteAirLineBRoute Starts ....
[Context) thread #2 - Multicast] getQuoteAirLineARoute          INFO  *********** Transforming the request ************
[Context) thread #3 - Multicast] getQuoteAirLineBRoute          INFO  *********** Transforming the request Airline B ************
[Context) thread #2 - Multicast] getQuoteAirLineARoute          INFO  Before calling Airline A Endpoint for Operation: getQuoteOperation
[Context) thread #3 - Multicast] getQuoteAirLineBRoute          INFO  Before calling Airline B Endpoint for Operation: getQuoteOperation
[           default-workqueue-2] getQuoteAirLineARoute          INFO  After calling Airline A Endpoint for Operation: getQuoteOperation
[           default-workqueue-2] getQuoteAirLineARoute          INFO  *********** Transforming the response Airline A ************
[           default-workqueue-2] getQuoteAirLineARoute          INFO  Route getQuoteAirLineARoute Ends ....
[           default-workqueue-1] getQuoteAirLineBRoute          INFO  After calling Airline B Endpoint for Operation: getQuoteOperation
[           default-workqueue-1] getQuoteAirLineBRoute          INFO  *********** Transforming the response ************

Na koniec tej serii artykułów o apache camel chciałbym jeszcze raz zaznaczyć, że przykład przedstawiony w 1,2,3 części oparty jest o oryginalny kod zawarty na stronie – https://www.javaworld.com/article/2078883/java-tip-write-an-soa-integration-layer-with-apache-camel.html?page=1. Ukłony dla autorów!

Zobacz kod na GitHubie i zapisz się na bezpłatny newsletter!

.

 

 

Leave a comment

Your email address will not be published.


*