`
C_LIFE
  • 浏览: 37589 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

SOA Suite 11g 开发指南之十:增加异常处理

    博客分类:
  • SOA
 
阅读更多
声明:该博文来自热爱JAVA,热爱生活。原文地址http://maping930883.blogspot.com/

Oracle SOA Suite 提供了复杂而精致的异常处理机制,你可以定义异常处理器来处理不同层次的异常,包括系统异常和应用异常。
BPEL的规范中提供了如何捕捉和处理异常,详细说明请参考《BPEL 如何处理异常?》。
但SOA应用中不光是BPEL组件,还有其它组件,比如Mediator。而Mediator并没有提供有关异常的规范,那么该如何处理Mediator中的异常呢?
为此,Oracle SOA Suite 提供了一个基于策略的异常处理机制,这些策略可以绑定到整个SOA 应用或者应用中的一个组件,比如Mediator。
在这个实验中,我们将首先处理基于策略的异常,然后再处理BPEL的异常。

1. 基于策略的异常
为了模拟remote fault,在EM中,我们把getStatusByCC服务Shutdown,输入大订单测试。
(1)remote fault异常



(2)增加策略文件:fault-policies.xml。与POProcessing中的composite.xml文件在同一目录。
<!-- Step #1: Add your fault handler for remote fault here: -->
<faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
name="bpelx:remoteFault">
<condition>
<action ref="ora-human-intervention"/>
</condition>
</faultName>

(3)增加策略文件:fault-bindings.xml。与POProcessing中的composite.xml文件在同一目录。
<?xml version="1.0" encoding="UTF-8" ?>
<faultPolicyBindings version="2.0.1"
xmlns="http://schemas.oracle.com/bpel/faultpolicy"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<composite faultPolicy="POProcessingFaults"/>
</faultPolicyBindings>

(4)重新发布POProcessing,重新测试大订单。发现该异常是可以恢复重试的。





(5)重启getStatusByCC服务,点击Recover重试。









2. 处理BPEL异常
BPEL的规范中提供了如何捕捉和处理异常,因此发生在BPEL中的异常最好使用规范中的处理办法。
目前,validateForCC的实现:如果传入一个不存在的信用卡号,validateForCC只是简单的返回一个空响应。这个空响应不太直观,因为返回空响应可能还有其它原因。
现在,修改validateForCC的实现如下:如果传入一个不存在的信用卡号,将会抛出一个UnkonwCC的异常。在BPEL中可以捕捉到这个异常,然后进行处理。这样的修改在设计上更加合理。

2.1 实验准备:创建VALIDATECC存储过程
该存储过程用来验证信用卡是否存在,如果不存在抛出应用异常:-20001, 'UNKNOWN CREDIT CARD'。
sqlplus soademo/soademo @create_validate_cc.sql
create or replace FUNCTION VALIDATECC(cc_number IN VARCHAR2)
RETURN VARCHAR2 AS
l_status CREDITCARDINFO.STATUS%TYPE;
BEGIN
select status
into l_status
from creditcardinfo
where ccnumber = cc_number;
RETURN l_status;
EXCEPTION
WHEN NO_DATA_FOUND THEN
raise_application_error(-20001, 'UNKNOWN CREDIT CARD');
END VALIDATECC;
/

2.2 修改ValidateForCC,增加validateCC Reference。
Meditor过滤条件如下:以2开头的信用卡号调用validateCC,返回'code=20001'的异常;
不以2开头的信用卡号调用getCreditValidation。
拖放Database Adapter,并设置如下:






2.3 修改ApproveLargeOrder BPEL。
把invokeCCStatusService放入一个Scope中,并为这个Scope添加一个Catch分支,捕捉bindingFault异常。
这里有一个BUG:默认生成的.bpel文件中定义的变量是<variable messageType="bpelx:bindingFault" name="FaultVar"/>
但实际上,没有地方定义类型bpelx:bindingFault,应该改成如下的样子:
<variable messageType="bpelx:RuntimeFaultMessage" name="FaultVar"/>
否则,编译时会报错:WSDL messageType "{http://schemas.oracle.com/bpel/extension}bindingFault" of variable "" is not defined in any of the WSDL files。

2.4 修改fault-policies.xml。
由于上一个实验中设置了基于策略的异常处理,而基于策略的异常处理优先于BPEL的异常处理,所以以下的设置是让基于策略的异常处理啥都不做,直接抛出异常,由BPEL异常处理来接管。
<!-- Step #2: Add your fault handler for binding fault here: -->
<faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension" name="bpelx:bindingFault">
<condition>
<!-- Let the component handle this specific binding fault -->
<test>$fault.code="20001"</test>
<action ref="ora-rethrow-fault"/>
</condition>
</faultName>

2.5 测试大订单,订单号以2开头。
你会发现ApproveLargeOrder中,异常被异常策略框架抛出,然后由BPEL异常框架捕捉到并处理。




3. 使用Java Fault Handler捕捉和处理异常。

3.1 MyFaultHandler.java
package soatraining.faulthandling;

import java.io.File;
import java.io.PrintStream;
import java.util.*;
import oracle.integration.platform.faultpolicy.IFaultRecoveryContext;
import oracle.integration.platform.faultpolicy.IFaultRecoveryJavaClass;

public class MyFaultHandler
implements IFaultRecoveryJavaClass
{

public MyFaultHandler()
{
}

public void handleRetrySuccess(IFaultRecoveryContext ifc)
{
print("RertySuccess");
}

public String handleFault(IFaultRecoveryContext ifc)
{
print("Handle Fault");
print("Properties");
print("=================================================================");
Map props = ifc.getProperties();
java.util.Map.Entry entry;
for(Iterator iterator = props.entrySet().iterator(); iterator.hasNext(); print((new StringBuilder()).append((String)entry.getKey()).append(" = ").append(((ArrayList)entry.getValue()).get(0)).toString()))
entry = (java.util.Map.Entry)iterator.next();

String logFileName = (String)((ArrayList)props.get("logFileName")).get(0);
String logFileDir = (String)((ArrayList)props.get("logFileDir")).get(0);
PrintStream ps = null;
try
{
ps = new PrintStream((new StringBuilder()).append(logFileDir).append(File.separator).append(logFileName).toString());
}
catch(Exception e)
{
print(e.getMessage());
}
log(ps, "Fault Details");
log(ps, "===============================================================");
log(ps, (new StringBuilder()).append("Fault Type ................ ").append(ifc.getType()).toString());
log(ps, (new StringBuilder()).append("Poilcy ID ................. ").append(ifc.getPolicyId()).toString());
log(ps, (new StringBuilder()).append("Faulted Partner Link ...... ").append(ifc.getReferenceName()).toString());
log(ps, (new StringBuilder()).append("Port Type ................. ").append(ifc.getPortType()).toString());
return "OK";
}

private void log(PrintStream ps, String s)
{
try
{
ps.println(s);
}
catch(Exception e)
{
print(e.getMessage());
}
}

private void print(String s)
{
System.out.println((new StringBuilder()).append("MyFaultHanlder: ").append(s).toString());
}
}

3.2 修改fault-policies.xml。
<!-- Step #2: Add your fault handler for binding fault here: -->
<faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension" name="bpelx:bindingFault">
<condition>
<!-- Let the component handle this specific binding fault -->
<test>$fault.code="20001"</test>
<action ref="my-java-handler"/>
</condition>
</faultName>

3.3 测试。
查看my-java-handler的定义,会发现它只是记录一些Log,然后重新抛出异常。
因此,BPEL的异常处理机制最终来接管该异常



4. 使用Java Fault Handler捕捉和处理Mediator异常。
Mediator异常处理只能使用基于策略的方式。
Mediator异常可能来自Adapter异常,可能来自Transformation异常。
我们将使用Java Fault Handler捕捉和处理Mediator的所有异常。
为了模拟Adapter异常,我们将把temp目录改成只读,这样对其进行写操作时将抛出异常。
注意,在Windows平台上,改成只读方式不起作用。即使把该目录换名也不行,File Adapter会自动创建该目录。

4.1 修改fault-policies.xml。
<!-- Step #3: Add your fault handler for mediator faults here: -->
<faultName xmlns:medns="http://schemas.oracle.com/mediator/faults" name="medns:mediatorFault">
<condition>
<action ref="my-mediator-fault-handler"/>
</condition>
</faultName>

<!-- Step #4: Add the Action definition for handling mediator fauls using custom java here:-->
<Action id="my-mediator-fault-handler">
<javaAction className="soatraining.faulthandling.MyFaultHandler"
defaultAction="ora-terminate" propertySet="myMediatorProps">
<returnValue value="OK" ref="ora-human-intervention"/>
</javaAction>
</Action>

<!-- Step #5: Add new property set for MyFaultHandler for logging Mediator faults here:-->
<propertySet name="myMediatorProps">
<property name="logFileName">mediator-faults.log</property>
<property name="logFileDir">c:\po\log</property>
</propertySet>

4.2 修改routePO mediator。
之所以要把“quantity < 1000”的路由从Sequential改成Parallel。
是因为Sequential表明Mediator的调用者和Mediator使用的是同一个Thread和Transaction Context,如果出现Mediator异常,异常将直接返回给调用者,而无法被Java Fault Handler捕捉到。
使用Parallel表明进入Mediator后,将启动一个新Thread和Transaction Context,如果出现Mediator异常,可以被Java Fault Handler捕捉到。



4.3 测试。
EM 中应该提示等待人工恢复,因为策略上设置的是“ora-human-intervention”。
因为我是Win7平台,所以没有测试,以后在Linux上再验证吧。
  • 大小: 38.1 KB
  • 大小: 27.4 KB
  • 大小: 44.4 KB
  • 大小: 70.8 KB
  • 大小: 54.7 KB
  • 大小: 38.4 KB
  • 大小: 106.6 KB
  • 大小: 58 KB
  • 大小: 98.2 KB
  • 大小: 81.6 KB
  • 大小: 50.6 KB
  • 大小: 74.9 KB
  • 大小: 55.7 KB
  • 大小: 150.5 KB
分享到:
评论

相关推荐

    Oracle SOA Suite 11g入门实例

    本入门实例将带领我们逐步了解并掌握如何在Oracle SOA Suite 11g环境中进行开发。 首先,我们需要理解SOA的核心概念。SOA是一种设计原则,它允许不同的应用程序通过共享可重用的服务进行通信。这些服务是自包含的,...

    Oracle SOA Suite 11g Developer's Cookbook

    《Oracle SOA Suite 11g Developer's Cookbook》是一本专为Oracle SOA Suite开发者设计的实战指南,旨在帮助读者深入理解和应用Oracle SOA Suite 11g的各种功能和技术。Oracle SOA Suite作为一套全面的面向服务架构...

    Oracle SOA Suite 11g Developer's Guide

    《Oracle SOA Suite 11g Developer's Guide》是一本旨在帮助开发者掌握Oracle SOA Suite 11g这一强大服务导向架构(Service-Oriented Architecture, SOA)解决方案的专业指南。本书由Antony Reynolds与Matt Wright...

    Oracle SOA Suite 11g Handbook

    《Oracle SOA Suite 11g Handbook》是针对Oracle企业级服务导向架构(Service-Oriented Architecture, SOA)解决方案的权威指南。Oracle SOA Suite是Oracle公司提供的一套全面集成的中间件平台,用于构建、部署和...

    Oracle SOA Suite 11g 环境搭建手册(二)

    ### Oracle SOA Suite 11g 环境搭建手册(二)——深入解析与实践指南 #### 一、WebLogic 11g 安装流程详解 在Oracle SOA Suite 11g环境中,WebLogic 11g作为基础的应用服务器平台起着至关重要的作用。以下是详细的...

    Oracle SOA Suite 11g R1 Developer's Guide.pdf

    《Oracle SOA Suite 11g R1 Developer's Guide》一书是针对Oracle SOA Suite 11g R1版本的全面开发指南,由Antony Reynolds和Matt Wright共同撰写,于2010年由Packt Publishing出版。本书旨在帮助开发者理解和掌握...

    Oracle SOA Suite 11g 环境搭建手册(一)

    ### Oracle SOA Suite 11g 环境搭建手册(一) #### 1. 前期准备 ##### 1.1. 硬件平台 为了顺利部署Oracle SOA Suite 11g,首先需要确保具备合适的硬件平台。最低要求如下: - 物理内存:1GB - 硬盘空间:20GB ...

    ORACLE SOA SUITE

    Oracle SOA Suite是一款全面的企业服务总线(ESB)和业务流程管理(BPM)解决方案,由Oracle公司提供。它为企业提供了一整套工具和服务,用于构建、部署和管理面向服务的架构(SOA)。本篇文章将深入探讨Oracle SOA ...

    oracle SOA suit开发详解指南

    ### Oracle SOA Suite 11g R1 开发详解指南 #### 一、概述 《Oracle SOA Suite 11g R1 开发详解指南》是一本深入介绍Oracle SOA Suite 11g R1的书籍,作者为Antony Reynolds与Matt Wright。该书旨在帮助开发者了解...

    oracle soa suite handbook

    1. **开发环境**:使用Oracle JDeveloper,一个全面的集成开发环境(IDE),支持SOA Suite组件的开发。 2. **生命周期管理**:通过Oracle Enterprise Manager提供,包括版本控制、测试、部署和更新等。 3. **测试与...

    Oracle SOA Suite 11g Developer's Cookbook source code

    Oracle SOA Suite 11g Developer's Cookbook 代码

    quick start guide soa suite11gr1ps4

    ### Oracle SOA Suite 11g R1 (11.1.1.5.0) 快速入门指南 #### 一、Oracle SOA Suite 概述 Oracle SOA Suite 是一套全面且可热插拔的软件套件,用于构建、部署和服务导向架构(SOA)的管理。该套件的各个组件都...

Global site tag (gtag.js) - Google Analytics