Enrich Content and Aggregate Data

Overview

In this lab, you develop routes that process the account records in JSON format, and through enrichment and aggregation create a more complete account record. The resulting record is stored in a database.

Goals

  • Design Apache Camel routes that consume JSON records from AMQ

  • Use the multicast EIP pattern to distribute the messages to the services

  • Design the CXF web service using JAX-WS annotations to consume from SOAP backend service

  • Consume from the backend REST service

  • Aggregate the messages received using the aggregation EIP pattern

  • Save the aggregated message in an SQL database using the Spring SQL component

index.png

部署 Rest 服务

1. 本地启动 Rest 服务
$ cd fuse-get-started/enrich-content-rest-and-ws-microservices/rest-backend-service/
$ mvn spring-boot:run -Dfabric8.skip=true
2. 本地测试 Rest 服务
$ curl -k http://localhost:8080/rest/customerservice/enrich -X POST  -d '{"company":{"name":"Rotobots","geo":"NA","active":true},"contact":{"firstName":"Bill","lastName":"Smith","streetAddr":"100 N Park Ave.","city":"Phoenix","state":"AZ","zip":"85017","phone":"602-555-1100"}}' -H 'content-type: application/json'
{"clientId":0,"salesRepresentative":null,"company":{"name":"Rotobots","geo":"NORTH_AMERICA","active":true},"contact":{"firstName":"Bill","lastName":"Smith","streetAddr":"100 N Park Ave.","city":"Phoenix","state":"AZ","zip":"85017","phone":"602-555-1100"}}
3. 部署 Rest 到 OpenShift
$ cd fuse-get-started/enrich-content-rest-and-ws-microservices/rest-backend-service/
$ mvn fabric8:deploy
4. 远程测试 Rest 服务
$ curl -k http://HOST/rest/customerservice/enrich -X POST  -d '{"company":{"name":"Rotobots","geo":"NA","active":true},"contact":{"firstName":"Bill","lastName":"Smith","streetAddr":"100 N Park Ave.","city":"Phoenix","state":"AZ","zip":"85017","phone":"602-555-1100"}}' -H 'content-type: application/json'
{"clientId":0,"salesRepresentative":null,"company":{"name":"Rotobots","geo":"NORTH_AMERICA","active":true},"contact":{"firstName":"Bill","lastName":"Smith","streetAddr":"100 N Park Ave.","city":"Phoenix","state":"AZ","zip":"85017","phone":"602-555-1100"}}

部署 SOAP 服务

1. 本地启动 SOAP 服务
$ cd fuse-get-started/enrich-content-rest-and-ws-microservices/soap-backend-service/
$ mvn camel:run -Dfabric8.skip=true
Note
本地启动成功后通过 http://localhost:8080/ws/customerService?wsdl 可查看服务描述。
2. 本地测试 SOAP 服务
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.usecase.fuse.org/">
   <soapenv:Header/>
   <soapenv:Body>
      <ser:updateAccount>
         <!--Optional:-->
         <arg0>
            <clientId>0</clientId>
            <!--Optional:-->
            <company>
               <active>true</active>
               <!--Optional:-->
               <geo>NA</geo>
               <!--Optional:-->
               <name>Bill Smith</name>
            </company>
            <!--Optional:-->
            <contact>
               <!--Optional:-->
               <city>Baltimore</city>
               <!--Optional:-->
               <firstName>Satya</firstName>
               <!--Optional:-->
               <lastName>Jayanti</lastName>
               <!--Optional:-->
               <phone>143-222-2344</phone>
               <!--Optional:-->
               <state>MD</state>
               <!--Optional:-->
               <streetAddr>1077 America Ave.</streetAddr>
               <!--Optional:-->
               <zip>11751</zip>
            </contact>
            <!--Optional:-->
            <salesRepresentative>?</salesRepresentative>
         </arg0>
      </ser:updateAccount>
   </soapenv:Body>
</soapenv:Envelope>
3. 部署 SOAP 到 OpenShift
$ cd fuse-get-started/enrich-content-rest-and-ws-microservices/soap-backend-service/
$ mvn fabric8:deploy
Note
本地启动成功后通过 http://HOST/ws/customerService?wsdl 可查看服务描述。

部署 Camel

1. camelContext
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:camel="http://camel.apache.org/schema/spring"
    xmlns:cxf="http://camel.apache.org/schema/cxf"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.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">
    <cxf:cxfEndpoint
        address="http://:/ws/customerService"
        id="customerWebService" loggingFeatureEnabled="true"
        serviceClass="org.fuse.usecase.service.CustomerWS" wsdlURL="classpath:wsdl/customerService.wsdl"/>
    <bean class="org.fuse.usecase.AccountAggregator" id="reconcileData"/>
    <bean class="org.fuse.usecase.ProcessorBean" id="processorBean"/>
    <!--  THIS PROVIDER DOESN'T WORK & RETURN ERROR 415 Unsupported Media Type
      It can't also handle the Body : No message body reader has been found for
      class CXF_Test.cxf_test.Book, ContentType: application/json
      <bean id="jsonProvider" class="org.apache.cxf.jaxrs.provider.json.JSONProvider"/>
    -->
    <bean
        class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider" id="jsonProvider"/>
    <camelContext id="_camelContext1" xmlns="http://camel.apache.org/schema/spring">

        <!--
        <restConfiguration bindingMode="off" component="servlet"
            contextPath="/rest" host="localhost" port="8181"/>
        <rest apiDocs="true" consumes="application/json"
            enableCORS="true"
            id="rest-fba86e71-44f3-46c1-a71c-f311edfa9d05"
            path="/account" produces="application/json">
            <post id="41f43632-5d15-49a1-9d54-0495fbc269d4" uri="/service">
                <to id="_to12" uri="direct:usecase"/>
            </post>
        </rest>
         -->
        <route id="_route3">
