Mule自带例子之flight-reservation
1 配置效果图

2 应用的配置文件
<?xml version="1.0" encoding="UTF-8"?> <mule xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting" xmlns:vm="http://www.mulesoft.org/schema/mule/vm" xmlns:json="http://www.mulesoft.org/schema/mule/json"
xmlns:ajax="http://www.mulesoft.org/schema/mule/ajax" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans" version="CE-3.4.0" 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-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/ajax http://www.mulesoft.org/schema/mule/ajax/current/mule-ajax.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd"> <ajax:connector name="Ajax" serverUrl="http://0.0.0.0:9092/reservation" resourceBase="${app.home}/docroot" jsonCommented="true" doc:name="Ajax" /> <!-- 航班预定流,主要通过调用processReservation来完成航班信息的处理 -->
<flow name="makeReservation">
<ajax:inbound-endpoint channel="/searchFlights" connector-ref="Ajax" responseTimeout="10000" doc:name="Ajax" />
<flow-ref name="processReservation" doc:name="processReservation"/>
</flow> <!--
航班预定信息处理流
对航班的安排做的假设:
航班号以3结尾,不可获得,直接抛出FlightUnavailableException异常
航班号不是以3结尾,可进入下一步处理:
航班号以2结尾,可取得座位信息'20A';否则抛出没有座位信息异常'No seat info available',并把'No seat info available'赋给座位信息部分
-->
<flow name="processReservation"> <json:json-to-object-transformer returnClass="org.mule.example.ReservationRequest" doc:name="JSON to ReservationRequest" /> <!-- 把请求的负载保存到session对象中(payload的类型为ReservationRequest) -->
<set-session-variable variableName="reservationRequest" value="#[payload]" doc:name="Save orignal request in Session" /> <!-- 设置响应消息的负载 -->
<set-payload value="#[new org.mule.example.ReservationResponse()]" doc:name="Set ReservationResponse Payload" /> <!-- 把请求消息中的flighs设置到响应消息中 (payload的类型为ReservationResponse) -->
<expression-component doc:name="Add request flight to response">
<![CDATA[payload.setFlights(reservationRequest.flights)]]>
</expression-component> <set-variable variableName="totalPrice" value="#[0]" doc:name="Initialize totalPrice" /> <!-- 设置一个totalPrice变量,值为0 --> <!-- 迭代处理payload(payload的类型为ReservationResponse,里面有请求信息flights) -->
<foreach collection="#[payload.flights]" doc:name="Foreach on flights">
<scripting:transformer doc:name="Search flight availability">
<scripting:script engine="Groovy"><![CDATA[
if (payload.flightNumber.endsWith('3'))
throw new org.mule.example.FlightUnavailableException()
else
payload]]>
</scripting:script>
</scripting:transformer> <!--
此处声明了一个地址为vm://acquireFlightPriceQueue VM出站端点,即把响应消息扔到了acquireSeatsInfoQueue队列
而acquireSeatsInfo流,在地址vm://acquireFlightPriceQueue上等待请求
exchange-pattern="request-response" 表示该VM出站端点 等待acquireSeatsInfo流给的响应
-->
<vm:outbound-endpoint exchange-pattern="request-response" path="acquireSeatsInfoQueue" doc:name="Acquire Seats Info"/>
<!-- 再把响应消息扔到了acquireFlightPriceQueue队列,等待响应 -->
<vm:outbound-endpoint exchange-pattern="request-response" path="acquireFlightPriceQueue" doc:name="Acquire Flight Price" /> <!-- 更新totalPrice变量的值,把本次迭代的票价加到总价中 -->
<set-variable variableName="totalPrice" value="#[totalPrice + payload.ticketPrice]" doc:name="Add price to totalPrice" />
</foreach> <expression-component doc:name="Add total price to reservation">
<![CDATA[payload.totalPrice = flowVars['totalPrice']]]>
</expression-component>
<!-- 把响应对象转换为JSON, 航班预定处理结束 -->
<json:object-to-json-transformer doc:name="Object to JSON" /> <!-- 异常捕获区 -->
<choice-exception-strategy doc:name="Choice Exception Strategy">
<!-- -->
<catch-exception-strategy when="#[exception.causedBy(org.mule.example.FlightUnavailableException)]" doc:name="Catch Exception Strategy">
<scripting:transformer doc:name="Add no avaiilability error">
<scripting:script engine="Groovy">
<![CDATA[
def payload = new org.mule.example.ReservationResponse()
payload.addError('There is no availability for the selected flight!')
payload]]>
</scripting:script>
</scripting:transformer>
<json:object-to-json-transformer doc:name="Object to JSON" />
</catch-exception-strategy> <catch-exception-strategy doc:name="Catch Exception Strategy">
<scripting:transformer doc:name="Add exception message">
<scripting:script engine="Groovy">
<![CDATA[
def payload = new org.mule.example.ReservationResponse()
payload.addError('Error processing request!')
payload]]>
</scripting:script>
</scripting:transformer>
<set-property propertyName="http.status" value="500" doc:name="Set http status 500" />
<json:object-to-json-transformer doc:name="Object to JSON" />
</catch-exception-strategy>
</choice-exception-strategy>
</flow> <!--
应用启动时,该流服务随之启动,然后在vm://acquireFlightPriceQueue上等待请求
-->
<flow name="acquireSeatsInfo">
<!-- 在acquireSeatsInfoQueue路径上等待输入座位信息 -->
<vm:inbound-endpoint exchange-pattern="request-response" path="acquireSeatsInfoQueue" doc:name="VM"/> <!-- 使用脚本进行处理 -->
<scripting:component doc:name="Acquire seats info service">
<scripting:script engine="Groovy"><![CDATA[
if (payload.flightNumber.endsWith('2'))
payload.seatInfo = '20A'
else
throw new Exception('No seat info available')
payload]]></scripting:script>
</scripting:component> <!-- 异常处理 -->
<catch-exception-strategy doc:name="Catch Exception Strategy">
<expression-component doc:name="Add no seat info available message"><![CDATA[payload.seatInfo = 'No seat info available']]></expression-component>
</catch-exception-strategy>
</flow> <!-- 如:下面的path="acquireFlightPriceQueue"配置拼写不对
********************************************************************************
Message : There is no receiver registered on connector "connector.VM.mule.default" for endpointUri vm://acquireFlightPriceQueue
Code : MULE_ERROR-0
在端点地址为vm://acquireFlightPriceQueue的连接器上没有注册接收者
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Exception stack is:
1. There is no receiver registered on connector "connector.VM.mule.default" for endpointUri vm://acquireFlightPriceQueue (org.mule.api.transport.NoReceiverForEndpointException)
org.mule.transport.vm.VMMessageDispatcher:85 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transport/NoReceiverForEndpointException.html)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Root Exception stack trace:
org.mule.api.transport.NoReceiverForEndpointException: There is no receiver registered on connector "connector.VM.mule.default" for endpointUri vm://acquireFlightPriceQueue
at org.mule.transport.vm.VMMessageDispatcher.doSend(VMMessageDispatcher.java:85)
at org.mule.transport.AbstractMessageDispatcher.process(AbstractMessageDispatcher.java:81)
at org.mule.transport.AbstractConnector$DispatcherMessageProcessor.process(AbstractConnector.java:2627)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
航班的票价计算怪怪的,编号*2: payload.ticketPrice = Integer.valueOf(payload.flightNumber) * 2
-->
<flow name="acquireFlightPrice">
<vm:inbound-endpoint exchange-pattern="request-response" path="acquireFlightPriceQueue" doc:name="acquireFlightPrice"/>
<expression-component doc:name="acquireFlightPrice">
<![CDATA[payload.ticketPrice = Integer.valueOf(payload.flightNumber) * 2]]>
</expression-component>
</flow>
</mule>
3 相关类定义
1)Flight -- 航班信息类
package org.mule.example;
import java.io.Serializable;
public class Flight implements Serializable {
/**
*
*/
private static final long serialVersionUID = -841916700389246787L;
private String flightNumber;
private String seatInfo;
private Double ticketPrice;
public String getFlightNumber() {
return flightNumber;
}
public void setFlightNumber(String flightNumber) {
this.flightNumber = flightNumber;
}
public String getSeatInfo() {
return seatInfo;
}
public void setSeatInfo(String seatInfo) {
this.seatInfo = seatInfo;
}
public Double getTicketPrice() {
return ticketPrice;
}
public void setTicketPrice(Double ticketPrice) {
this.ticketPrice = ticketPrice;
}
}
2)ReservationRequest -- 请求消息负载内容类
package org.mule.example;
import java.io.Serializable;
public class ReservationRequest implements Serializable {
/**
*
*/
private static final long serialVersionUID = 3502244785792589115L;
private Flight[] flights;
public Flight[] getFlights() {
return flights;
}
public void setFlights(Flight[] flights) {
this.flights = flights;
}
}
3)ReservationResponse 响应消息负载内容类
package org.mule.example; import java.io.Serializable;
import java.util.ArrayList;
import java.util.List; public class ReservationResponse implements Serializable { private List<String> errors = new ArrayList<String>(); private Flight[] flights;
public Double totalPrice; public Double getTotalPrice() {
return totalPrice;
}
public void setTotalPrice(Double totalPrice) {
this.totalPrice = totalPrice;
} public List<String> getErrors() {
return errors;
}
public void setErrors(List<String> errors) {
this.errors = errors;
} public Flight[] getFlights() {
return flights;
}
public void setFlights(Flight[] flights) {
this.flights = flights;
} //------ 添加错误信息---------------------
public void addError(String error) {
errors.add(error);
} //------- 原始请求对象---------------------
private ReservationRequest originalRequest; public ReservationRequest getOriginalRequest() {
return originalRequest;
} public void setOriginalRequest(ReservationRequest originalRequest) {
this.originalRequest = originalRequest;
}
}
4)FlightUnavailableException 异常类
package org.mule.example;
public class FlightUnavailableException extends Exception {
}
4 Ajax访问页面
1)index.html
<!DOCTYPE html>
<html>
<head>
<link href="flight-reservation.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="mule-resource/js/mule.js"></script>
<script type="text/javascript" src="flight-reservation.js"></script>
</head>
<body onload="onload();">
<div class="content">
<div class="flightReservationHeader"> Flight Reservation System </div>
<div id="title"> Search Best Flight </div>
<div class="searchBox">
<form id="searchFlight">
<div class="cities">
<div id="origin">
<div>Origin</div>
<select class="origin" id="originCity">
<option value=""></option>
<option value="BUE">Buenos Aires (BUE)</option>
</select>
</div>
<div id="destination">
<div>Destination</div>
<select class="destination" id="destinationCity">
<option value=""></option>
<option value="MOW">Moscu (MOW) </option>
<option value="HKG">Hong Kong (HKG) </option>
<option value="TW">Tai Wang (TW)</option>
</select>
</div>
</div>
</form>
<div id="makeSearch">
<input id="searchButton" type="button" value="Search" onClick="makeSearch(dojo.byId('originCity').value, dojo.byId('destinationCity').value)">
</div>
</div>
<div class="response">
<div id="error"><div id="errorMessage"></div></div>
<div id="searchResults"></div>
</div>
</div>
</body>
</html>
2) flight-reservation.js
function onload() {
dojo.byId("error").style.display = "none";
dojo.byId("searchResults").style.display = "none";
}
//发送航班请求
function makeSearch(origin, destination) {
var request="";
if (origin == "BUE" && destination == "MOW")
{
var request = {
"flights": [
{"flightNumber":912},
{"flightNumber":1022},
{"flightNumber":732}
]
};
mule.rpc("/searchFlights", JSON.stringify(request), processResponse);
}
else if (origin == "BUE" && destination == "HKG")
{
var request = {
"flights":[
{"flightNumber":822},
{"flightNumber":1133}
]
};
mule.rpc("/searchFlights", JSON.stringify(request), processResponse);
}
else if (origin == "BUE" && destination == "TW")
{
var request = {
"flights":[
{"flightNumber":822},
{"flightNumber":1004}
]
};
mule.rpc("/searchFlights", JSON.stringify(request), processResponse);
}
else
{
var request={"Invalid Request":[]};
mule.rpc("/searchFlights", JSON.stringify(request), processResponse);
}
}
//处理响应
function processResponse(message) {
resp = JSON.parse("[" + message.data + "]")[0];
if(resp.errors == "")
{
dojo.byId("error").style.display = "none";
dojo.byId("searchResults").style.display = "block";
var results = "<table class='results'>";
results += "<th>Flight Number</th><th>Seat assignment</th><th>Price</th>"
for(var i = 0; i < resp.flights.length;i++)
{
results +="<tr><td>" + resp.flights[i].flightNumber + "</td><td>" + resp.flights[i].seatInfo + "</td><td>$" + resp.flights[i].ticketPrice + "</td></tr>";
}
results += "<tr><td colspan='3'><div id='totalPrice'>Total price is $" + resp.totalPrice + "</div></td><tr>"
results += "</table>";
dojo.byId("searchResults").innerHTML = results;
}
else
{
dojo.byId("error").style.display = "block";
dojo.byId("searchResults").style.display = "none";
dojo.byId("errorMessage").innerHTML = resp.errors;
}
}
3) flight-reservation.css
.content {
padding: 20px 0 20px 50px;
width: 620px;
color: #003399;
background-color: #F8F8FF
}
.flightReservationHeader {
text-align: center;
font-weight: bold;
padding-bottom: 20px;
font-size: 1.8em;
}
#title {
padding-top: 5px;
font-weight: bold;
background-color: #E8EDFF;
width: 150px;
height: 25px;
border: 2px solid #B9C9FE;
text-align: center
}
.searchBox {
width: 550px;
background-color: #E8EDFF;
border: 2px solid #B9C9FE;
position: relative;
padding-bottom: 30px;
padding-top: 20px
}
.cities {
padding: 10px 35px 10px 35px
}
#origin {
float: left;
padding-right: 50px
}
.origin {
width: 215px
}
.destination {
width: 215px
}
#destination {
float: left
}
#makeSearch {
clear: both;
padding: 20px 0 10px 40px;
position: relative;
}
#searchButton {
background-color: #B9C9FE
}
#error {
width: 550px;
height: 50px;
color: #FF0000;
text-align: center;
background-color: #FFDAB9;
border: 2px solid #FF0000;
display: none
}
#errorMessage {
padding: 10px
}
.response {
padding-top: 30px
}
.response table {
width: 550px;
}
.response table th {
background: none repeat scroll 0 0 #B9C9FE;
border-bottom: 1px solid #FFFFFF;
border-top: 4px solid #AABCFE;
color: #003399;
padding: 8px
}
.response table td {
background: none repeat scroll 0 0 #E8EDFF;
border-bottom: 1px solid #FFFFFF;
border-top: 1px solid transparent;
color: #666699;
padding: 8px;
}
#totalPrice {
float: right;
font-weight: bold
}
5 执行效果分析
1)flights编号都以'2'结尾,所以正常运行

