Python is a great language for scripting and I am showing here how to use it to monitor SOAP services.
I tested this to monitor Advent Geneva report engine which is exposed through SOAP.
This script can be used to monitor a SOAP web service and send an alert in case it does not work as expected. Note that we send a first request, we parse the response to get a session ID and then we send a second request using that session ID to assert there is a proper response (We assert the presence of certain node in that final response) It works with responses containing namespaces, a typical scenario in real life SOAP Web Services.
#!/usr/bin/python
#
# soap-geneva-monitor.py <url>
#
# Author: Nestor Urquiza
# Date: 04/07/2011
#
# Sends an email alert whenever the Advent Geneva report fails
# Used to monitor Geneva Report Engine through its SOAP interface
#
# Preconditions:
# Install httplib2 from http://code.google.com/p/httplib2/wiki/Install
# Install ElementTree from http://effbot.org/zone/element-index.htm
#
import sys
import socket
from smtplib import SMTPException
import httplib2
import elementtree.ElementTree as etree
from urllib2 import HTTPError
import smtplib
########
# Config
#######
sender = 'donotreply@nestorurquiza.com'
receivers = ['nurquiza@nestorurquiza.com']
host = 'mail.nestorurquiza.com'
thisHostname = socket.gethostname()
########
# Functions
#######
def sendRequest( xml_str ):
headers = {'SOAPAction': ''}
headers['User-Agent'] = "Monitoring"
headers['Content-length'] = str(len(xml_str))
h = httplib2.Http(".cache")
response, content = h.request(url, "POST", body=xml_str, headers=headers)
if response.status == 500 and not \
(response["content-type"].startswith("text/xml") and \
len(content) > 0):
raise HTTPError(response.status, content, None, None, None)
if response.status not in (200, 500):
raise HTTPError(response.status, content, None, None, None)
doc = etree.fromstring(content)
if response.status == 500:
faultstring = doc.findtext(".//faultstring")
detail = doc.findtext(".//detail")
raise HTTPError(response.status, faultstring, detail, None, None)
return doc
########
# Main
#######
if len(sys.argv) != 3:
sys.exit("Usage: soap-geneva-monitor.py <url> <hostname>")
#url = "http://genevatest:4640"
url = sys.argv[1]
subject = url + " monitored from " + thisHostname
hostname = sys.argv[2]
print hostname
#Define the namespace for responses
namespace = "http://geneva.advent.com"
xml_str = """<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<gen:StartCallableRunrep xmlns:gen="http://geneva.advent.com">
<gen:portNumber>9000</gen:portNumber>
<gen:hostname>""" + str(hostname) + """</gen:hostname>
<gen:username>user</gen:username>
<gen:password>password</gen:password>
<gen:extraFlags></gen:extraFlags>
</gen:StartCallableRunrep>
</soapenv:Body>
</soapenv:Envelope>
"""
try:
doc = sendRequest( xml_str )
print etree.tostring(doc)
runrepSessionId = doc.findtext(".//{%s}runrepSessionId" % namespace)
#print "runrepSessionId:" + str(runrepSessionId)
xml_str = """<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<gen:RunCallableRunrepRunReport xmlns:gen="http://geneva.advent.com">
<gen:runrepSessionId>""" + str(runrepSessionId) + """</gen:runrepSessionId>
<gen:runrepFileName>taxlotappacc.rsl</gen:runrepFileName>
<gen:extraFlags>-p TREE -at Dynamic -ap "TREE" -ps 04/06/2011 -pe 04/06/2011 --SeparateLegalEntities 1 --FundLegalEntity "TREE MF"</gen:extraFlags>
</gen:RunCallableRunrepRunReport>
</soapenv:Body>
</soapenv:Envelope>"""
doc = sendRequest( xml_str )
portfolioName = doc.findtext(".//{%s}portfolioName" % namespace)
#print portfolioName
if portfolioName != 'TREE':
raise Exception("Data Error", "Portfolio name '" + portfolioName + "' != TREE")
except Exception, err:
error = "I could not get a successful response for the SOAP Service. Details: " + str( err )
message = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (sender, receivers, subject) + error
try:
smtpObj = smtplib.SMTP(host)
smtpObj.sendmail(sender, receivers, message)
except SMTPException:
print "Error: unable to send email"
The script runs every 5 minutes from an external machine (Not from Geneva)
*/10 * * * * /usr/sbin/soap-geneva-monitor.py http://genevatest:4640
No comments:
Post a Comment