SCA概念与应用实践(7.SCA装配模型--7.3 接口 interface)
来源:互联网 发布:费用优化步骤 编辑:程序博客网 时间:2024/05/31 13:16
7.3. 接口 interface
7.3.1. 解释
Interface定义一个或多个业务功能。这些业务功能通过service来对外提供,通过reference来使用。一个service提供确切唯一的interface的业务功能给其他component使用。每个接口都定义了一个或多个操作(operation),每个operation都有0个或1个请求(输入)消息和0个或1个响应(输出)消息。请求和响应消息可以是简单类型,如string 值,也可以是复杂类型。
Tuscany中service的interface支持 JavaInterface和WSDLInterface。
查看Restaurant2.composite,RestaurantService定义,
<sca:service name="RestaurantService">
<sca:interface.java interface="restaurant2.api.RestaurantService"/>
</sca:service>
这里使用的是java interface。Interface的值是service类的全限定名。
7.3.2. 替换service的interface为WSDL interface
Ø 生成wsdl文件
首先使用interface restaurant2.api.RestaurantService生成WSDL文件restaurant2.wsdl
Ø 删除RestaurantService的interface,然后添加WSDLPortType
图7_3_1
Ø 并设置peroperties
Interface: http://api.restaurant2/#wsdl.interface(RestaurantService)
图7_3_2
Ø 给RestaurantService添加binding
图7_3_3
Ø 然后设置properties
Uri:http://localhost:8085/RestaurantService
图7_3_4
现在的RestaurantServiceComponent的定义为
<sca:component name="RestaurantServiceComponent">
<sca:implementation.java class="restaurant2.lib.RestaurantServiceImpl"/>
<sca:reference name="menuService"/>
<sca:reference name="billService"/>
<sca:service name="RestaurantService">
<sca:interface.wsdl interface="http://api.restaurant2/#wsdl.interface(RestaurantService)"/>
<sca:binding.ws uri="http://localhost:8085/RestaurantService"/>
<sawsdl:semantic.sawsdl/>
</sca:service>
<sawsdl:semantic.sawsdl/>
</sca:component>
interface – portType/interface
URI地址的格式 <WSDL-namespace-URI>#wsdl.interface(<portTypeOrInterface-name>)
Ø 测试webservice
添加新类RestaurantServiceServer
运行RestaurantServiceServer
图7_3_5
使用soapUI测试webservice
使用restaurant2.wsdl创建一个新的project
图7_3_6
调用getMenu的结果
图7_3_7
调用getBill的结果
图7_3_8
7.3.3. 本地和远程接口
通过在java接口类中添加@Remotable来定义为远程接口,否则为本地接口。本地接口的服务只能被在同一个进程中的component所使用。WSDL定义的接口一定是远程的。远程服务接口不能对方法或操作进行重载。
7.3.4. 双向interface
一个业务服务与另一个业务服务的关系经常是peer-to-peer的,在service层面上要求双向依赖。换句话说,一个service既使用某个service提供的服务,同时又为对方提供服务。特别是在基于异步消息而非远程过程调用(RPC)的情况下。双向接口的目的是在SCA中建立点对点双向服务关系。
对于某个特定的接口类型,interface属性中可以可选择性的定义一个回调接口。如果定义了一个回调接口,那么SCA将该接口整体作为一个双向接口
如果一个service使用一个双向interface定义,那么在component的实现中必须实现该接口,并且通过回调接口来与调用服务接口的client进行交互。
如果一个reference使用一个双向interface定义,那么使用该reference的client component的实现会通过该接口来调用service。Client component的实现必须实现该回调接口。回调既能用于远程也能用于本地服务。一个双向服务接口必须要么都为远程的,要么都为本地的。一个双向服务不能同时混用本地服务和远程服务。
7.3.4.1. 使用双向interface的本地service
以TipServiceComponent上的service为例,BillServiceComponent要调用TipServiceComponent的getPriceWithTip来获得加上小费后的账单。前面的例子中,getPriceWithTip会直接返回账单,下面我们把它修改成不直接返回账单,而是利用callback的方式传回账单。我们简单介绍一下这个例子。在实际应用中,很少会在本地service中使用callback。所有的服务都是在同一个进程中,使用callback也没实际作用。
Ø 定义callback的interface
Ø TipService中声明callback接口,并设置getPriceWithTip为Oneway,没有返回值
Ø }BillServiceImpl中实现回调接口
Ø TipServiceImpl中添加callback接口的setter方法,并修改getPriceWithTip调用callback
Ø 在Restaurant2.composite中删去TipServiceComponent的service,同时删去相应的wire,在BillServiceComponent的reference上添加target。
<?xml version="1.0" encoding="UTF-8"?>
<sca:composite xmlns:frascati="http://frascati.ow2.org" xmlns:instance="http://www.w3.org/2004/08/wsdl-instance" xmlns:sawsdl="http://www.w3.org/ns/sawsdl" xmlns:sca="http://www.osoa.org/xmlns/sca/1.0" xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0" name="Restaurant2" targetNamespace="http://eclipse.org/Restaurant2/src/Restaurant2">
<sca:component name="RestaurantServiceComponent">
<sca:implementation.java class="restaurant2.lib.RestaurantServiceImpl"/>
<sca:reference name="menuService"/>
<sca:reference name="billService"/>
<sca:service name="RestaurantService">
<sca:interface.wsdl interface="http://api.restaurant2/#wsdl.interface(RestaurantService)"/>
<sca:binding.ws uri="http://localhost:8085/RestaurantService"/>
<sawsdl:semantic.sawsdl/>
</sca:service>
<sawsdl:semantic.sawsdl/>
</sca:component>
<sca:component name="MenuServiceComponent">
<sca:implementation.java class="restaurant2.lib.MenuServiceImpl"/>
<sca:service name="MenuService">
<sca:interface.java interface="restaurant2.api.MenuService"/>
</sca:service>
</sca:component>
<sca:component name="BillServiceComponent">
<sca:implementation.java class="restaurant2.lib.BillServiceImpl"/>
<sca:service name="BillService">
<sca:interface.java interface="restaurant2.api.BillService"/>
</sca:service>
<sca:reference name="vatService"/>
<sca:reference name="tipService" target="TipServiceComponent"/>
</sca:component>
<sca:component name="VatServiceComponent">
<tuscany:implementation.script script="restaurant2/lib/VatServiceImpl.js"/>
<sca:service name="VatService">
<sca:interface.java interface="restaurant2.api.VatService"/>
</sca:service>
</sca:component>
<sca:component name="TipServiceComponent">
<sca:implementation.java class="restaurant2.lib.TipServiceImpl"/>
</sca:component>
<sca:wire source="RestaurantServiceComponent/billService" target="BillServiceComponent/BillService"/>
<sca:wire source="BillServiceComponent/vatService" target="VatServiceComponent/VatService"/>
<sca:service name="RestaurantService" promote="RestaurantServiceComponent/RestaurantService"/>
<sca:wire source="RestaurantServiceComponent/menuService" target="MenuServiceComponent/MenuService"/>
</sca:composite>
Ø 运行RestaurantServiceServer
Ø 用soapUI调用webservice
图7_3_9
Ø Application的输出
图7_3_10
7.3.4.2. 使用双向interface的远程调用
Ø 新建一个project,叫做Restaurant2Tip
Ø 在项目Restaurant2Tip的src目录下新建SCA Composite Diagram,名字为Restaurant2Tip
Ø 从项目Restaurant2的SCA composite Diagram里删除TipServiceComponent,
图7_3_11
Ø 在Restaurant2Tip的diagram里新建TipServiceComponent
图7_3_12
Ø 在TipServiceComponent上添加service, 名字是TipService.
Ø 给service TipService添加Java interface,interface的属性中定义:
Interface:restaurant2.api.TipService
CallbackInterface:restaurant2.api.TipServiceCallback
图7_3_13
Ø 给service TipService添加binding,设置binding的uri为http://localhost:8085/TipServiceComponent
图7_3_14
Ø 复制TipService.java TipServiceCallback.java 和TipServiceImpl.java到项目Restaurant2Tip
Ø 新建测试类TipServiceServer.java
图7_3_15
Ø 在Restaurant2的component BillServiceComponent的reference tipService上添加java interface,并设置属性为:
Interface:restaurant2.api.TipService
CallBack Interface:restaurant2.api.TipServiceCallback
图7_3_16
Ø 在Restaurant2的component BillServiceComponent的reference tipService上添加binding,并设置uri为http://localhost:8086/TipServiceComponent
图7_3_17
Ø 首先运行Restaurant2Tip下的TipServiceServer
图7_3_18
Ø 然后运行Restaurant2下面的RestaurantServiceServer
图7_3_19
Ø 使用soapUI调用Restaurant2的web service
图7_3_20
Ø 在Restaurant2Tip的TipServiceServer的Console里输出
图7_3_21
Ø 在Restaurant2的RestaurantServiceServer的Console里输出
Starting of the SCA Restaurant Application exposed as Web Services...
Jun 25, 2010 1:12:32 PM org.apache.tuscany.sca.node.impl.NodeImpl <init>
INFO: Creating node: Restaurant2.composite
Jun 25, 2010 1:12:33 PM org.apache.tuscany.sca.node.impl.NodeImpl configureNode
INFO: Loading contribution: file:/D:/eclipse-3.5.2/workspace/Restaurant2/bin/
Jun 25, 2010 1:12:34 PM
…………
http://quzhengxi:8087/TipServiceComponentCB
... Press Enter to Exit...
call tipService on thread Thread[Thread-9,5,main]
waiting for callback ...
waiting for callback ...
…………
waiting for callback ...
waiting for callback ...
receiveResult on thread Thread[Thread-11,5,main]
Result: 42.35
Set Result to priceWithTipRate.
从输出中可以看到,BillService首先调用TipService的getPriceWithTip,然后等待TipService调用callback来设置priceWithTipRate的值,当BillService获得priceWithTipRate的值后,返回给上一层调用。
7.3.5. 会话接口(conversational interfaces)
7.3.5.1. 解释
很多时候服务不能定义成一个方法单独完成,可能调用一系列的方法。SCA把这一系列调用称为conversation。如果service使用了双向接口,那么会话同时包含调用和回调。
SCA使用使用会话标识来管理会话服务,会话标识来自于应用数据之外的通讯数据中。SCA的runtime依赖binding的支持来会自动管理会话。
支持会话的很重要的目的是管理应用的状态数据。看上面的例子,BillService使用回调方法从TipService来获得计算后的priceWithTipRate。在类BillServiceImpl里我们定义的变量priceWithTipRate是static的。这个在实际应用中是不可行的,如果他是static的,当有两个以上账单结帐时就会出现混乱,即使修改一下,也无法解决同时结帐的问题。
如果去掉static,计算账单的进程那么就无法获得通过callback写入的priceWithTipRate值。下面我们看一下去掉static后的结果。
7.3.5.2. 演示需要使用conversation的地方
Ø 修改BillServiceImpl,(1)删掉static,(2)删掉输出” waiting for callback”,这个是为了比较容易看到输出。
Ø 运行TipServiceServer和RestaurantServiceServer,然后用soapUI调用ws getBill,无法获得结果。
图7_3_22
Ø 查看RestaurantServiceServer的console
图7_3_23
在这里你会看到,call tipService的进程和收到结果的进程是不同的,Thread-9调用this.tipService.getPriceWithTip(pricewithTaxRate); 后一直在等待结果,但是TipService把结果发给了另外一个进程thread-11,所以thread-9一直在等待。
7.3.5.3. 使用conversation解决上面问题
Conversation的定义就是为了解决这个问题。Conversation通过annotation @Conversational 来定义。这个例子中,是个双向的interface,所以调用和回调都要定义conversation。
Ø 修改TipService和,Restaurant2 和Restaurant2Tip里的都要修改
Ø 修改TipServiceImpl,
这两个东西
@Scope("CONVERSATION")
@ConversationAttributes(maxAge="1 seconds"),conversation后面节会再说。
Ø 修改BillServiceImpl
这两项@Scope("CONVERSATION")
@ConversationAttributes(maxAge="10 minutes",
maxIdleTime="5 minutes")
注意这里priceWithTipRate不是static的。
Ø 下面再运行TipServiceServer和RestaurantServiceServer,然后用soapUI调用ws getBill,成功获得结果。
Ø 查看RestaurantServiceServer的console的输出,虽然call tipService的进程和收到结果的进程是不同的,但调用的进程后来可以获得结果。
call tipService on thread Thread[Thread-9,5,main]
waiting for callback ...
waiting for callback ...
......
waiting for callback ...
receiveResult on thread Thread[Thread-11,5,main]
waiting for callback ...
......
waiting for callback ...
waiting for callback ...
Result: 42.35
Set Result to priceWithTipRate.
- SCA概念与应用实践(7.SCA装配模型--7.3 接口 interface)
- SCA概念与应用实践(7.SCA装配模型--7.1 compoent)
- SCA概念与应用实践(7.SCA装配模型--7.2 实现 implementation)
- SCA概念与应用实践(7.SCA装配模型--7.4 composite)
- SCA概念与应用实践(7.SCA装配模型--7.5属性 property)
- SCA概念与应用实践(7.SCA装配模型--7.6服务service & 7.7引用reference)
- SCA概念与应用实践(7.SCA装配模型--7.8连线 wire)
- SCA概念与应用实践(7.SCA装配模型--7.1 compoent)
- SCA概念与应用实践(7.SCA装配模型--7.2 实现 implementation)
- SCA概念与应用实践(6. SCA装配图的解释)
- SCA概念与应用实践(6. SCA装配图的解释)
- SCA概念与应用实践(2. SCA基本概念)
- SCA概念与应用实践(3. SCA实现介绍)
- SCA概念与应用实践(2. SCA基本概念)
- SCA概念与应用实践(3. SCA实现介绍)
- SCA概念与应用实践(1. 介绍和内容)
- SCA概念与应用实践(4.环境安装和设置)
- SCA概念与应用实践(5. 一个例子演示)
- TC官方文档翻译08----内存树数据库API(Tokyo Cabinet/Tokyo Tyarnt 文档系列)
- TC官方文档翻译09----内存池对象API(Tokyo Cabinet/Tokyo Tyarnt 文档系列)
- Mac OS X下CUDA Host端的编译选项设定
- 虚函数表的实质。
- 覆盖,隐藏,重载。
- SCA概念与应用实践(7.SCA装配模型--7.3 接口 interface)
- 实用 Ajax 工具函数
- MFC 对话框 开启 Aero 毛玻璃 半透明 效果 (二)
- JavaScript 预先加载图片
- MFC 对话框 开启 Aero 毛玻璃 半透明 效果 (三)
- JS鼠标划过变换图片案例
- 超酷的JavaScript 图像液态效果
- 系统动力学软件vensim学习之茶水冷却TIME STEP
- web 打印,web打印控件的三种实现方法