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 ...
随机推荐
- 第二周<导学/分类>
分类学习 分类算法各有不同 knn naivebyes regression dnn sklearn.linear_modlel 线性函数 sklearn.preprocessing 非线性函数 分类 ...
- 可复用且高度解耦的iOS用户统计实现
http://www.cocoachina.com/ios/20160421/15912.html 本文为投稿文章,作者:编程小翁(简书) 用户统计 用户行为统计(User Behavior Stat ...
- python pattern 类
- ThInkPHP加密和解密cookie(登录操作)
摘自:http://www.thinkphp.cn/code/1794.html 通过加密cookie是网站安全性更高,登录信息不保存在session中在function.php文件在建立两个函数,加 ...
- Spring → 04:Bean(1)
一.Bean概念 Spring Bean是被实例的,组装的及被Spring 容器管理的Java对象. Spring 容器会自动完成@bean对象的实例化. 创建应用对象之间的协作关系的行为称为:装配( ...
- 【JZOJ4824】【NOIP2016提高A组集训第1场10.29】配对游戏
题目描述 流行的跳棋游戏是在一个有m*n个方格的长方形棋盘上玩的.棋盘起初全部被动物或障碍物占满了.在一个方格中,'X'表示一个障碍物,一个'0'-'9'的个位数字表示一个不同种类的动物,相同的个位数 ...
- C++模板编译模型
一:传统的编译模型 使用C/C++进行编程时,一般会使用头文件以使定义和声明分离,并使得程序以模块方式组织.将函数声明.类的定义放在头文件中,而将函数实现以及类成员函数的定义放在独立的文件中. 但是对 ...
- js原生复习2.0
// 1.闭包的作用// 实现共有变量,函数累加器的实现// 可以做缓存以及储存结构// 可以实现封装,实现属性私有化// 模块开发,防止全局污染// var name = 123;// var in ...
- cume_dist(),名次分析——-最大排名/总个数
函数:cume_dist() over(order by id) select id,area,score, cume_dist() over(order by id) a, --按ID最大排名/总个 ...
- 阿里大数据产品Dataphin上线公共云,将助力更多企业构建数据中台
日前,由阿里数据打造的智能数据构建与管理Dataphin,重磅上线阿里云-公共云,开启智能研发版本的公共云公测!在此之前,Dataphin以独立部署方式输出并服务线下客户,已助力多家大型客户高效自动化 ...