2012-11-13

multi mapping and split message with XSLT in SAP PI

应用场景是主数据的复制,从SAP到Salesforce,即:
SAP --RFC--> PI --SOAP-->Salesforce

在调用Salesforce的upsert时,一次最多只能包含200个对象,所以当PI接收到超过200个对象的数据时,需要把一个message分成多个messages,即1 --> n。Operation Mapping包括三个步骤:
  1. message mapping,从源数据结构映射到Salesforce的upsert结构
  2. Java mapping,从value mapping中取出有效的sessionID和serverURL,在dynamic configuration里设置相应的值
  3. XSLT mapping,生成多个SOAP request,每个request里的upsert包括最多200个objects,其中要注意output的结构和正确的namespace
在第三步要注意ouput的正确结构为
<message>
 <message1>
  <soapenv:Envelope>
   ...
  </soapenv:Envelope>
  <soapenv:Envelope>
   ...
  </soapenv:Envelope>
  </message1>
<message>

 上面的例子会被adapter正确的解释成2个messages。

如果XSLT生成的结构像下面这样:

<message>
 <message1>
  <soapenv:Envelope>
  ...
  </soapenv:Envelope>
 </message1>
  <message1>
  <soapenv:Envelope>
   ...
  </soapenv:Envelope>
  </message1>
<message>

那么在monitoring里会得到下面的错误:

<SAP:Category>XIServer</SAP:Category>
  <SAP:Code area="MAPPING">MISSING_INTERFACE</SAP:Code>
  <SAP:P1>2</SAP:P1>
  <SAP:P2 />
  <SAP:P3 />
  <SAP:P4 />
  <SAP:AdditionalText />
  <SAP:Stack>No interface specified for parameter 2</SAP:Stack>


在测试时还需注意,如果是在Repository(design time)里测试operation mapping或message mapping,source input里需要构造
<message> <message1> ...</message1><message>这样的结构,但是在directory里或RWB(runtime)里测试时,payload里都不应该出现<message> <message1> ...</message1></message>这样的结构,否则会得到类似下面的错误:
sap.aii.mappingtool.tf7.IllegalInstanceException: Cannot create target element /ns0:Messages. Values missing in queue context.
第3步的XSLT:

<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:urn="urn:enterprise.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://pi.cceag.de/SFDC" xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">
    <xsl:output indent="yes" method="xml"/>
    <xsl:template match="/">
        <ns0:Messages>
        <ns0:Message1>
            <xsl:for-each select="//sObjects[position() mod 200 = 1]">
                    <soapenv:Envelope>
                        <xsl:call-template name="header"/>
                        <soapenv:Body>
                            <urn:upsert>
                                <externalIDFieldName>
                                    <xsl:value-of select="//upsert/externalIDFieldName"/>
                                </externalIDFieldName>
                                <xsl:for-each select=". | following-sibling::sObjects[position() &lt; 200]">
                                    <xsl:call-template name="sObjects" />
                                </xsl:for-each>
                            </urn:upsert>
                        </soapenv:Body>
                    </soapenv:Envelope>
            </xsl:for-each>
         </ns0:Message1>       
        </ns0:Messages>
    </xsl:template>

    <xsl:template match="soapenv:Header" name="header">
        <xsl:copy-of select="/soapenv:Envelope/soapenv:Header"/>
    </xsl:template>

    <xsl:template match="sObjects" name="sObjects">
        <urn:sObjects xsi:type="Account">
        <xsl:for-each select="./*">
            <xsl:element name="{local-name()}">
                <xsl:value-of select="./text()" />
            </xsl:element>
         </xsl:for-each>
         </urn:sObjects>
    </xsl:template>
</xsl:stylesheet>

使用PI 7.1生成WSDL

在SOAP2IDOC场景下,发送方的adaper为SOAP,PI能为调用web service的第三方提供WSDL。生成WSDL有两种方式,一种是通过Sender Agreement,另一种是通过Integration Repository –> Tools -> Display WSDL菜单。其中前者要求调用者提供访问PI的用户名和密码,而后者则无需提供。

Recently I had a requirement from third party system, to send message to PI without user name and password.

We having the scenario SOAP to IDOC. In sender side SOAP adapter and in IDOC as the receiver. I have developed the Interface and tested using SOAP test tool. After my testing I had send the WSDL to the thirdparty SaaS system. They told that they can't use this WSDL and use the URL end point instead. But here is the problem. Their Even Brocker system can't call the PI webservice with User ID and Password. They want webservice URL which should not have any user credential requirement.

As the SOAP adapter in PI requires the user ID and password to send message to PI. The normal way of extracting WSDL at the Sender Agreement level (Display WSDL) use Adapter Engine to send message and it requires user credentials.

Solution

Go to

Integration Repository –> Tools -> Display WSDL

This will popup another window.

Press the continue button and click on the button propose URL.

http://<server>:<port>/sap/xi/engine?type=entry

Then click continue and specify Interface and Specify Sender and finally save the WSDL to your computer.

2012-11-12

动态设定SAP PI SOAP Receiver的目的地

一些主数据需要从SAP发到Salesforce,receiver channel使用SOAP adapter。因为Salesforce的loadbalancer,调用Salesforce web service的URL有可能变动,所以不能在receiver channel里静态设定目的地URL,而需要在dynamic configuration里动态设定key为TServerLocation的值。要使动态设定的值生效,需要两点:
  • 如果channel里给定的URL是一个有效的URL,那么这个静态的URL会被adapter使用,而不是dynamic configuration里的值
  • 如果dynamic configuration里的URL使用HTTP协议,那么channel里的相应设定必须为http://,如果动态设定的URL为HTTPS,那么channel里相应的设置为https://.
在message mapping中可以使用下面的UDF来设定。
public String setSoapURL(String url, Container container) throws StreamTransformationException{
        String namespace = "http://sap.com/xi/XI/System/SOAP";
        String parameterKey = "TServerLocation";
        DynamicConfiguration conf = (DynamicConfiguration) container.getTransformationParameters().get(    StreamTransformationConstants.DYNAMIC_CONFIGURATION);
        DynamicConfigurationKey key = DynamicConfigurationKey.create(namespace, parameterKey);
        if (conf != null) {
            conf.put(key, url);           
        }
        return ""; 
  }

2012-11-03

卸载Adobe Acrobat出错



卸载Adobe Acrobat X程序时,总是报错1324,说Path Contains an Invalid Character(路径中包含无效字符)或multifonction.sequ
日志报告显示错误来自于MircrosoftMsiInstaller
Event Type:       Error
Event Source:   MsiInstaller
Event Category:               None
Event ID:             11324

For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.
Data:
0000: 7b 41 43 37 36 42 41 38   {AC76BA8
0008: 36 2d 31 30 33 33 2d 46   6-1033-F
0010: 34 30 30 2d 37 37 36 30   400-7760
0018: 2d 30 30 30 30 30 30 30   -0000000
0020: 30 30 30 30 35 7d         00005} 

发现这个键值{AC76BA86-1033-F400-7760-000000000005}正好是Acrobat安装路径下Setup Files下文件夹的名字里面有Acrobat 10的完整安装文件。
微软早期曾提供一个名为Windows Installer CleanUp utility的小工具来解决安装或卸载程序时出现的问题不过现在被名为program install und uninstall troubleshooterhttp://support.microsoft.com/mats/Program_Install_and_Uninstall 的工具所替代。网上下载之后运行了估计约一刻钟才显示修复了卸载问题。不过原来的程序文件并未被移除,只是在安装的程序列表里没有了。