[译文] 使用Safesforce.com和Java来整合云计算应用(上)

原文:Integrate your Cloud Computing Apps with Salesforce.com, Java

作者:Andrew Lawlor

出处:http://www.devx.com/SaaS/Article/44382/0/page/1

 

目前的经济环境造成的压力要求减轻与开发和维护企业应用相关的费用,因此,许多组织正转向诸如来自Salesforce.comForce.com平台一类的云计算技术,以求降低成本并提升价值。

也许你没有听说过Force.com,其于2007年推出,用于帮助构建和实施云应用,其中包括数据库、用户接口、逻辑、工作流、移动和安全功能——全部由一个当前正为超过一千五百万用户提供十五万个应用的多用户共享内核来支持。

随着越来越多的组织机构开始了把他们的关键应用转移到云一端的进程,无论是因为制度上的偏执还是合法机构的监管要求,由于在基础设施方面的大量投资以及出于安全的原因,他们可能会决定保持机构内部的基础设施的一个子集。新的整合模式的出现使得许多应用在利用现有的基础设施的同时能够迁移到云一端。

本文举例说明了如何构建一种无缝安全地把来自机构内部基础设施的数据和服务整合到云应用中的聚合(mashup)。通过利用这一模式,组织机构可以在获得供应应用的云的多种好处的同时利用机构内部基础设施的敏感数据和现有可用的功能。作为一个说明性的例子,在Force.com应用的内部可无缝地调用一个用Java构建的机构内部服务和借助Apache Axis来启用的web service

 

整合架构

 

一个构建在Force.com平台上的基于云的应用可能需要访问和调用只由公司内部部署的基础设施提供的敏感数据和重要的业务逻辑。考虑一下传统的三层架构,整个表现层可以留驻在云一端,除了之前由组织机构开发的关键服务之外,业务逻辑层也存在于云一端。同样,数据层也位于云一端并处理应用用到的大部分数据,当需要敏感数据时,应用利用整合技术来访问驻留在机构内部的其他数据服务。下图展示了这一架构。

 

 



  

正如你所见到的那样,大部分的应用程序和功能都位于Force.com之上,一些数据和功能则位于企业内部网中,最终用户访问Force.com应用,该应用则相应地向机构内部的解决方案发出安全的调用。这并非是通过Java来整合Force.com的唯一方式,这不过是常见技术的一个说明,请参阅其他整合场景一节了解另外的一些可能情况。

 

整合的聚合

 

为了说Force.com平台的整合能力,这里展示一个来自理财行业的例子。华尔街的一家大型银行希望把它的理财CRM应用迁移到使用Force.com平台的云上。由于客户账户余额信息的敏感特性,该组织机构决定这部分信息必须保留在他们自己管理的机构内部的基础设施上,始终由他们来控制。所选择的架构把位于Force.com平台上的应用的大部分作为来自云一端的提供,并使用一个聚合来无缝安全地整合需要从组织机构内部的基础设施获取的账户余额信息。

该银行有一个使用Java构建的企业级的账户余额服务,该服务(的简化形式)返回给定账户号的当前余额。银行富有活力的面向服务架构(Service Oriented ArchitectureSOA)把这一服务外露出来,这样就可以通过Web使用标准的SOAP协议和安全认证来消费这一服务,安全地认证消费者确保了用户有权访问这样的敏感信息。Apache Axis被用作Web Service以启用这一Java服务,可以很安全地实施这一做法,例如,通过利用双向的SSL,以及把进来的IP地址范围限制为Force.com的地址范围等。

理财应用通过使用账户页面上的每项呈现实时地调用账户余额Web Service来显示账户余额。

Force.com平台使用常见的模型-视图-控制器(Model-View-ControllerMVC)模式来为用户显示内容。控制器包含了被用来与用户交互的业务逻辑,就这一应用来说, 一个用Apex 代码(Apex Code)编写的控制器扩展被用来调用外部的Web Service以检索当前的账户余额。这一例子中的模型则是Force.com标准和自定义对象(结构一类的丰富数据组合的Force.com术语)的组合。

 