<!--             <from id="_from3" uri="direct:usecase"/> -->
            <from id="_from3" uri="amqp:queue:accountQueue"/>
            <convertBodyTo id="_convertBodyTo1" type="String"/>
            <multicast id="_multicast1" parallelProcessing="true" strategyRef="reconcileData">
                <log id="_log2" loggingLevel="INFO" message="inside multicast"/>
                <to id="_to4" uri="direct://callRestEndpoint"/>
                <to id="_to5" uri="direct://callWSEndpoint"/>
            </multicast>
            <log id="_log8" loggingLevel="INFO" message="after multicast : ${body}"/>
            <to id="_to6" uri="direct:insertDB"/>
        </route>
        <!-- Call WebService Client -->
        <route id="_route5">
            <from id="_from5" uri="direct://callWSEndpoint"/>
            <log id="_log12" message="In the SOAP service request: ${body}"/>
            <unmarshal id="_unmarshal1">
                <json library="Jackson" unmarshalTypeName="org.globex.Account"/>
            </unmarshal>
            <to id="_to7" uri="cxf:bean:customerWebService"/>
            <log id="_log10" loggingLevel="INFO" message=">> WebService Response : ${body[0].id}, ${body[0].salesContact}, ${body[0].company.geo}, ${body[0].contact.firstName}, ${body[0].contact.lastName} "/>
        </route>
        <!-- Call REST Client -->
        <route id="_route6">
            <from id="_from6" uri="direct://callRestEndpoint"/>
            <onException id="_onException2">
                <exception>java.lang.Exception</exception>
                <redeliveryPolicy maximumRedeliveries="1"/>
                <handled>
                    <constant>true</constant>
                </handled>
                <log id="_log3" message=">> Error : ${exception.message}, ${exception.stacktrace}"/>
            </onException>
            <setHeader headerName="Content-Type" id="_setHeader1">
                <constant>application/json</constant>
            </setHeader>
            <setHeader headerName="Accept" id="_setHeader2">
                <constant>application/json</constant>
            </setHeader>
            <setHeader headerName="CamelHttpMethod" id="_setHeader3">
                <constant>POST</constant>
            </setHeader>
            <setHeader headerName="originalBody" id="_setHeader4">
                <simple>${body}</simple>
            </setHeader>
            <setHeader headerName="CamelHttpUri" id="_setHeader5">
                <simple>http://:/rest/customerservice/enrich</simple>
            </setHeader>
            <log id="_log4" message=">> Before calling restClient : ${body}"/>
            <to id="_to8" uri="http4://restClient"/>
            <unmarshal id="_unmarshal2">
                <json library="Jackson" unmarshalTypeName="org.globex.Account"/>
            </unmarshal>
            <log id="_log6" message=">> REST Response : ${body}"/>
        </route>
        <!-- Insert Records -->
        <route id="_route7">
            <from id="_from7" uri="direct:insertDB"/>
            <log id="_log11" message=">> Before Insert : ${body}"/>
            <bean id="_bean3" method="defineNamedParameters" ref="processorBean"/>
            <to id="_to9" uri="sql:INSERT INTO USECASE.T_ACCOUNT(CLIENT_ID,SALES_CONTACT,COMPANY_NAME,COMPANY_GEO,COMPANY_ACTIVE,CONTACT_FIRST_NAME,CONTACT_LAST_NAME,CONTACT_ADDRESS,CONTACT_CITY,CONTACT_STATE,CONTACT_ZIP,CONTACT_PHONE,CREATION_DATE,CREATION_USER) VALUES (:#CLIENT_ID,:#SALES_CONTACT,:#COMPANY_NAME,:#COMPANY_GEO,:#COMPANY_ACTIVE,:#CONTACT_FIRST_NAME,:#CONTACT_LAST_NAME,:#CONTACT_ADDRESS,:#CONTACT_CITY,:#CONTACT_STATE,:#CONTACT_ZIP,:#CONTACT_PHONE,:#CREATION_DATE,:#CREATION_USER);"/>
            <log id="_log7" message=">>> Results : ${body}"/>
        </route>

    </camelContext>
</beans>
2. 本地部署
$ cd fuse-get-started/enrich-content-rest-and-ws-microservices/amq-enrich-persist/
$ mvn spring-boot:run -Dfabric8.skip=true -Dspring.profiles.active=dev
3. 部署到 OpenShift
$ cd fuse-get-started/enrich-content-rest-and-ws-microservices/amq-enrich-persist/
$ mvn fabric8:deploy -Popenshift

测试

使用 AMQ 客户端,发送如下三条消息到 accountQueue
{"company":{"name":"Rotobots","geo":"NA","active":true},"contact":{"firstName":"Bill","lastName":"Smith","streetAddr":"100 N Park Ave.","city":"Phoenix","state":"AZ","zip":"85017","phone":"602-555-1100"}}

{"company":{"name":"BikesBikesBikes","geo":"NA","active":true},"contact":{"firstName":"George","lastName":"Jungle","streetAddr":"1101 Smith St.","city":"Raleigh","state":"NC","zip":"27519","phone":"919-555-0800"}}

{"company":{"name":"CloudyCloud","geo":"EU","active":true},"contact":{"firstName":"Fred","lastName":"Quicksand","streetAddr":"202 Barney Blvd.","city":"Rock City","state":"MI","zip":"19728","phone":"313-555-1234"}}

results matching ""

    No results matching ""