2)该请求包含了一个以'3'结尾的航班编号,触发该航班不可得异常

3)尾号为2的航班,分配的座位都是'20A';尾号为3的航班,不可得;尾号不是2、3的航班没座位

Mule自带例子之flight-reservation的更多相关文章
- Mule自带例子之stockquote
1 配置效果图 2 配置文件 <?xml version="1.0" encoding="UTF-8"?> <mule version=&qu ...
- Mule自带例子之loanbroker-simple
1 配置效果图 2 配置文件 <?xml version="1.0" encoding="UTF-8"?> <mule xmlns:cxf=& ...
- Mule ESB 自带例子hello初体验
1 配置的流的效果图 2 应用配置文件hello.xml内容 <?xml version="1.0" encoding="UTF-8"?> < ...
- 可视化工具solo show-----Prefuse自带例子GraphView讲解
2014.10.15日以来的一个月,挤破了头.跑断了腿.伤透了心.吃够了全国最大餐饮连锁店——沙县小吃.其中酸甜苦辣,绝不是三言两语能够说得清道的明的.校招的兄弟姐妹们,你们懂得…… 体会最深的一句话 ...
- MYSQL的锁介绍,以及死锁发生情况-带例子
mysql锁能在并发情况下的mysql进行更好的优化 MySQL有三种锁的级别:页级.表级.行级,这3种锁的特性可大致归纳如下: 表级锁:开销小,加锁快:不会出现死锁:锁定粒度大,发生锁冲突的概率最高 ...
- hadoop自带例子wordcount的具体运行步骤
1.在hadoop所在目录“usr/local”下创建一个文件夹input root@ubuntu:/usr/local# mkdir input 2.在文件夹input中创建两个文本文件file1. ...
- asp.net web api 2.2 基础框架(带例子)
链接:https://github.com/solenovex/asp.net-web-api-2.2-starter-template 简介 这个是我自己编写的asp.net web api 2.2 ...
- OPENCV SVM介绍和自带例子
依据机器学习算法如何学习数据可分为3类:有监督学习:从有标签的数据学习,得到模型参数,对测试数据正确分类:无监督学习:没有标签,计算机自己寻找输入数据可能的模型:强化学习(reinforcement ...
- Python中threading的join和setDaemon的区别[带例子]
python的进程和线程经常用到,之前一直不明白threading的join和setDaemon的区别和用法,今天特地研究了一下.multiprocessing中也有这两个方法,同样适用,这里以thr ...
随机推荐
- LintCode刷题笔记-- InterLeaving
标签: 动态规划 解题思路 1. 这道题最重要的是,存在三个字符串,但是并不需要两个二维矩阵来进行解,因为可以使用i+j-1来代表s3的下标,这样就可以通过i和j来遍历s3了.因为对于任何一个合法的交 ...
- 错觉-Info:视错觉与UI元素间的可能
ylbtech-错觉-Info:视错觉与UI元素间的可能 1.返回顶部 1. 视觉原理在当下红火的机械视觉中是必不可少的,那在我们日常工作的UI产品设计中又有什么可能性的呢?今天,我从“视错觉”这个角 ...
- ecshop二次开发之视频上传
1.前台展示效果: 2.后台展示效果: 3.代码实现: 后台实现过程: 1.在languages/zh_cn/admin/goods.PHP中插入 $_LANG['tab_video'] = '视频上 ...
- Git-svn:用git管理svn仓库
1. 将svn仓库中的项目导入本地git仓库 使用 git svn clone [svn_url] 命令即可完成从svn仓库导入本地,由于该命令会将svn仓库中所有版本的更新都会同步到本地仓库,如果项 ...
- php各种字符串截取
各种字符串截取.php <?php /** * 字符串截取,支持中文和其他编码 * @param [string] $str [字符串] * @param integer $start [起始位 ...
- 深入浅出Cocoa之消息【转】
在入门级别的ObjC 教程中,我们常对从C++或Java 或其他面向对象语言转过来的程序员说,ObjC 中的方法调用(ObjC中的术语为消息)跟其他语言中的方法调用差不多,只是形式有些不同而已. 譬如 ...
- 解决Apache日志"internal dummy connection"方法
最近查看服务器中apache日志,发现有大量的 OPTIONS * HTTP/1.0" 200 - "-" "Apache (internal dummy co ...
- 【JZOJ4814】【NOIP2016提高A组五校联考2】tree
题目描述 给一棵n 个结点的有根树,结点由1 到n 标号,根结点的标号为1.每个结点上有一个物品,第i 个结点上的物品价值为vi. 你需要从所有结点中选出若干个结点,使得对于任意一个被选中的结点,其到 ...
- 【C++】反向迭代器(rbegin,rend)(转载)
转自:http://blog.csdn.net/kjing/article/details/6936325 rbegin和rend,很有用! C++ primer (中文版第四版)第273页 9.3. ...
- mogodb 修改字段属性
修改为decimal类型 db.shopgoods.find({'Pricing.Detail':{$type:2}}).forEach(function(x){x.Pricing.Detail=Nu ...