Difference between revisions of "ZSI Examples"

From PeformIQ Upgrade
Jump to navigation Jump to search
 
(18 intermediate revisions by the same user not shown)
Line 1: Line 1:
= Some ZSI Examples =
=Some Python ZSI Examples=


== CDPBilling ==
==Document Injection Example==


A Python script using the Zolera SOAP Infrastructure was implemented which allowed arbitrary combinations of orders to be generated.  This script was run from the command line with arguments specifying the required attributes of order set. It dynamically generated an order cluster with randomized data, injected this into the web tier and captured and parsed the return response into a log file along with various timings.
[[Python SOAP - Document Injection Example]]


Follow these links to view the submit script (do.py) and component ZSI generated modules:
==SaintBook==


<pre>
$ cat wsdl.sh
#!/bin/sh


== do.py ==
wget http://saintbook.org/MightyMaxims/MightyMaxims.asmx?WSDL
</pre>


The following WSDL was used to generate the Python scripts attached below:
<pre>
from ZSI.wstools import WSDLTools


* [http://www.performiq.com.au/kb/images/CDPBilling.wsdl CDPBilling.wsdl]
...


The injection script (do.py) and required components (generated by wsdl2py) are attached here:
location = 'http://saintbook.org/MightyMaxims/MightyMaxims.asmx?WSDL'


* [http://www.performiq.com.au/kb/images/Do_submit.py do.py]
load = reader.loadFromURL
* [http://www.performiq.com.au/kb/images/CDPBilling_serviceagent_services.py Services]
* [http://www.performiq.com.au/kb/images/CDPBilling_serviceagent_services_types.py Services_Types]
* [http://www.performiq.com.au/kb/images/customer_data.zip Customer Data]


One of the gotchas was that I had to modify the ZSI site package to turn off the addition of the type explicitly to each elent of the XML. When this was enabled - as by default setup - the injected XML was rejected by the TIBCO interface. Source for modified ZSI site-package is attached at:
wsdl = load(location)
...
</pre>


* [http://www.performiq.com.au/kb/images/ZSI_site_package.tz ZSI Site Package]
Not sure works for me
-josh


<pre>
<pre>
#!/usr/bin/env python
$ mkdir TMP
#
$ cd TMP/
#
$ wsdl2py http://saintbook.org/MightyMaxims/MightyMaxims.asmx?WSDL
#
$ ls
#-------------------------------------------------------------------------------
Maxim_client.py Maxim_server.py Maxim_types.py


from CDPBilling_serviceagent_services import *
$ python
Python 2.5.1 (r251:54863, May 23 2007, 10:06:54)
[GCC 4.0.0 20041026 (Apple Computer, Inc. build 4061)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from ZSI.wstools import WSDLTools
>>> location = 'http://saintbook.org/MightyMaxims/MightyMaxims.asmx?WSDL'
>>> w = reader.loadFromURL(location)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'reader' is not defined


from ZSI import FaultException, Fault
>>> reader = WSDLTools.WSDLReader()
>>> w = reader.loadFromURL(location)
>>> w
<ZSI.wstools.WSDLTools.WSDL instance at 0xca080>
</pre>


import ZSI


import os
import re
import csv
import sys
import time
import getopt
import random
import socket
import pprint
import pickle
import traceback


import types
<pre>
import pprint
On Jan 31, 2008, at 7:49 AM, Lorena Carlo wrote:


import xml.dom.minidom
> Hi,
>
> I don't know if this is a ZSI bug, but for some reason I can not load
> the following webservice:
>
> http://saintbook.org/MightyMaxims/MightyMaxims.asmx?WSDL
>
> This is the portion of code:
>
> from ZSI.wstools import WSDLTools
> location = 'http://saintbook.org/MightyMaxims/MightyMaxims.asmx?WSDL'
> load = reader.loadFromURL
> wsdl = load(location)
>
> This is the exception I get:
>
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> File
> "c:\Python24\lib\site-packages\zsi-2.1_a1-py2.4.egg\ZSI\wstools
> \WSDLTools
> .py", line 39, in loadFromURL
> File
> "c:\Python24\lib\site-packages\zsi-2.1_a1-py2.4.egg\ZSI\wstools
> \Utility.p
> y", line 642, in loadFromURL
> File
> "c:\Python24\lib\site-packages\zsi-2.1_a1-py2.4.egg\ZSI\wstools
> \Utility.p
> y", line 203, in urlopen
> File
> "c:\Python24\lib\site-packages\zsi-2.1_a1-py2.4.egg\ZSI\wstools
> \Utility.p
> y", line 153, in urlopen
> File "c:\Python24\lib\urllib.py", line 82, in urlopen
>  return opener.open(url)
> File "c:\Python24\lib\urllib.py", line 190, in open
>  return getattr(self, name)(url)
> File "c:\Python24\lib\urllib.py", line 426, in open_file
>  return self.open_local_file(url)
> File "c:\Python24\lib\urllib.py", line 440, in open_local_file
>  raise IOError(e.errno, e.strerror, e.filename)
> IOError: [Errno 2] No such file or directory:
> '\\MightyMaxims\\MightyMaxims.asmx
> ?WSDL?65784000'
>
> Any help will be appreciated, thanks!
>
> Lorena
</pre>


# from xml.dom.utils import FileReader
=Building Complex Type Arrays=
from string import join, split   
from datetime import datetime, timedelta
from time import strptime


#-------------------------------------------------------------------------------
<pre>
So grab an interpreter and import the generated module, then use 
help() to look at the request you're trying to use.  You'll probably 
see some helper methods and properties in there,


__version__        = '1.2.0'
new_
set_
get_


debug_flg          = False
If that doesn't help provide the WSDL
verbose_flg        = False
sundry_flg        = False


no_sundries        = 0
-josh
cnt_requests      = 0
</pre>
log                = None


ServiceURL        = "http://hx418:10000/Services/CDPBilling"  # Is retrieved from WSDL
On Feb 6, 2008, at 7:51 AM, Joseph Boiteau wrote:


notification_email = 'peter.harding@auspost.com.au'
<pre>
> Hi,
>
> I'm using a ZSI client interface generated with  --complexType 
> option (ZSI 2.0)
> When I try to construct a request properly, I cannot find a nice way 
> to instantiate the array object.
>
> A simple list [] seems to correspond to the array, but then I have 
> no parent object to instantiate an array element..
>
> Using the second generated file (*_services_types.py), the element i 
> get using ns0.myDef_Def(None) is a basic object.. without specific 
> attributes or methods I need.
>
> So I'm looking after the manner to instantiate properly any sub-node 
> object.
>
> Thanks
</pre>


cdp_defaults      = {
=Nilable Types=
                        'AaE'    : ['APCBE', 'AAE PSft', 1,  'SVT-A-%06d', 0],
                        'MPC'    : ['APCBE', 'MPVIC', 1,  'SVT-M-%06d', 0],
                        'XXX'    : ['XXXXX', 'XXXX', 1,  'SVT-X-%06d', 0]
                    }


cdpId              = 'AaE'
<pre>
cdp_details        = None
a nilled element looks like this:
service_header    = None
no_orders          = 1


dt_order          = None
  <whatever xsi:nil="true"/>
dt_request        = None


cdp_data_pickle    = "cdp.pickle"


add_performance    = True
So it should be present if it is minOccurs=1


#===============================================================================
-josh


class CDP:
On Feb 7, 2008, at 11:32 AM, Rex Corrovan wrote:
  pass


  def __init__(self, cdpID):
      self.cdpID          = cdpID
      self.consortiumID    = cdp_details[cdpID][0]
      self.sourceSystemID  = cdp_details[cdpID][1]
      self.sequenceID      = cdp_details[cdpID][2]
      self.OrderNoFmt      = cdp_details[cdpID][3]
      self.OrderNo        = cdp_details[cdpID][4]
      self.customer        = []


  def get_order_number(self):
Hey all,
      order_number                = self.OrderNo
      self.OrderNo              += 1
      cdp_details[self.cdpID][4]  = self.OrderNo
      return order_number


#===============================================================================
Been using ZSI a while now, and came across a 'Bad Thing&trade;'. I would get an exception that 'Required <type> missing' any time I would make certain requests.


class Customer:
Upon further investigation I realized that if the WSDL I was using had nillable=true, and minOccurs=1 ZSI, and more specifically TC.py, would throw this exception if the server returned an empty element. In this case an Empty element is valid because nillable is true, and the server HAS to return this tag simply because it has minOccurs of 1.
  pass


  def __init__(self, m):
Anyway, the fix was not to hard, on line (note: I also added the space after 'Required ' in the exception string for a better looking message)
      self.apAccountNumber  = int(m[0])
      self.cdpAccountNumber = int(m[1])
      self.cdpCustomerID    = int(m[2])
      self.cdpCustomerName  = m[3]
      self.workCentreID    = int(m[4])
      self.order            = []


  def __str__(self):
from original Line 153:
      str = """
        if not href:
      apAccountNumber  = %d
            if self.minOccurs is 0: return None
      cdpAccountNumber = %d
            raise EvaluateException('Required' + tag + ' missing',
      cdpCustomerID    = %d
                    ps.Backtrace(elt))
      cdpCustomerName  = '%s'
      """ % (
              self.apAccountNumber,
              self.cdpAccountNumber,
              self.cdpCustomerID,
              self.cdpCustomerName
            )


      for o in self.order:
        str += """
      Order:\n"""
        str += o.__str__()


      return str
To my patched version:
        if not href:
            if self.minOccurs is 0: return None
            if self.minOccurs is 1 and self.nillable is True: return None
            raise EvaluateException('Required ' + tag + ' missing',
                    ps.Backtrace(elt))
</pre>


#===============================================================================
=Namespaces=


class Order:
<pre>
  pass
This is the wsdl for the above service:


  def __init__(self, cdp, customer):
<?xml version="1.0" encoding="UTF-8"?><!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.2_01-hudson-189-. --><!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.2_01-hudson-189-. --><definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://services/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://services/" name="testserviceService">
      self.orderID            = cdp.OrderNoFmt % cdp.get_order_number()
<wsp:UsingPolicy></wsp:UsingPolicy>
      self.orderStatus        = None
<wsp:Policy wsu:Id="testservicePortBinding_testMethod_WSAT_Policy">
      self.orderDateTime      = dt_order.timetuple()
<wsp:ExactlyOne>
      self.readyDateTime      = (dt_order + timedelta(days=1)).timetuple()
<wsp:All>
      self.invoiceDateTime    = (dt_order + timedelta(days=2)).timetuple()
<ns1:ATAlwaysCapability xmlns:ns1="http://schemas.xmlsoap.org/ws/2004/10/wsat" wsp:Optional="false"></ns1:ATAlwaysCapability>
      self.numberOfItems      = 1
<ns2:ATAssertion xmlns:ns3="http://schemas.xmlsoap.org/ws/2002/12/policy" xmlns:ns2="http://schemas.xmlsoap.org/ws/2004/10/wsat" ns3:Optional="true" wsp:Optional="true"></ns2:ATAssertion>
      self.workCentreID        = customer.workCentreID
</wsp:All>
      self.CustomerReference  = None
</wsp:ExactlyOne>
      self.OrderReference      = None
</wsp:Policy>
      self.PickUpAddress      = None
<types>
      self.DeliveryAddress    = None
<xsd:schema>
      self.Weight              = None
<xsd:import namespace="http://services/" schemaLocation="http://localhost:8080/testserviceService/testservice?xsd=1"></xsd:import>
      self.Dimension          = None
</xsd:schema>
      self.Performance        = None
</types>
      self.Service            = []
<message name="testMethod">
<part name="parameters" element="tns:testMethod"></part>
</message>
<message name="testMethodResponse">
<part name="parameters" element="tns:testMethodResponse"></part>
</message>
<portType name="testservice">
<operation name="testMethod">
<input message="tns:testMethod"></input>
<output message="tns:testMethodResponse"></output>
</operation>
</portType>
<binding name="testservicePortBinding" type="tns:testservice">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"></soap:binding>
<operation name="testMethod">
<wsp:PolicyReference URI="#testservicePortBinding_testMethod_WSAT_Policy"></wsp:PolicyReference>
<soap:operation soapAction=""></soap:operation>
<input>
<soap:body use="literal"></soap:body>
</input>
<output>
<soap:body use="literal"></soap:body>
</output>
</operation>
</binding>
<service name="testserviceService">
<port name="testservicePort" binding="tns:testservicePortBinding">
<soap:address location="http://localhost:8080/testserviceService/testservice"></soap:address>
</port>
</service>
</definitions>
</pre>


  def __str__(self):
(This code directly incooperates an EJB, but without this, directly having the code in the WebMethod shows the same result.)
      str = """
        orderID            = %s
        orderDateTime      = %s
        readyDateTime      = %s
        invoiceDateTime    = %s
        numberOfItems      = %d
        workCentreID        = %d
      """ % (
        self.orderID,
        self.orderDateTime,
        self.readyDateTime,
        self.invoiceDateTime,
        self.numberOfItems,
        self.workCentreID
      )
      return str


Using wsdl2py I got:


#===============================================================================
<pre>
wn@omega:~$ wsdl2py --url http://localhost:8080/testserviceService/testservice?wsdl
Error loading http://localhost:8080/testserviceService/testservice?wsdl:
namespace of schema and import match
wn@omega:~$
</pre>


class CustomerReference:
Using the ServiceProxy module directly in the code shows the same result.
  pass


  def __init__(self, cdp):
      self.customerCostCentre    = '%06d' % random.randint(100000,200000)
      self.otherCustomerRef      = '%s%05d' % (cdp.cdpID, random.randint(10000,99999))
      self.otherCustomerRefDesc  = 'Consignment Note Number'


  def __str__(self):
Could someone give me a hint what's wrong here?
      return "CustomerReference"


#===============================================================================
==wsdl2py Example==
certainly it is a stupid failure, but I'm unable to bring it to work: a WebService provider coded using Netbeans with J2EE 1.5 and the client with ZSI:


class OrderReference:
  pass


  def __init__(self, m):
<pre>
      self.orderRef1              = 'M%08d' % random.randint(10000000,99999999)
wn@omega:~$ wsdl2py --url http://localhost:8080/testserviceService/testservice?wsdl
      self.orderRef1Desc          = 'Manifest Number'
Error loading http://localhost:8080/testserviceService/testservice?wsdl:
      self.orderRef2              = 'R%05d' % random.randint(10000,99999)
namespace of schema and import match
      self.orderRef2Desc          = 'Run Number'
wn@omega:~$
      self.orderRef3              = 'J%06d' % random.randint(100000,999999)
</pre>
      self.orderRef3Desc          = 'Job Number'


  def __str__(self):
      return "OrderReference"


#===============================================================================
Using the ServiceProxy module directly in the code shows the same result.


class Address:
  pass


  def __init__(self, m):
From your wsdl .....
      # addr = get_address()
      self.address1    = m[0]
      self.address2    = m[1]
      self.address3    = m[2]
      self.address4    = m[3]
      self.suburb      = m[4]
      self.state      = m[5]
      self.postcode    = m[6]
      self.country    = m[7]


  def __str__(self):
<pre>
      str = "       Address: %s," % self.address1,
  <xsd:import namespace="http://services/" schemaLocation="http://localhost:8080/testserviceService/testservice?xsd=1"></xsd:import>
      if self.address2:
</pre>
        str += "%s, " % self.address2
      if self.address3:
        str += "%s, " % self.address3
      str += "%s, %s, %s" % (
        self.suburb,
        self.postcode,
self.state
      )
      return str


#===============================================================================
===sugarsoap - Client 1===


class Weight:
<pre>
  pass
$ cat run.py
#!/usr/bin/env python


  def __init__(self, w):
from sugarsoap_services import *
      self.entryWeight  = w
import md5
      self.cubedWeight  = w
import sys
      self.actualWeight = w


  def __str__(self):
def main():
      return "Weight: %d" % (self.entryWeight)
    loc = sugarsoapLocator()


#===============================================================================
    portType = loc.getsugarsoapPortType(tracefile=sys.stdout)


class Dimension:
    request = loginRequest()
  pass
    request._user_auth = uauth = request.new_user_auth()
    request._application_name='appname'


  def __init__(self, d):
    uauth._user_name ='admin'
      self.height          = d
    uauth._password  = md5.new('password').hexdigest()
      self.length          = d
    uauth._version = '1.1'
      self.width          = d


  def __str__(self):
    response = portType.login(request)
      return "Dimensions: %d x %d x %d" % (self.height, self.length, self.width)


#===============================================================================
    print response._return
    print response._return._id
    print response._return._error._name


class Performance:
if "__main__" == __name__:
  pass
    main()
</pre>


  def __init__(self):
===sugarsoap - Client 1===
      t_pickup_sched    = dt_order + timedelta(hours=2)
      t_pickup_actual  = t_pickup_sched + timedelta(minutes=30)
      t_delivery_sched  = t_pickup_sched + timedelta(hours=1)
      t_delivery_actual = t_delivery_sched + timedelta(minutes=30)


      self.schedPickUpDateTime        = t_pickup_sched.timetuple()
<pre>
      self.pickupSignatureRequired    = False
$ cat run.py
      self.pickupSignatureReceived    = False
#!/usr/bin/env python
      self.actualPickUpDateTime      = t_pickup_actual.timetuple()
      self.latePickUpIndicator        = False
      self.pickUpTimeliness          = -1
      self.schedDeliveryDateTime      = t_delivery_sched.timetuple()
      self.deliverySignatureRequired  = True
      self.deliverySignatureReceived  = True
      self.actualDeliveryDateTime    = t_delivery_actual.timetuple()
      self.lateDeliveryIndicator      = True
      self.deliveryTimeliness        = 7


  def __str__(self):
from sugarsoap_services import *
      return "Performance:"
import md5
import sys


#===============================================================================
def main():
    loc = sugarsoapLocator()


class Service:
    portType = loc.getsugarsoapPortType(tracefile=sys.stdout)
  pass


  # serviceCodeSet,serviceType,serviceArea,serviceCode,serviceDesc,apProductCode
    request = loginRequest()
    request._user_auth = uauth = request.new_user_auth()
    request._application_name='appname'


  def __init__(self, m):
    uauth._user_name ='admin'
      self.serviceCodeSet    = m[0]
    uauth._password  = md5.new('password').hexdigest()
      self.serviceType      = m[1]
     uauth._version = '1.1'
      self.serviceArea      = m[2]
      self.serviceCode      = m[3]
      self.serviceDesc      = m[4]
      self.apProductCode     = m[5]
      self.deliveryDistance  = None
      self.charge            = []


      if  self.apProductCode == '':
    response = portType.login(request)
        self.apProductCode = None


  def __str__(self):
    print response._return
      return "%s,%s,%s" % (self.serviceType, self.serviceArea,self.serviceCodeSet)
    print response._return._id
    print response._return._error._name


#===============================================================================
if "__main__" == __name__:
    main()
</pre>


class Charge:
certainly it is a stupid failure, but I'm unable to bring it to work: a WebService provider coded using Netbeans with J2EE 1.5 and the client with ZSI:
  pass


  def __init__(self, cdp, m):
      self.transactionID      = '%s%06d' % (cdp.cdpID[0:1], random.randint(100000,999999))
      self.transactionType    = m[0]
      self.chargeType          = m[1]
      self.chargeCode          = m[2]
      self.chargeCodeDesc      = m[3]
      self.priceCharged        = float(m[4])
      self.taxCode            = m[5]


  def __str__(self):
<pre>
      return "%s,%s,%s,%s" % (
wn@omega:~$ wsdl2py --url http://localhost:8080/testserviceService/testservice?wsdl
        self.chargeType,
Error loading http://localhost:8080/testserviceService/testservice?wsdl:
        self.chargeCode,
namespace of schema and import match
        self.chargeCodeDesc,
wn@omega:~$
        self.priceCharged
</pre>
      )


#===============================================================================
#----- Read in Account address info ---------------------------------------


class Addresses:
Using the ServiceProxy module directly in the code shows the same result.
  pass


  #-------------------------------------------------------------


  def __init__(self, carrier):
From your wsdl .....
      self.addresses = []


      file = 'dat/%s/Address.csv' % carrier.cdpID
<pre>
  <xsd:import namespace="http://services/" schemaLocation="http://localhost:8080/testserviceService/testservice?xsd=1"></xsd:import>
</pre>


      f_in  = open(file, "r")
===sugarsoap - Client 1===


      reader = csv.reader(f_in)
<pre>
$ cat run.py
#!/usr/bin/env python


      for row in reader:
from sugarsoap_services import *
        if re.search('#', row[0]):
import md5
            continue
import sys
        self.addresses.append(Address(row))


      f_in.close() # Explicitly close the file *NOW*
def main():
    loc = sugarsoapLocator()


      self.no_addresses = len(self.addresses)
    portType = loc.getsugarsoapPortType(tracefile=sys.stdout)


      if debug_flg: print "Read in %d addresses" % self.no_addresses
    request = loginRequest()
    request._user_auth = uauth = request.new_user_auth()
    request._application_name='appname'


  #-------------------------------------------------------------
    uauth._user_name ='admin'
    uauth._password  = md5.new('password').hexdigest()
    uauth._version = '1.1'


  def Get(self):
    response = portType.login(request)
      idx = random.randint(0, self.no_addresses - 1)


      return self.addresses[idx]
    print response._return
    print response._return._id
    print response._return._error._name


  #-------------------------------------------------------------
if "__main__" == __name__:
    main()
</pre>


  def GetPair(self):
An import's namespace must match the targetNamespace attribute of the "file" or schema being imported.
      idx1 = random.randint(0, self.no_addresses - 1)


      while True:
But this namespace must be different than the namespace of the schema you are importing it into.
        idx2 = random.randint(0, self.no_addresses - 1)
        if idx1 != idx2:
            break


      return (self.addresses[idx1], self.addresses[idx2])
<pre>
//
<schema targetNamespace="urn:1">


#===============================================================================
<import namespace="urn:2" schemaLocation="importFile.xsd:/>


class Charges:
// importFile.xsd
  pass
<schema targetNamespace="urn:2">
...
</pre>


  #-------------------------------------------------------------
-josh
</pre>


  def __init__(self, carrier):
==Nusoap==
      self.values = []


      file = 'dat/%s/Charge.csv' % carrier.cdpID
<pre>
from ZSI import *
pyobj = [ 1, 2.0, 'a', ['b', 1.0], [(4,'a'), (5, 'c')] ],
sw = writer.SoapWriter()
sw.serialize(pyobj, typecode=Any(), unique=True)
str(sw)


      f_in  = open(file, "r")


      reader = csv.reader(f_in)
import sys
cli = client.Binding(url='', tracefile=sys.stdout)
rsp = cli.whatever(pyobj)


      for row in reader:
        if re.search('#', row[0]):
            continue
        self.values.append(Charge(carrier, row))


      f_in.close() # Explicitly close the file *NOW*
Re: ZSI client, Nusoap server - data format trouble?
Subject: Re: ZSI client, Nusoap server - data format trouble?
List-id: Discussion of Python and Web services <pywebsvcs-talk.lists.sourceforge.net>
ZSI-1.7 (or whatever) is corrupting the XML instance by using the default namespace, I think if you use ZSI-2.* or svn it will work.


      self.no_values = len(self.values)
-josh
</pre>


      if debug_flg: print "Read in %d charges" % self.no_values
==sugarsoap==


  #-------------------------------------------------------------
===sugarsoap - Client===


  def Get(self):
<pre>
      idx = random.randint(0, self.no_values - 1)
$ cat run.py
#!/usr/bin/env python


      return self.values[idx]
from sugarsoap_services import *
import md5
import sys


#===============================================================================
def main():
    loc = sugarsoapLocator()


class Charges_Sundry:
    portType = loc.getsugarsoapPortType(tracefile=sys.stdout)
  pass


  #-------------------------------------------------------------
    request = loginRequest()
    request._user_auth = uauth = request.new_user_auth()
    request._application_name='appname'


  def __init__(self, carrier):
    uauth._user_name ='admin'
      self.values = []
    uauth._password  = md5.new('password').hexdigest()
    uauth._version = '1.1'


      file = 'dat/%s/Charge_Sundry.csv' % carrier.cdpID
    response = portType.login(request)


      f_in  = open(file, "r")
    print response._return
    print response._return._id
    print response._return._error._name


      reader = csv.reader(f_in)
if "__main__" == __name__:
    main()
</pre>
   
===sugarsoap - Client 2===


      for row in reader:
<pre>
        if re.search('#', row[0]):
#!/usr/bin/env python
            continue
        sundry = Charge(carrier, row)
        print sundry
        self.values.append(sundry)


      f_in.close()  # Explicitly close the file *NOW*
from sugarsoap_services import *


      self.no_values = len(self.values)
import md5
import sys


      print "Read in %d sundry charges" % self.no_values
def main():
      if debug_flg: print "Read in %d sundry charges" % self.no_values
    loc = sugarsoapLocator()


  #-------------------------------------------------------------
    portType = loc.getsugarsoapPortType(tracefile=sys.stderr)


  def Get(self):
    uauth = ns1.user_auth_Def()
      idx = random.randint(0, self.no_values - 1)
    uauth._user_name ='admin'
    uauth._password  = md5.new('password').hexdigest()
    uauth._version = '1.1'


      return self.values[idx]
    request = loginRequestWrapper()
    request._user_auth = uauth
    request._application_name='appname'


#===============================================================================
    response = portType.login(request)


class Customers:
    print response._return
  pass
    print response._return._id
    print response._return._error._name


  #-------------------------------------------------------------
if "__main__" == __name__:
    main()
</pre>


  def __init__(self, carrier):
=Authentication and Zimbra=
      self.values = []


      file = 'dat/%s/Customer.csv' % carrier.cdpID
<pre>
 
I posted recently about type problems when using ZSI with a service (Zimbra
      f_in  = open(file, "r")
Collaboration Suite, or ZCS) that does not have WSDL available:
 
      reader = csv.reader(f_in)
 
      for row in reader:
        if re.search('#', row[0]):
            continue
        self.values.append(Customer(row))
 
      f_in.close()  # Explicitly close the file *NOW*
 
      self.no_values = len(self.values)
 
      if debug_flg: print "Read in %d Customers" % self.no_values
 
  #-------------------------------------------------------------
 
  def Get(self):
      idx = random.randint(0, self.no_values - 1)
 
      return self.values[idx]
 
#===============================================================================
 
class Services:
  pass
 
  #-------------------------------------------------------------
 
  def __init__(self, carrier):
      self.values = []
 
      file = 'dat/%s/Service.csv' % carrier.cdpID
 
      if debug_flg: print "Using -- %s" % file
 
      f_in  = open(file, "r")
 
      reader = csv.reader(f_in)
 
      for row in reader:
        if re.search('#', row[0]):
            continue
        s = Service(row)
        # print s
        self.values.append(s)
 
      f_in.close()  # Explicitly close the file *NOW*
 
      self.no_values = len(self.values)
 
      if debug_flg: print "Read in %d services" % self.no_values
 
  #-------------------------------------------------------------
 
  def Get(self):
      idx = random.randint(0, self.no_values - 1)
 
      self.values[idx].charge = []
 
      return self.values[idx]
 
#===============================================================================
 
#-------------------------------------------------------------------------------
 
def load_cdp_data():
  global cdp_details
 
  try:
      pf = open(cdp_data_pickle, "r")
  except IOError, msg:
      sys.stderr.write('%s: cannot open: %s\n' % (cdp_data_pickle, msg))
      cdp_details = cdp_defaults
      return
 
  u  = pickle.Unpickler(pf)
 
  cdp_details = u.load()
 
  pf.close()
 
  return
 
#-------------------------------------------------------------------------------
 
def save_cdp_data():
 
  try:
      pf = open(cdp_data_pickle, 'w')
  except IOError, msg:
      sys.stderr.write('%s: cannot open: %s\n' % (cdp_data_pickle, msg))
      sys.exit(1)
 
  p = pickle.Pickler(pf)
 
  p.dump(cdp_details)
 
  pf.close()
 
#-------------------------------------------------------------------------------
 
def generate_orders(cdp, no_orders=1, debug=None):
  #----- Create data constructors ---------------------------------------------
 
  customers        = Customers(cdp)
  addresses        = Addresses(cdp)
  charges          = Charges(cdp)
  services        = Services(cdp)
 
  if sundry_flg:
      sundry_charges = Charges_Sundry(cdp)
 
  customer_list = []
 
  customer        = customers.Get()
 
  customer_list.append(customer)
 
  for order_idx in range(no_orders):
      order    = Order(cdp, customer)
 
      customer.order.append(order)
 
      order.CustomerReference = CustomerReference(cdp)
 
      (order.PickUpAddress, order.DeliveryAddress) = addresses.GetPair()
 
      order.Weight        = Weight(random.randint(100,3000))
      order.Dimension      = Dimension(random.randint(10,99))
      order.Service        = services.Get()
 
      if add_performance:
        order.Performance = Performance()
 
      order.Service.charge.append(charges.Get())
 
      if sundry_flg:
        for i in range(no_sundries):
            order.Service.charge.append(sundry_charges.Get())
 
      print "Len Charges - %d" % len(order.Service.charge)
 
  print customer
 
  return customer_list
 
#----- Construct the Service Header --------------------------------------------
 
def create_header(debug=None):
 
  reqInfo = ns1.RequestorInfo_Def('RequestorInfo').pyclass()
 
  reqInfo._ComponentID            = 'Test'
  reqInfo._ComponentName          = 'Test Application'
 
  service_header = ESBSvcHeader()
 
  #service_header._SvcName        = 'receiveCDPBilling'
  service_header._SvcName        = 'CDPBilling-receiveBilling'
  service_header._SvcVersion      = '1.0'
  service_header._RequestDt      = dt_request.timetuple()
  service_header._RequestorInfo  = reqInfo
 
  if (debug): print service_header.__dict__
 
#-------------------------------------------------------------------------------
 
def create_request(cdp, customers, debug=None):
  global dt_request
  global service_header
 
  dt_request = datetime.now()
 
  log.write("============================================================")
  log.write("%s INFO Start new request" % dt_request.strftime("%Y-%m-%d %H:%M:%S"))
 
 
  request = None
 
  #----- Construct the Service Header -----------------------------------------
 
  reqInfo = ns1.RequestorInfo_Def('RequestorInfo').pyclass()
 
  reqInfo._ComponentID            = 'Test'
  reqInfo._ComponentName          = 'Test Application'


  service_header = ESBSvcHeader()
http://sourceforge.net/mailarchive/forum.php?thread_name=20080716203904.GA7422%40boost.horde.net&forum_name=pywebsvcs-talk


  #service_header._SvcName        = 'receiveCDPBilling'
We were able to get an unofficial/mostly complete WSDL from Zimbra. I had
  service_header._SvcName        = 'CDPBilling-receiveBilling'
problems using ZSI 2.0 with it, since ZCS relies on SOAP Headers to pass an
  service_header._SvcVersion      = '1.0'
authentication token.
  service_header._RequestDt      = dt_request.timetuple()
  service_header._RequestorInfo  = reqInfo


  if (debug): print service_header.__dict__
SOAP Header support was added in ZSI 2.1alpha1, which works fine. Below is
some sample code.


  #----- Create the order request ---------------------------------------------
john


  request = ReceiveCDPBilling()


  request._cdpID              = cdp.cdpID
binding = zimbraAdminLocator().getzimbraAdminSoap12(
  request._consortiumID      = cdp.consortiumID
   url='https://vicar.example.com:7071/service/admin/soap')
  request._sourceSystemID    = cdp.sourceSystemID
   request._sequenceID        = cdp.sequenceID
  request._notificationEmail  = notification_email
  request._Customer          = []


  # print request
auth_req = zimbra_admin_server.AuthSoap12In()
  # print request.__dict__
auth_req._name = 'admin'
auth_req._password = 'examplepass'


  for cust in customers:
auth_res = binding.Auth(authreq)
      customer = ns0.Customer_Def('Customer').pyclass()


      request._Customer.append(customer)
context = GED('urn:zimbra', 'context').pyclass()
context._authToken = auth_res._authToken
context._sessionId = auth_res._sessionId


      customer._apAccountNumber  = cust.apAccountNumber
create_req = zimbra_admin_server.CreateAccountSoap12In()
      customer._cdpAccountNumber = cust.cdpAccountNumber
create_req._name = 'exampleuser@vicar.example.com'
      customer._cdpCustomerID    = cust.cdpCustomerID
create_req._password = 'userpass'
      customer._cdpCustomerName  = cust.cdpCustomerName
      customer._Order            = []


      # print customer
binding.CreateAccount(create_req, soapheaders=[context])
      # print customer.__dict__


      for ord in cust.order:
spec = GTD('urn:zimbraAdmin', 'GetAccountSpecifier')(None).pyclass(
        order = ns0.Order_Def('Order').pyclass()
'exampleuser@vicar.example.com')
spec._attrs = {'by': 'name'}
get_req = zimbra_admin_server.GetAccountSoap12In()
get_req._account = spec
acct = binding.GetAccount(get_req, soapheaders=[context])
id = acct._account._attrs['id']


        order._orderID            = ord.orderID
fwd_addr = GTD('urn:zimbraAdmin', 'ItemAttribute')(None).pyclass(
        order._orderStatus        = ord.orderStatus
'forwarddest@example.com')
        order._orderDateTime      = ord.orderDateTime
fwd_addr._attrs = {'n': 'zimbraPrefMailForwardingAddress'}
        order._readyDateTime      = ord.readyDateTime
modify_req = zimbra_admin_server.ModifyAccountSoap12In()
        order._invoiceDateTime    = ord.invoiceDateTime
modify_req._id = id
        order._numberOfItems      = ord.numberOfItems
modify_req._a = [fwd_addr]
        order._workCentreID        = ord.workCentreID
        order._CustomerReference  = None
        order._OrderReference      = None
        order._PickUpAddress      = None
        order._DeliveryAddress    = None
        order._Weight              = None
        order._Dimension          = None
        order._Performance        = None
        order._Service            = []


        print "Constructing order number %s" % order._orderID
binding.ModifyAccount(modify_req, soapheaders=[context])


        customer._Order.append(order)
--
 
John Morrissey         _o            /\         ----  __o
         customerReference = ns0.CustomerReference_Def('CustomerReference').pyclass()
jwm@horde.net       _-< \_          / \      ----  < \,
 
www.horde.net/   __(_)/_(_)________/    \_______(_) /_(_)__
        cust_ref = ord.CustomerReference
 
        customerReference._customerCostCentre    = cust_ref.customerCostCentre
customerReference._otherCustomerRef      = cust_ref.otherCustomerRef
        customerReference._otherCustomerRefDesc  = cust_ref.otherCustomerRefDesc
 
        order._CustomerReference  = customerReference
 
        pickUpAddress = ns0.Address_Def('Address').pyclass()
 
        pickUpAddress._address1    = ord.PickUpAddress.address1[:34]
        pickUpAddress._address2    = ord.PickUpAddress.address2[:34]
        pickUpAddress._address3    = ord.PickUpAddress.address3[:34]
        pickUpAddress._suburb      = ord.PickUpAddress.suburb
        pickUpAddress._postcode    = ord.PickUpAddress.postcode
        pickUpAddress._state      = ord.PickUpAddress.state
        pickUpAddress._country    = ord.PickUpAddress.country
 
        order._PickUpAddress      = pickUpAddress
 
        deliveryAddress = ns0.Address_Def('Address').pyclass()
 
        deliveryAddress._address1  = ord.DeliveryAddress.address1[:34]
        deliveryAddress._address2  = ord.DeliveryAddress.address2[:34]
        deliveryAddress._address3  = ord.DeliveryAddress.address3[:34]
        deliveryAddress._suburb    = ord.DeliveryAddress.suburb
        deliveryAddress._postcode  = ord.DeliveryAddress.postcode
        deliveryAddress._state    = ord.DeliveryAddress.state
        deliveryAddress._country  = ord.DeliveryAddress.country
 
        order._DeliveryAddress    = deliveryAddress
 
        weight = ns0.Weight_Def('Weight').pyclass()
 
        weight._entryWeight        = ord.Weight.entryWeight
        weight._cubedWeight        = ord.Weight.cubedWeight
        weight._actualWeight      = ord.Weight.actualWeight
 
        order._Weight              = weight
 
        dimension = ns0.Dimension_Def('Dimension').pyclass()
        dimension._height          = ord.Dimension.height
        dimension._length          = ord.Dimension.length
        dimension._width          = ord.Dimension.width
 
        order._Dimension          = dimension
 
        if ord.Performance:
            performance = ns0.Performance_Def('Performance').pyclass()
 
            performance._schedPickUpDateTime        = ord.Performance.schedPickUpDateTime
            performance._pickupSignatureRequired    = ord.Performance.pickupSignatureRequired
            performance._pickupSignatureReceived    = ord.Performance.pickupSignatureReceived
            performance._actualPickUpDateTime      = ord.Performance.actualPickUpDateTime
            performance._latePickUpIndicator        = ord.Performance.latePickUpIndicator
            performance._pickUpTimeliness          = ord.Performance.pickUpTimeliness
            performance._schedDeliveryDateTime      = ord.Performance.schedDeliveryDateTime
            performance._deliverySignatureRequired  = ord.Performance.deliverySignatureRequired
            performance._deliverySignatureReceived  = ord.Performance.deliverySignatureReceived
            performance._actualDeliveryDateTime    = ord.Performance.actualDeliveryDateTime
            performance._lateDeliveryIndicator      = ord.Performance.lateDeliveryIndicator
            performance._deliveryTimeliness         = ord.Performance.deliveryTimeliness
 
            order._Performance                      = performance
 
        service = ns0.Service_Def('Service').pyclass()
 
        service._serviceType      = ord.Service.serviceType
        service._serviceArea      = ord.Service.serviceArea
        service._serviceCodeSet    = ord.Service.serviceCodeSet
        service._serviceCode      = ord.Service.serviceCode
        service._serviceDesc      = ord.Service.serviceDesc
        service._apProductCode    = ord.Service.apProductCode
        service._deliveryDistance  = None
        service._Charge            = []
 
        order._Service.append(service)
 
        for ord_charge in ord.Service.charge:
            # ord_charge = ord.Service.charge[0]
 
            charge = ns0.Charge_Def('Charge').pyclass()
 
            charge._transactionID      = ord_charge.transactionID
            charge._transactionType    = ord_charge.transactionType
            charge._chargeType          = ord_charge.chargeType
            charge._chargeCode          = ord_charge.chargeCode
            charge._chargeCodeDesc      = ord_charge.chargeCodeDesc
            charge._priceCharged        = ord_charge.priceCharged
            charge._taxCode            = ord_charge.taxCode
 
            service._Charge.append(charge)
 
  assert isinstance(request, ReceiveCDPBilling), "ERROR: Need ReceiveCDPBilling pyclass instance"
 
  return request
 
#-------------------------------------------------------------------------------
 
def send(request):
  response = None
 
  locator    = CDPBilling_serviceagentLocator()
 
  service_url = locator.getCDPBillingAddress()
 
  log.write('End Point (Servie URL) -> "%s"' % service_url)
 
  kw = {'url' : service_url}
 
  if log:
      kw['tracefile'] = log
 
  port_type = locator.getCDPBilling(**kw)
 
  # service_header = GED(u'http://www.auspost.com.au/ESB/schema/ESBTypes', u'ESBSvcHeader').pyclass()
  # service_header.SvcName = 'receiveCDPBilling'
 
  try:
      response = port_type.receiveCDPBilling(request, soapheaders=[service_header],)
 
  except (Fault, FaultException), msg:
      dt_end       = datetime.now()
 
      print "msg -> {{%s}}" % str(msg)
      print "response -> ", response
 
      # print response._ESBSvcHeader
      # print response._ESBException
 
      # faultText    = (msg.fault[0].string or '<no fault text available>')
      # faultDetail  = "SOAP response: \n" + msg.fault[1].strip("\n")
 
      faultText  = 'N/A'
      faultDetail = 'N/A'
 
      log.write("Fault (for %s): %s" % (request._Customer[0]._cdpCustomerID, faultText))
      log.write("%s ERROR Fault Exception: Details: %s, elapsed: %s, %s, %s" % \
        (datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
          faultText, str(dt_end - dt_request),
          traceback.format_tb(sys.exc_info()[2],1),
          faultDetail))
 
  except socket.error, msg:
      log.write("Fault - socket error (for %s): %s" % (request._BusinessRefID, msg))
       log.write("%s ERROR Socket Error Exception. Details: %s %s" % \
        (datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        msg,
        traceback.format_tb(sys.exc_info()[2],1)))
 
  #----- Order successfully processed -------------------------------
 
  else:               
      dt_end      = datetime.now()
      log.write("OK (for Customer %s - %s)" % (request._Customer[0]._cdpCustomerID,
                                                request._Customer[0]._cdpCustomerName))
 
  return response
 
#-------------------------------------------------------------------------------
 
def analyse(logfile):
  cnt = 0
 
  lfd    = open(logfile, 'r')
 
  for line in lfd.readlines():
      if cnt == 11:
        response_xml = line[:-1]
        # print "[[%s]]" % response_xml
      # print "Cnt -> %d" % cnt
      cnt += 1
 
  lfd.close()
 
  ofd = open('response.xml', 'w')
 
  ofd.write(response_xml)
  ofd.close()
 
  return response_xml
 
#-------------------------------------------------------------------------------
 
def examine(efd):
  resp_xml = analyse('send.log')
 
 
  dom_obj = xml.dom.minidom.parse('response.xml')
 
  pp      = pprint.PrettyPrinter(indent=3)
 
  # print "===== dom_obj.__dict__ =========================================\n"
  # pp.pprint(dom_obj.__dict__)
  # print "\n"
 
  envelope = dom_obj.childNodes[0]
 
  # print "===== dom_obj.childNodes: ======================================\n"
  # pp.pprint(envelope.__dict__)
  # print "\n"
 
  soap_header = envelope.childNodes[0]
  # pp.pprint(soap_header.__dict__)
  # print "\n"
 
  svc_header = soap_header.childNodes[0]
  #pp.pprint(svc_header.__dict__)
  #print "\n"
 
  request_dt = svc_header.childNodes[2]
  # print "request_dt.__dict__"
  # pp.pprint(request_dt.__dict__)
  # print "\n"
 
  req_date = request_dt.childNodes[0].nodeValue
  t  = split(req_date, '.')
  msec = t[1].replace('Z','')
  dt = datetime(*(strptime(t[0], "%Y-%m-%dT%H:%M:%S")[0:6]))
  dt = dt.replace(microsecond=int(msec) * 1000)
 
  tracking = svc_header.childNodes[4]
  # print "tracking.__dict__"
   # pp.pprint(tracking.__dict__)
  # print "\n"
 
  status_node = tracking.childNodes[1]
  # print "status.__dict__"
  # pp.pprint(status.__dict__)
  # print "\n"
  status = status_node.childNodes[0].nodeValue
 
  tracking_events = tracking.childNodes[3]
  # print "tracking_events.__dict__"
  # pp.pprint(tracking_events.__dict__)
  # print "\n"
 
  events1 = tracking_events.childNodes[0]
  # print "events1.__dict__"
  # pp.pprint(events1.__dict__)
  # print "\n"
 
  e1_dt_node = events1.childNodes[1]
  # pp.pprint(e1_dt_node.__dict__)
  # print "\n"
  e1_dt = e1_dt_node.childNodes[0].nodeValue
  t  = split(e1_dt, '.')
  msec = t[1].replace('+10:00','')
  e1_dt = datetime(*(strptime(t[0], "%Y-%m-%dT%H:%M:%S")[0:6]))
  dt_end = e1_dt.replace(microsecond=int(msec) * 1000)
 
  e1_desc_node = events1.childNodes[2]
  e1_desc = e1_desc_node.childNodes[0].nodeValue
  # print e1_desc
  m = re.search("ocessed is ([0-9]*),", e1_desc)
  if m:
      no_orders = int(m.group(1))
  else:
      no_orders = 0
 
  events2 = tracking_events.childNodes[1]
  # pp.pprint(events2.__dict__)
  # print "\n"
 
  e2_node = events2.childNodes[1]
  # pp.pprint(e2_node.__dict__)
  # print "\n"
  e2_dt = e2_node.childNodes[0].nodeValue
  t  = split(e2_dt, '.')
  msec = t[1].replace('+10:00','')
  e2_dt = datetime(*(strptime(t[0], "%Y-%m-%dT%H:%M:%S")[0:6]))
  dt_start = e2_dt.replace(microsecond=int(msec) * 1000)
 
  e2_desc_node = events2.childNodes[2]
  e2_desc = e2_desc_node.childNodes[0].nodeValue
  #print "    frontend processing desc:  %s" % e2_desc
 
  t_delta    = dt_end - dt_start
  t_microsec = 0.0 + (t_delta.days * 86400) + t_delta.seconds + (t_delta.microseconds/1000000.0)
 
  efd.write("                Request date:  %s\n" % req_date)
  efd.write("                    Received:  %d orders\n" % no_orders)
  efd.write("                      Status:  %s\n\n" % status)
  efd.write("Start frontend processing DT:  %s\n" % dt_start)
  efd.write("  End frontend processing DT:  %s\n" % dt_end)
  efd.write("    Average processing time:  %.03f seconds\n" % (t_microsec/no_orders))
   efd.write("    %4d orders processed in:  %.03f seconds\n" % (no_orders, t_microsec))
 
  efd.close()
 
  # PLH
 
  # body = envelope.childNodes[1]
  # pp.pprint(body)
  # pp.pprint(body.__dict__)
  # print "\n"
 
  # billing_response = body.childNodes[0]
  # pp.pprint(billing_response)
  # pp.pprint(billing_response.__dict__)
  # print "\n"
 
 
#-------------------------------------------------------------------------------
 
def generate(cdpId, no_orders):
  global log
  global dt_order
  global cdp_details
  global add_performance
 
  dt_order = datetime.now() - timedelta(days=3)
  dt_stamp = datetime.now().strftime('%Y%m%d%H%M%S')
 
  print "Timestamp [%s]" % dt_stamp
  print "Posting order at %s" % dt_order
  print "timetuple %s" % dt_order.timetuple()
 
  load_cdp_data()
 
  if (cdpId == 'MPC'):
      add_performance = True
 
  logfile = "log/ReceiveCDPBilling__%s.log" % dt_stamp
 
  log    = open(logfile, 'w+')
 
  cdp    = CDP(cdpId)
 
  customer_orders = generate_orders(cdp, no_orders=no_orders)
 
  request  = create_request(cdp, customer_orders)
 
  response = send(request)
 
  save_cdp_data()
 
  log.close()
 
  os.system('rm send.log');
  os.system('ln -s %s send.log' % logfile);
 
  if (response == 'success'):
      exlog = "log/examine__%s.log" % dt_stamp
      efd = open(exlog, 'w')
      examine(efd)
      efd.close()
      os.system('rm examine.log')
      os.system('ln -s %s examine.log' % exlog)
      os.system('cat examine.log')
 
#-------------------------------------------------------------------------------
 
def usage():
  USAGE = """
 
    Usage:
   
      $ dt.py
   
  """
 
  sys.stderr.write(USAGE)
 
#-------------------------------------------------------------------------------
 
def main(argv):
  global debug_flg, verbose_flg, sundry_flg, cdpId, no_orders, no_sundries
 
  loop_cnt    = 1
  examine_flg = False
 
  #----- Process command line arguments ----------------------------
 
  try:
      opts, args = getopt.getopt(argv, "c:dehl:n:sS:v",
              ["cdp", "debug", "examine", "help", "loop", "no=", "sundry", "sundries", "verbose"])
  except getopt.GetoptError:
      usage()
      sys.exit(2)
  else:
      for opt, arg in opts:
        if opt in ("-h", "--help"):
            usage()
            sys.exit(0)
        elif opt in ("-c", "--cdp"):
            cdpId = arg
        elif opt in ("-e", "--examine"):
            examine_flg = True
        elif opt in ("-l", "--loop"):
            loop_cnt = int(arg)
        elif opt in ("-n", "--no"):
            no_orders = int(arg)
        elif opt in ("-s", "--sundry"):
            sundry_flg  = True
            no_sundries = 1
        elif opt in ("-S", "--sundries"):
            sundry_flg  = True
            no_sundries = int(arg)
        elif opt in ("-v", "--verbose"):
            verbose_flg = True
 
  if not cdp_defaults.has_key(cdpId):
      print 'Bad CDP ID "%s"' % cdpId
      sys.exit(1)
 
  if examine_flg:
      examine(sys.stdout)
  else:
      for idx in range(loop_cnt):
        generate(cdpId, no_orders)
        if idx < loop_cnt - 1:
            time.sleep(30)
 
 
#---------------------------------------------------------------------
 
if __name__ == "__main__":
  main(sys.argv[1:])
 
 
#---------------------------------------------------------------------
 
"""
 
ESBSOAPException:
                def __init__(self):
                    # pyclass
                    self._ESBSvcHeader = None
                    self._ESBException = None
                    return
 
ESBSvcHeader
                def __init__(self):
                    # pyclass
                    self._SvcName = None
                    self._SvcVersion = None
                    self._RequestDt = None
                    self._RequestorInfo = None
                    self._Tracking = None
                    return
 
ESBException:
                def __init__(self):
                    # pyclass
                    self._ExceptionCategory = None
                    self._ExceptionType = None
                    self._ExceptionCode = None
                    self._ExceptionDescription = None
                    self._ExceptionOtherData = None
                    self._ESBAlert = None
                    return
 
 
"""
</pre>
</pre>


==== Example of Usage ====
[[Category:Python]]
 
[[Category:ZSI]]
Generate a 10 order cluster from MPC CDP
 
<pre>
$ ./do.py -c MPC -n 10
Timestamp [20070914150827]
Posting order at 2007-09-11 15:08:27.906250
timetuple (2007, 9, 11, 15, 8, 27, 1, 254, -1)
 
      apAccountNumber  = 5995220
      cdpAccountNumber = 2909130
      cdpCustomerID    = 2845275
      cdpCustomerName  = 'IST Test customer'
     
      Order:
 
        orderID            = SVT-M-001510
        orderDateTime      = (2007, 9, 11, 15, 8, 27, 1, 254, -1)
        readyDateTime      = (2007, 9, 12, 15, 8, 27, 2, 255, -1)
        invoiceDateTime    = (2007, 9, 13, 15, 8, 27, 3, 256, -1)
        numberOfItems      = 1
        workCentreID        = 275784
     
      ...
     
      Order:
 
        orderID            = SVT-M-001518
        orderDateTime      = (2007, 9, 11, 15, 8, 27, 1, 254, -1)
        readyDateTime      = (2007, 9, 12, 15, 8, 27, 2, 255, -1)
        invoiceDateTime    = (2007, 9, 13, 15, 8, 27, 3, 256, -1)
        numberOfItems      = 1
        workCentreID        = 275784
     
      Order:
 
        orderID            = SVT-M-001519
        orderDateTime      = (2007, 9, 11, 15, 8, 27, 1, 254, -1)
        readyDateTime      = (2007, 9, 12, 15, 8, 27, 2, 255, -1)
        invoiceDateTime    = (2007, 9, 13, 15, 8, 27, 3, 256, -1)
        numberOfItems      = 1
        workCentreID        = 275784
     
Constructing order number SVT-M-001510
Constructing order number SVT-M-001511
Constructing order number SVT-M-001512
Constructing order number SVT-M-001513
Constructing order number SVT-M-001514
Constructing order number SVT-M-001515
Constructing order number SVT-M-001516
Constructing order number SVT-M-001517
Constructing order number SVT-M-001518
Constructing order number SVT-M-001519
 
                Request date:  2007-09-14T15:08:28.004Z
                    Received:  10 orders
                      Status:  FinishedOK
 
Start frontend processing DT:  2007-09-14 15:01:27.917000
  End frontend processing DT:  2007-09-14 15:01:30.062000
    Average processing time:  0.214 seconds
      10 orders processed in:  2.145 seconds
 
</pre>

Latest revision as of 14:16, 22 August 2008

Some Python ZSI Examples

Document Injection Example

Python SOAP - Document Injection Example

SaintBook

$ cat wsdl.sh 
#!/bin/sh

wget http://saintbook.org/MightyMaxims/MightyMaxims.asmx?WSDL
from ZSI.wstools import WSDLTools

...

location = 'http://saintbook.org/MightyMaxims/MightyMaxims.asmx?WSDL'

load = reader.loadFromURL

wsdl = load(location)
...

Not sure works for me -josh

$ mkdir TMP
$ cd TMP/
$ wsdl2py http://saintbook.org/MightyMaxims/MightyMaxims.asmx?WSDL
$ ls
Maxim_client.py	Maxim_server.py	Maxim_types.py

$ python
Python 2.5.1 (r251:54863, May 23 2007, 10:06:54)
[GCC 4.0.0 20041026 (Apple Computer, Inc. build 4061)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
 >>> from ZSI.wstools import WSDLTools
 >>> location = 'http://saintbook.org/MightyMaxims/MightyMaxims.asmx?WSDL'
 >>> w = reader.loadFromURL(location)
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
NameError: name 'reader' is not defined

 >>> reader = WSDLTools.WSDLReader()
 >>> w = reader.loadFromURL(location)
 >>> w
<ZSI.wstools.WSDLTools.WSDL instance at 0xca080>


On Jan 31, 2008, at 7:49 AM, Lorena Carlo wrote:

> Hi,
>
> I don't know if this is a ZSI bug, but for some reason I can not load
> the following webservice:
>
> http://saintbook.org/MightyMaxims/MightyMaxims.asmx?WSDL
>
> This is the portion of code:
>
> from ZSI.wstools import WSDLTools
> location = 'http://saintbook.org/MightyMaxims/MightyMaxims.asmx?WSDL'
> load = reader.loadFromURL
> wsdl = load(location)
>
> This is the exception I get:
>
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> File
> "c:\Python24\lib\site-packages\zsi-2.1_a1-py2.4.egg\ZSI\wstools 
> \WSDLTools
> .py", line 39, in loadFromURL
> File
> "c:\Python24\lib\site-packages\zsi-2.1_a1-py2.4.egg\ZSI\wstools 
> \Utility.p
> y", line 642, in loadFromURL
> File
> "c:\Python24\lib\site-packages\zsi-2.1_a1-py2.4.egg\ZSI\wstools 
> \Utility.p
> y", line 203, in urlopen
> File
> "c:\Python24\lib\site-packages\zsi-2.1_a1-py2.4.egg\ZSI\wstools 
> \Utility.p
> y", line 153, in urlopen
> File "c:\Python24\lib\urllib.py", line 82, in urlopen
>   return opener.open(url)
> File "c:\Python24\lib\urllib.py", line 190, in open
>   return getattr(self, name)(url)
> File "c:\Python24\lib\urllib.py", line 426, in open_file
>   return self.open_local_file(url)
> File "c:\Python24\lib\urllib.py", line 440, in open_local_file
>   raise IOError(e.errno, e.strerror, e.filename)
> IOError: [Errno 2] No such file or directory:
> '\\MightyMaxims\\MightyMaxims.asmx
> ?WSDL?65784000'
>
> Any help will be appreciated, thanks!
>
> Lorena

Building Complex Type Arrays

So grab an interpreter and import the generated module, then use  
help() to look at the request you're trying to use.   You'll probably  
see some helper methods and properties in there,

	new_
	set_
	get_

If that doesn't help provide the WSDL

-josh

On Feb 6, 2008, at 7:51 AM, Joseph Boiteau wrote:

> Hi,
>
> I'm using a ZSI client interface generated with  --complexType  
> option (ZSI 2.0)
> When I try to construct a request properly, I cannot find a nice way  
> to instantiate the array object.
>
> A simple list [] seems to correspond to the array, but then I have  
> no parent object to instantiate an array element..
>
> Using the second generated file (*_services_types.py), the element i  
> get using ns0.myDef_Def(None) is a basic object.. without specific  
> attributes or methods I need.
>
> So I'm looking after the manner to instantiate properly any sub-node  
> object.
>
> Thanks

Nilable Types

a nilled element looks like this:

  <whatever xsi:nil="true"/>


So it should be present if it is minOccurs=1 

-josh

On Feb 7, 2008, at 11:32 AM, Rex Corrovan wrote:


Hey all,

Been using ZSI a while now, and came across a 'Bad Thing™'. I would get an exception that 'Required <type> missing' any time I would make certain requests.

Upon further investigation I realized that if the WSDL I was using had nillable=true, and minOccurs=1 ZSI, and more specifically TC.py, would throw this exception if the server returned an empty element. In this case an Empty element is valid because nillable is true, and the server HAS to return this tag simply because it has minOccurs of 1.

Anyway, the fix was not to hard, on line (note: I also added the space after 'Required ' in the exception string for a better looking message)

from original Line 153:
        if not href:
            if self.minOccurs is 0: return None
            raise EvaluateException('Required' + tag + ' missing',
                    ps.Backtrace(elt))


To my patched version:
        if not href:
            if self.minOccurs is 0: return None
            if self.minOccurs is 1 and self.nillable is True: return None
            raise EvaluateException('Required ' + tag + ' missing',
                    ps.Backtrace(elt))

Namespaces

This is the wsdl for the above service:

<?xml version="1.0" encoding="UTF-8"?><!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.2_01-hudson-189-. --><!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.2_01-hudson-189-. --><definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://services/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://services/" name="testserviceService">
<wsp:UsingPolicy></wsp:UsingPolicy>
<wsp:Policy wsu:Id="testservicePortBinding_testMethod_WSAT_Policy">
<wsp:ExactlyOne>
<wsp:All>
<ns1:ATAlwaysCapability xmlns:ns1="http://schemas.xmlsoap.org/ws/2004/10/wsat" wsp:Optional="false"></ns1:ATAlwaysCapability>
<ns2:ATAssertion xmlns:ns3="http://schemas.xmlsoap.org/ws/2002/12/policy" xmlns:ns2="http://schemas.xmlsoap.org/ws/2004/10/wsat" ns3:Optional="true" wsp:Optional="true"></ns2:ATAssertion>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<types>
<xsd:schema>
<xsd:import namespace="http://services/" schemaLocation="http://localhost:8080/testserviceService/testservice?xsd=1"></xsd:import>
</xsd:schema>
</types>
<message name="testMethod">
<part name="parameters" element="tns:testMethod"></part>
</message>
<message name="testMethodResponse">
<part name="parameters" element="tns:testMethodResponse"></part>
</message>
<portType name="testservice">
<operation name="testMethod">
<input message="tns:testMethod"></input>
<output message="tns:testMethodResponse"></output>
</operation>
</portType>
<binding name="testservicePortBinding" type="tns:testservice">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"></soap:binding>
<operation name="testMethod">
<wsp:PolicyReference URI="#testservicePortBinding_testMethod_WSAT_Policy"></wsp:PolicyReference>
<soap:operation soapAction=""></soap:operation>
<input>
<soap:body use="literal"></soap:body>
</input>
<output>
<soap:body use="literal"></soap:body>
</output>
</operation>
</binding>
<service name="testserviceService">
<port name="testservicePort" binding="tns:testservicePortBinding">
<soap:address location="http://localhost:8080/testserviceService/testservice"></soap:address>
</port>
</service>
</definitions>

(This code directly incooperates an EJB, but without this, directly having the code in the WebMethod shows the same result.)

Using wsdl2py I got:

wn@omega:~$ wsdl2py --url http://localhost:8080/testserviceService/testservice?wsdl
Error loading http://localhost:8080/testserviceService/testservice?wsdl: 
namespace of schema and import match
wn@omega:~$ 

Using the ServiceProxy module directly in the code shows the same result.


Could someone give me a hint what's wrong here?

wsdl2py Example

certainly it is a stupid failure, but I'm unable to bring it to work: a WebService provider coded using Netbeans with J2EE 1.5 and the client with ZSI:


wn@omega:~$ wsdl2py --url http://localhost:8080/testserviceService/testservice?wsdl
Error loading http://localhost:8080/testserviceService/testservice?wsdl: 
namespace of schema and import match
wn@omega:~$ 


Using the ServiceProxy module directly in the code shows the same result.


From your wsdl .....

  <xsd:import namespace="http://services/" schemaLocation="http://localhost:8080/testserviceService/testservice?xsd=1"></xsd:import>

sugarsoap - Client 1

$ cat run.py
#!/usr/bin/env python

from sugarsoap_services import *
import md5
import sys

def main():
    loc = sugarsoapLocator()

    portType = loc.getsugarsoapPortType(tracefile=sys.stdout)

    request = loginRequest()
    request._user_auth = uauth = request.new_user_auth()
    request._application_name='appname'

    uauth._user_name ='admin'
    uauth._password  = md5.new('password').hexdigest()
    uauth._version = '1.1'

    response = portType.login(request)

    print response._return
    print response._return._id
    print response._return._error._name

if "__main__" == __name__:
    main()

sugarsoap - Client 1

$ cat run.py
#!/usr/bin/env python

from sugarsoap_services import *
import md5
import sys

def main():
    loc = sugarsoapLocator()

    portType = loc.getsugarsoapPortType(tracefile=sys.stdout)

    request = loginRequest()
    request._user_auth = uauth = request.new_user_auth()
    request._application_name='appname'

    uauth._user_name ='admin'
    uauth._password  = md5.new('password').hexdigest()
    uauth._version = '1.1'

    response = portType.login(request)

    print response._return
    print response._return._id
    print response._return._error._name

if "__main__" == __name__:
    main()

certainly it is a stupid failure, but I'm unable to bring it to work: a WebService provider coded using Netbeans with J2EE 1.5 and the client with ZSI:


wn@omega:~$ wsdl2py --url http://localhost:8080/testserviceService/testservice?wsdl
Error loading http://localhost:8080/testserviceService/testservice?wsdl: 
namespace of schema and import match
wn@omega:~$ 


Using the ServiceProxy module directly in the code shows the same result.


From your wsdl .....

  <xsd:import namespace="http://services/" schemaLocation="http://localhost:8080/testserviceService/testservice?xsd=1"></xsd:import>

sugarsoap - Client 1

$ cat run.py
#!/usr/bin/env python

from sugarsoap_services import *
import md5
import sys

def main():
    loc = sugarsoapLocator()

    portType = loc.getsugarsoapPortType(tracefile=sys.stdout)

    request = loginRequest()
    request._user_auth = uauth = request.new_user_auth()
    request._application_name='appname'

    uauth._user_name ='admin'
    uauth._password  = md5.new('password').hexdigest()
    uauth._version = '1.1'

    response = portType.login(request)

    print response._return
    print response._return._id
    print response._return._error._name

if "__main__" == __name__:
    main()

An import's namespace must match the targetNamespace attribute of the "file" or schema being imported.

But this namespace must be different than the namespace of the schema you are importing it into.

// 
<schema targetNamespace="urn:1">

<import namespace="urn:2" schemaLocation="importFile.xsd:/>

// importFile.xsd
<schema targetNamespace="urn:2">
...

-josh

Nusoap

from ZSI import *
pyobj =  [ 1, 2.0, 'a', ['b', 1.0], [(4,'a'), (5, 'c')] ],
sw = writer.SoapWriter()
sw.serialize(pyobj, typecode=Any(), unique=True)
str(sw)


import sys
cli = client.Binding(url='', tracefile=sys.stdout)
rsp = cli.whatever(pyobj)


Re: ZSI client, Nusoap server - data format trouble?
Subject: 	Re: ZSI client, Nusoap server - data format trouble?
List-id: 	Discussion of Python and Web services <pywebsvcs-talk.lists.sourceforge.net>
ZSI-1.7 (or whatever) is corrupting the XML instance by using the default namespace, I think if you use ZSI-2.* or svn it will work.

-josh

sugarsoap

sugarsoap - Client

$ cat run.py
#!/usr/bin/env python

from sugarsoap_services import *
import md5
import sys

def main():
    loc = sugarsoapLocator()

    portType = loc.getsugarsoapPortType(tracefile=sys.stdout)

    request = loginRequest()
    request._user_auth = uauth = request.new_user_auth()
    request._application_name='appname'

    uauth._user_name ='admin'
    uauth._password  = md5.new('password').hexdigest()
    uauth._version = '1.1'

    response = portType.login(request)

    print response._return
    print response._return._id
    print response._return._error._name

if "__main__" == __name__:
    main()

sugarsoap - Client 2

#!/usr/bin/env python

from sugarsoap_services import *

import md5
import sys

def main():
    loc = sugarsoapLocator()

    portType = loc.getsugarsoapPortType(tracefile=sys.stderr)

    uauth = ns1.user_auth_Def()
    uauth._user_name ='admin'
    uauth._password  = md5.new('password').hexdigest()
    uauth._version = '1.1'

    request = loginRequestWrapper()
    request._user_auth = uauth
    request._application_name='appname'

    response = portType.login(request)

    print response._return
    print response._return._id
    print response._return._error._name

if "__main__" == __name__:
    main()

Authentication and Zimbra

I posted recently about type problems when using ZSI with a service (Zimbra
Collaboration Suite, or ZCS) that does not have WSDL available:

http://sourceforge.net/mailarchive/forum.php?thread_name=20080716203904.GA7422%40boost.horde.net&forum_name=pywebsvcs-talk

We were able to get an unofficial/mostly complete WSDL from Zimbra. I had
problems using ZSI 2.0 with it, since ZCS relies on SOAP Headers to pass an
authentication token.

SOAP Header support was added in ZSI 2.1alpha1, which works fine. Below is
some sample code.

john


binding = zimbraAdminLocator().getzimbraAdminSoap12(
   url='https://vicar.example.com:7071/service/admin/soap')

auth_req = zimbra_admin_server.AuthSoap12In()
auth_req._name = 'admin'
auth_req._password = 'examplepass'

auth_res = binding.Auth(authreq)

context = GED('urn:zimbra', 'context').pyclass()
context._authToken = auth_res._authToken
context._sessionId = auth_res._sessionId

create_req = zimbra_admin_server.CreateAccountSoap12In()
create_req._name = 'exampleuser@vicar.example.com'
create_req._password = 'userpass'

binding.CreateAccount(create_req, soapheaders=[context])

spec = GTD('urn:zimbraAdmin', 'GetAccountSpecifier')(None).pyclass(
	'exampleuser@vicar.example.com')
spec._attrs = {'by': 'name'}
get_req = zimbra_admin_server.GetAccountSoap12In()
get_req._account = spec
acct = binding.GetAccount(get_req, soapheaders=[context])
id = acct._account._attrs['id']

fwd_addr = GTD('urn:zimbraAdmin', 'ItemAttribute')(None).pyclass(
	'forwarddest@example.com')
fwd_addr._attrs = {'n': 'zimbraPrefMailForwardingAddress'}
modify_req = zimbra_admin_server.ModifyAccountSoap12In()
modify_req._id = id
modify_req._a = [fwd_addr]

binding.ModifyAccount(modify_req, soapheaders=[context])

-- 
John Morrissey          _o            /\         ----  __o
jwm@horde.net        _-< \_          /  \       ----  <  \,
www.horde.net/    __(_)/_(_)________/    \_______(_) /_(_)__