#!/usr/bin/env python
#
# Author: Sean Dobbs (s-dobbs@northwestern.edu), 2014-03-05
#
# Original Version:
# Copyright 2008 Cornell University, Ithaca, NY 14853. All rights reserved.
# Author: Valentin Kuznetsov, 2008
"""
Web services toolkit
Client for testing
"""
import os, sys, string, re, httplib, urllib, urlparse, inspect
import types, smtplib, traceback, time, socket
# As of Python 2.3 you can specify how long a socket should wait
# for a response before timing out. This can be useful in applications
# which have to fetch web pages. By default the socket module has no
# timeout and can hang. Currently, the socket timeout is not exposed
# at the httplib or urllib2 levels. However, you can set the default
# timeout globally for all sockets using
# timeout in seconds
timeout = 5
socket.setdefaulttimeout(timeout)
def parseWSDL(wsdl):
"""Parse a wsdl file. So far we use urllib to do a job to read content of the file"""
data = urllib.urlopen(wsdl).read()
print data
return data
def soapEnvelope():
"""Form a soap envelop in a form of CS web service wants. """
envelope="""
"""
return envelope
def headerEnvelope(ns,userName,password):
"""Form a header of soap envelop which include user authentication"""
envelope="""
%s
%s
"""%(ns,userName,password)
return envelope
def soapBody(ns,method,aDict):
"""Form a body of soap envelop. Construct appropriate array of items to retrieve."""
envelope="""
<%s xmlns="%s">"""%(method,ns)
for key in aDict.keys():
argName=key
argValue=aDict[key]
if type(argValue) is types.ListType:
for val in argValue:
envelope+="\n <%s>%s%s>"%(argName,val,argName)
else:
envelope+="\n <%s>%s%s>"%(argName,argValue,argName)
envelope+="""
%s>
"""%method
return envelope
def endEnvelope():
"""Add end statement to soap envelop"""
envelope="""\n"""
return envelope
def constructSOAPEnvelope(ns,method,aDict):
"""Construct a soap envelop for given method and argument list"""
# envelope=soapEnvelope()+headerEnvelope()+soapBody(method,aList)+endEnvelope()
envelope=soapEnvelope()+soapBody(ns,method,aDict)+endEnvelope()
return envelope
def sendSOAPMessage_v1(host,ns,method,envelope,debug=0):
"""Send soap message to ESMetaDataServer. Right now we use httplib to do a job"""
http_conn=""
try:
if debug:
httplib.HTTPConnection.debuglevel = 3
if not (host[:7]=="http://" or host[:8]=="https://"):
raise "invalid URL '%s' it should be in a form http://url or https://url"%host
hList = urlparse.urlparse(host)
host = hList[1]
path = hList[2]
ws="%s/ws"%path
if debug:
print "\n### sendSOAPMessage host='%s' and ws='%s'"%(host,ws)
http_conn = httplib.HTTP(host)
http_conn.putrequest('POST',ws)
http_conn.putheader('Host',host)
http_conn.putheader('Content-Type','text/xml; charset=utf-8')
http_conn.putheader('Content-Length',str(len(envelope)))
http_conn.putheader('SOAPAction',ns+method)
http_conn.endheaders()
http_conn.send(envelope)
(status_code,msg,reply)=http_conn.getreply()
response=http_conn.getfile().read()
if debug or msg!="OK":
print
print http_conn.headers
print "*** Outgoing SOAP ", "*"*54
print envelope
print "*"*72
print "status code:",status_code
print "message:",msg
print "*"*72
print reply
print "*** Incoming SOAP ", "*"*54
print response
http_conn.close()
except:
if http_conn:
http_conn.close()
# Write out the exception to stderr
sys.excepthook( sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2] )
def getConnection(scheme,host):
time.sleep(1) # let's try again to establish connection
conn=""
if scheme=="http":
conn = httplib.HTTPConnection(host)
elif scheme=="https":
conn = httplib.HTTPSConnection(host)
else:
raise "Unkonwn schema '%s'"%scheme
try:
conn.connect()
except:
time.sleep(1) # let's try again to establish connection
if scheme=="http":
conn = httplib.HTTPConnection(host)
elif scheme=="https":
conn = httplib.HTTPSConnection(host)
else:
raise "Unkonwn schema '%s'"%scheme
return conn
def sendSOAPMessage(host,ns,method,envelope,debug=0):
"""Send soap message to cougar.cs.cornell.edu. Right now we use httplib to do a job"""
conn=""
_host="%s"%host
try:
if debug:
httplib.HTTPConnection.debuglevel = 1
if not (host[:7]=="http://" or host[:8]=="https://"):
raise "invalid URL '%s' it should be in a form http://url or https://url"%host
hList = urlparse.urlparse(host)
scheme= hList[0]
host = hList[1]
path = hList[2]
# ws="%s/"%path
# if debug:
# print "\n### sendSOAPMessage host='%s' and ws='%s'"%(host,ws)
conn=getConnection(scheme,host)
headers={'Content-Type':'application/xml','SOAPAction':ns+method}
conn.request("POST","%s/"%_host,envelope,headers)
response = conn.getresponse()
print "+++",response.status, response.reason
data = response.read()
print data
conn.close()
except:
if conn:
conn.close()
# Write out the exception to stderr
sys.excepthook( sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2] )
########################################################################
### MAIN
########################################################################
if __name__ == "__main__":
x = 1
verbose = 0
test = 1
host = "http://localhost:62000"
# host = "http://webdb.lepp.cornell.edu/proxy/cmds/"
usage ="""soap.py [ -help ] [ -listServices ] [ -verbose ] [ -host ]
[ - [= =] ]
Examples: soap.py -GetRuns DatasetName=data18 Energy_Range_Name=psi
"""
if len(sys.argv)==1:
print usage
sys.exit()
index=0
while x < len(sys.argv):
index+=1
if index==20: break
print x,sys.argv[x]
if sys.argv[x]=="-verbose":
verbose=1
x+=1
if sys.argv[x]=="-listServices":
print "EventStore services:"
print "- GetRuns(Dataset_Name, Energy_Range_Name)\n"
print "- GetEnergyBoundaries(Energy_Range_Name)\n"
print "- GetEnergyRangeNames()\n"
print "- GetDatasetNames()\n"
print "- GetRunRanges(Dataset_Name, Energy_Range_Name)\n"
sys.exit()
if sys.argv[x]=="-help":
print usage
sys.exit()
if sys.argv[x]=="-host":
host=sys.argv[x+1]
x+=2
if x < len(sys.argv) and sys.argv[x][0]=="-":
service=sys.argv[x][1:]
x+=1
listArgs=sys.argv[x:]
aDict= {}
for item in listArgs:
if item[0]=="-": break
name=""
aList=[]
if string.find(item,"=")==-1:
print "You need to supply argument name for",item
sys.exit()
else:
ss=string.split(item,"=")
name = ss[0]
value= ss[1]
if re.match("\A\d+\.\d+\Z", value):
value=float(value)
else:
if re.match("\A\d+\Z", value):
value=int(value)
aDict[name]=value
x+=1
ns="http://gluex.org/GlueX"
print host,ns,service, aDict
envelope=constructSOAPEnvelope(ns,service,aDict)
print envelope
sendSOAPMessage(host,ns,service,envelope,verbose)