JavaWeb Service托管

 

我们假设用Java实现的web service被托管在内联网中,位于Apache Axisweb service栈上,让我们稍加详细地考虑一下这一情况。

Java实现的账户余额服务,位于内联网上,有着以下特征:

 

<pre><code>public java.lang.String getAccountBalance(java.lang.String accountNumber)

 

该服务为指定的账户号(accountNumber)返回账户余额(accountBalance),如果账户号无效的话则返回“无效的账户号”这一信息,这一过程显然已经简化,但是阐明了要点。该服务访问机构内部的关系数据库以检索当前余额,不过既然服务的细节不是这一整合利用的中心问题,因此在这里就不展示这部分内容了。

为了让我们的基于云的理财应用访问这一机构内部的服务,该服务必须作为一个web service来提供,Apache Axis项目是一个非常受欢迎和成熟的包,被用来把Java方法外露成能够由任何有访问这一机构内部服务器权限的消费者调用的Web ServiceAxis提供了Java2WSDL这样一种功能来为任何指定的Java类文件产生一个标准兼容的WSDL文件,为了为我们的账户余额服务生成一个WSDL文件,在命令行中执行下面的语句:

 

Java2WSDL AccountService.java

 

这里的AccountService是包含了getAccountBalance()方法的类的名称,Axis将会生成几个Web Service用来支持我们的getAccountService方法的文件。对于我们的整合用例来说,最感兴趣的是生成的名为AccountService.wsdlWeb Service描述语言(Web Service Description LanguageWSDL)文件:

 

<?xml version="1.0" encoding="UTF-8"?>

<wsdl:definitions xmlns:tns2="http://AccountService" targetNamespace="http://AccountService">

    <!-- WSDL scheme type removed -->

  <wsdl:message name="getAccountBalanceRequest">

    <wsdl:part name="getAccountBalanceRequest" element="tns2:getAccountBalance"/>

  </wsdl:message>

  <wsdl:message name="getAccountBalanceResponse">

    <wsdl:part name="return" element="tns2:getAccountBalanceResponse"/>

  </wsdl:message>

  <wsdl:portType name="AccountServicePortType">

    <wsdl:operation name="getAccountBalance">

      <wsdl:input message="tns2:getAccountBalanceRequest"/>

      <wsdl:output message="tns2:getAccountBalanceResponse"/>

    </wsdl:operation>

  </wsdl:portType>

<!--wsdl binding removed -->

<wsdl:service name="AccountService">

    <wsdl:port name="AccountServicePort" binding="tns2:AccountServiceBinding">

      <soap:address location="https://aptaria.com:9081/AccountService/services/AccountServicePort"/>

    </wsdl:port>

  </wsdl:service>

 

可以注意到,这一WSDL标明了AccountService有一个Web ServicegetAccountBalance,该服务接受一个String类型的账户号(accountNumber),并返回一个String类型的账户余额(accountBalance),还需要注意的是,AccountService位于一个外部的域:aptaria.com之上,这一外部的预制式服务器上托管着我们的getBalanceService

现在AccountService已经在我们的机构内部基础设施上建立起来了,getAccountBalance方法已经作为Web Service启用(外露),现在我们可以专心于把这一关键功能整合到我们的Force.com理财应用中。

 

Force.comWeb Service调用

 

为了给用户显示账户的当前余额,我们必须配置理财应用,无论何时,只要账户页面在Force.com上被提交,就让应用执行一个到外部的Web Service的调用。本节着眼于如何配置Force.com对外部web service的调用,以及如何使用工具来自动生成调用web service的代码。

首先我们必须启用Force.com的网络安全设置以允许我们的应用向外调用Web Service,由于这是敏感信息,因此我们想确保只有可信任的机构内部基础设施才能与我们的基于云的应用相连接。Force.com平台可以配置成把所有外出的Web Service调用限制到某个特定的IP地址范围上,这就极大地降低了与伪造的或者恶意的AccountService接触的风险。

