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 值,也可以是复杂类型。

 

Tuscanyserviceinterface支持 JavaInterfaceWSDLInterface

查看Restaurant2.compositeRestaurantService定义,

<sca:service name="RestaurantService">

      <sca:interface.java interface="restaurant2.api.RestaurantService"/>

</sca:service>

这里使用的是java interfaceInterface的值是service类的全限定名。

 

7.3.2.       替换serviceinterfaceWSDL interface

Ø         生成wsdl文件

首先使用interface restaurant2.api.RestaurantService生成WSDL文件restaurant2.wsdl

 

Ø         删除RestaurantServiceinterface,然后添加WSDLPortType

 7_3_1

 

7_3_1

Ø         并设置peroperties

Interface: http://api.restaurant2/#wsdl.interface(RestaurantService)

7_3_2

 

7_3_2

Ø         RestaurantService添加binding

7_3_3

 

7_3_3

Ø         然后设置properties

Urihttp://localhost:8085/RestaurantService

7_4_4

 

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

 

7_3_5

使用soapUI测试webservice

使用restaurant2.wsdl创建一个新的project

7_3_6 

 

7_3_6

调用getMenu的结果

7_3_7

 

7_3_7

调用getBill的结果

7_3_8

 

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定义,那么使用该referenceclient component的实现会通过该接口来调用serviceClient component的实现必须实现该回调接口。回调既能用于远程也能用于本地服务。一个双向服务接口必须要么都为远程的,要么都为本地的。一个双向服务不能同时混用本地服务和远程服务。

7.3.4.1. 使用双向interface的本地service

TipServiceComponent上的service为例,BillServiceComponent要调用TipServiceComponentgetPriceWithTip来获得加上小费后的账单。前面的例子中,getPriceWithTip会直接返回账单,下面我们把它修改成不直接返回账单,而是利用callback的方式传回账单。我们简单介绍一下这个例子。在实际应用中,很少会在本地service中使用callback。所有的服务都是在同一个进程中,使用callback也没实际作用。

Ø         定义callbackinterface

Ø         TipService中声明callback接口,并设置getPriceWithTipOneway,没有返回值

 

Ø         }BillServiceImpl中实现回调接口

 

Ø         TipServiceImpl中添加callback接口的setter方法,并修改getPriceWithTip调用callback

 

Ø         Restaurant2.composite中删去TipServiceComponentservice,同时删去相应的wire,在BillServiceComponentreference上添加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

 

7_3_9

Ø         Application的输出
7_3_10

 

7_3_10

7.3.4.2.       使用双向interface的远程调用

Ø         新建一个project,叫做Restaurant2Tip

Ø         在项目Restaurant2Tipsrc目录下新建SCA Composite Diagram,名字为Restaurant2Tip

Ø         从项目Restaurant2SCA composite Diagram里删除TipServiceComponent,

7_3_11

7_3_11

Ø         Restaurant2Tipdiagram里新建TipServiceComponent

 7_3_12

 

7_3_12

Ø         TipServiceComponent上添加service, 名字是TipService.

Ø         service TipService添加Java interfaceinterface的属性中定义:

Interfacerestaurant2.api.TipService

CallbackInterfacerestaurant2.api.TipServiceCallback

7_3_13

 

7_3_13

 

Ø         service TipService添加binding,设置bindingurihttp://localhost:8085/TipServiceComponent

7_3_14

 

7_3_14

Ø         复制TipService.java TipServiceCallback.java TipServiceImpl.java到项目Restaurant2Tip

Ø         新建测试类TipServiceServer.java

 

7_3_15 

 

7_3_15

Ø         Restaurant2component BillServiceComponentreference tipService上添加java interface,并设置属性为:

Interfacerestaurant2.api.TipService

CallBack Interfacerestaurant2.api.TipServiceCallback

7_3_16

 

7_3_16

Ø         Restaurant2component BillServiceComponentreference tipService上添加binding,并设置urihttp://localhost:8086/TipServiceComponent

7_3_17

 

7_3_17

Ø         首先运行Restaurant2Tip下的TipServiceServer

7_3_18

 

7_3_18

Ø         然后运行Restaurant2下面的RestaurantServiceServer

7_3_19

 

7_3_19

Ø         使用soapUI调用Restaurant2web service

7_3_20

 

7_3_20

Ø         Restaurant2TipTipServiceServerConsole里输出

7_3_21

 

7_3_21

Ø         Restaurant2RestaurantServiceServerConsole里输出

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首先调用TipServicegetPriceWithTip,然后等待TipService调用callback来设置priceWithTipRate的值,当BillService获得priceWithTipRate的值后,返回给上一层调用。

 

7.3.5.       会话接口(conversational interfaces

7.3.5.1.       解释

很多时候服务不能定义成一个方法单独完成,可能调用一系列的方法。SCA把这一系列调用称为conversation。如果service使用了双向接口,那么会话同时包含调用和回调。

SCA使用使用会话标识来管理会话服务,会话标识来自于应用数据之外的通讯数据中。SCAruntime依赖binding的支持来会自动管理会话。

支持会话的很重要的目的是管理应用的状态数据。看上面的例子,BillService使用回调方法从TipService来获得计算后的priceWithTipRate。在类BillServiceImpl里我们定义的变量priceWithTipRatestatic的。这个在实际应用中是不可行的,如果他是static的,当有两个以上账单结帐时就会出现混乱,即使修改一下,也无法解决同时结帐的问题。

如果去掉static,计算账单的进程那么就无法获得通过callback写入的priceWithTipRate值。下面我们看一下去掉static后的结果。

7.3.5.2.       演示需要使用conversation的地方

Ø         修改BillServiceImpl,(1)删掉static,(2)删掉输出” waiting for callback”,这个是为了比较容易看到输出。

 

Ø         运行TipServiceServerRestaurantServiceServer,然后用soapUI调用ws getBill,无法获得结果。

7_3_22

 

7_3_22

Ø         查看RestaurantServiceServerconsole

7_3_23

 

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的。

 

 

Ø         下面再运行TipServiceServerRestaurantServiceServer,然后用soapUI调用ws getBill,成功获得结果。

Ø         查看RestaurantServiceServerconsole的输出,虽然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.

 

原创粉丝点击