一旦标明了提供AccountServiceIP地址范围,进入你的组织(org(基于云的应用环境的Force.com术语)中的Force.comSetup菜单,并沿着菜单找到Administrative SetupSecurity ControlsNetwork Access,在这一页面中你可以输入安全的AccountService的起始(Starting)和终止(Ending)的IP地址。

下一步我们必须标明对于我们的应用来说是外部的Web Service,我们通过把生成的WSDL上传到Force.com来做到这一点。一旦完成了加载,外部的Web Service就能够被任何的Apex类(ApexForce.com平台编程语言的名称)调用。为了加载已生成的WSDL,进入到组织(org)的Setup菜单中,并进入子菜单App SetupApex Classes,在这一页面中选择通过WSDL生成(Generate from WSDL)按钮,然后提供之前生成的WSDL文件的位置,然后按下解析WSDLParse WSDL)按钮。

一旦WSDL文件已经加载,你就会发现有一个新的Apex类出现在Org:AccountService中,这一生成的类看起来类似于这样子:

 

//Generated by wsdl2apex

 

public class AccountService{

  public class getAccountBalance_element {

   /* 省略 */

  }

  public class getAccountBalanceResponse_element {

   /* 省略*/

  }    

  public class AccountServicePort {

      public String endpoint_x = 'https://aptaria.com:9081/AccountService/services/AccountServicePort';

        public String getAccountBalance(String accountNumber) {

         /* 省略 */

        }

  }

}

 

类在AccountServiceWSDL被加载时完全由Force.com平台自动生成,需要注意的是,变量endpoint_x标明了AccountServiceURL地址。WSDL2Apex的妙处在于我们自己不需要关心代码的细节,平台为我们处理调用getAccountBalanc这一Web Service的累人工作,所有我们需要做的就是调用公共方法getAccountBalance并传入一个String类型的账户号(accountNumber)。

 

Force.com应用的用户接口

 

现在AccountService是可用的了,而且平台已经知晓如何调用作为一个Web Service的这一服务,我们可以更新Force.com的金融账户界面以使用页面上的每一项呈现来调用服务。本节着眼于如何使用标记语言来显示数据。

为了做到这一点,我们使用Force.com平台的Visualforce标记语言,visualforce使用类HTML标记(实际上,更类似于Java Server faces的)来产生不同的可视化结构。在我们的例子中,我们需要显示来自getAccountBalance服务的返回值,通过这样一种方式,用户就不会知道余额是由外部的web service提供的。

以下是在我们的金融账户页面上用来显示账户余额的Visualforce

 

<apex:page standardController="Financial_Account__c" extensions="AccountServiceController">

    <apex:pageBlock >

        <apex:pageBlockSection columns="2" >

            <apex:pageBlockSectionItem >

                <apex:outputLabel value="Account Balance"></apex:outputLabel>

            </apex:pageBlockSectionItem>

            <apex:pageBlockSectionItem >

                <div id="AccountBalance">{!AccountBalance}</div>               

            </apex:pageBlockSectionItem>           

        </apex:pageBlockSection>

        <apex:pageBlockSection columns="2" >

        </apex:pageBlockSection>

 

    </apex:pageBlock>

</apex:page>

 

Visualforc的标记为标签“Account Balance”和变量{!AccountBalance}定义了一个两列的表。

Visualforce自动调用在当前的控制器中定义的get方法:getAccountBalance,该方法则实时调用外部的web service并返回用于显示给用户看的账户余额(AccountBalance)值。这就是聚合的秘诀所在,当标准控制器直接从Force.com的标准和自定义对象中抽取数据时,我们所需的账户余额并不能由云来提供,作为替代,我们整合机构内部的Web Service来提供所需的敏感信息,为此我们需要利用一个Apex控制器扩展。

 

 

[译文] 使用Safesforce.com和Java来整合云计算应用(下)