import arc import time logger = arc.Logger(arc.Logger.getRootLogger(), 'EchoService.py') wsrf_rp_ns = "http://docs.oasis-open.org/wsrf/rp-2" echo_ns = "http://www.nordugrid.org/schemas/echo" import threading class EchoService(object): def __init__(self, cfg): logger.msg(arc.INFO, "EchoService (python) constructor called") # get the response-prefix from the config XML self.prefix = str(cfg.Get('prefix')) # get the response-suffix from the config XML self.suffix = str(cfg.Get('suffix')) logger.msg(arc.DEBUG, "EchoService (python) has prefix %(prefix)s and suffix %(suffix)s" % {'prefix': self.prefix, 'suffix': self.suffix}) self.ssl_config = self.parse_ssl_config(cfg) thread_test = str(cfg.Get('ThreadTest')) if thread_test: threading.Thread(target = self.infinite, args=[thread_test]).start() def __del__(self): logger.msg(arc.INFO, "EchoService (python) destructor called") def parse_ssl_config(self, cfg): try: client_ssl_node = cfg.Get('ClientSSLConfig') fromFile = str(client_ssl_node.Attribute('FromFile')) if fromFile: try: xml_string = file(fromFile).read() client_ssl_node = arc.XMLNode(xml_string) except: log.msg() pass if client_ssl_node.Size() == 0: return {} ssl_config = {} ssl_config['key_file'] = str(client_ssl_node.Get('KeyPath')) ssl_config['cert_file'] = str(client_ssl_node.Get('CertificatePath')) ca_file = str(client_ssl_node.Get('CACertificatePath')) if ca_file: ssl_config['ca_file'] = ca_file else: ssl_config['ca_dir'] = str(client_ssl_node.Get('CACertificatesDir')) return ssl_config except: import traceback logger.msg(arc.ERROR, traceback.format_exc()) return {} def infinite(self, url): logger.msg(arc.INFO, "EchoService (python) thread test starting") i = 0 while True: try: i += 1 cfg = arc.MCCConfig() s = arc.ClientSOAP(cfg, arc.URL(url)) ns = arc.NS('echo', echo_ns) outpayload = arc.PayloadSOAP(ns) outpayload.NewChild('echo:echo').NewChild('echo:say').Set('hi!') resp, status = s.process(outpayload) logger.msg(arc.INFO, "EchoService (python) thread test, iteration %(iteration)s %(status)s" % {'iteration': i, 'status': status}) time.sleep(3) except Exception as e: import traceback logger.msg(arc.DEBUG, traceback.format_exc()) def GetLocalInformation(self): ns = arc.NS({'':'http://schemas.ogf.org/glue/2008/05/spec_2.0_d41_r01'}) info = arc.XMLNode(ns,'Domains') service_node = info.NewChild('AdminDomain').NewChild('Services').NewChild('Service') service_node.NewChild('Type').Set('org.nordugrid.tests.echo_python') endpoint_node = service_node.NewChild('Endpoint') endpoint_node.NewChild('HealthState').Set('ok') endpoint_node.NewChild('ServingState').Set('production') return info def process(self, inmsg, outmsg): logger.msg(arc.DEBUG, "EchoService (python) 'Process' called") # time.sleep(10) # get the payload from the message inpayload = inmsg.Payload() logger.msg(arc.VERBOSE, 'inmsg.Auth().Export(arc.SecAttr.ARCAuth) = %s' % inmsg.Auth().Export(arc.SecAttr.ARCAuth).GetXML()) logger.msg(arc.VERBOSE, 'inmsg.Attributes().getAll() = %s ' % inmsg.Attributes().getAll()) logger.msg(arc.INFO, "EchoService (python) got: %s " % inpayload.GetXML()) # the first child of the payload should be the name of the request request_node = inpayload.Child() # get the namespace request_namespace = request_node.Namespace() logger.msg(arc.DEBUG, "EchoService (python) request_namespace: %s" % request_namespace) if request_namespace != echo_ns: if request_namespace == wsrf_rp_ns: outpayload = arc.PayloadSOAP(arc.NS({'wsrf-rp':wsrf_rp_ns})) outpayload.NewChild('wsrf-rp:GetResourcePropertyDocumentResponse').NewChild(self.GetLocalInformation()) outmsg.Payload(outpayload) logger.msg(arc.DEBUG, "outpayload %s" % outpayload.GetXML()) return arc.MCC_Status(arc.STATUS_OK) raise Exception('wrong namespace. expected: %s' % echo_ns) # get the name of the request without the namespace prefix # this is the name of the Body node's first child request_name = request_node.Name() # create an answer payload ns = arc.NS({'echo': echo_ns}) outpayload = arc.PayloadSOAP(ns) # here we defined that 'echo' prefix will be the namespace prefix of 'http://www.nordugrid.org/schemas/echo' # get the message say = str(request_node.Get('say')) # put it between the response-prefix and the response-suffix hear = self.prefix + say + self.suffix if request_name == 'double': # if the name of the request is 'double' # we create a new echo message which we send to http://localhost:60000/Echo using the ClientSOAP object cfg = arc.MCCConfig() ssl = False if self.ssl_config: cfg.AddCertificate(self.ssl_config.get('cert_file', None)) cfg.AddPrivateKey(self.ssl_config.get('key_file', None)) if 'ca_file' in self.ssl_config: cfg.AddCAFile(self.ssl_config.get('ca_file', None)) else: cfg.AddCADir(self.ssl_config.get('ca_dir', None)) ssl = True if ssl: url = arc.URL('https://localhost:60000/Echo') logger.msg(arc.DEBUG, 'Calling https://localhost:60000/Echo using ClientSOAP') else: url = arc.URL('http://localhost:60000/Echo') logger.msg(arc.DEBUG, 'Calling http://localhost:60000/Echo using ClientSOAP') # creating the ClientSOAP object s = arc.ClientSOAP(cfg, url) new_payload = arc.PayloadSOAP(ns) # creating the message new_payload.NewChild('echo:echo').NewChild('echo:say').Set(hear) logger.msg(arc.DEBUG, 'new_payload %s' % new_payload.GetXML()) # sending the message resp, status = s.process(new_payload) # get the response hear = str(resp.Get('echoResponse').Get('hear')) elif request_name == 'httplib': # if the name of the request is 'httplib' # we create a new echo message which we send to http://localhost:60000/echo using python's built-in http client try: import http.client as httplib except ImportError: import httplib logger.msg(arc.DEBUG, 'Calling http://localhost:60000/Echo using httplib') # create the connection h = httplib.HTTPConnection('localhost', 60000) new_payload = arc.PayloadSOAP(ns) # create the message new_payload.NewChild('echo:echo').NewChild('echo:say').Set(hear) logger.msg(arc.DEBUG, 'new_payload %s' % new_payload.GetXML()) # send the message h.request('POST', '/Echo', new_payload.GetXML()) r = h.getresponse() response = r.read() logger.msg(arc.DEBUG, response) resp = arc.XMLNode(response) # get the response hear = str(resp.Child().Get('echoResponse').Get('hear')) elif request_name == 'wait': logger.msg(arc.DEBUG, 'Start waiting 10 sec...') time.sleep(10) logger.msg(arc.DEBUG, 'Waiting ends.') # we create a node at '/echo:echoResponse/echo:hear' and put the string in it outpayload.NewChild('echo:echoResponse').NewChild('echo:hear').Set(hear) outmsg.Payload(outpayload) logger.msg(arc.DEBUG, "outpayload %s" % outpayload.GetXML()) # return with STATUS_OK return arc.MCC_Status(arc.STATUS_OK) # you can easily test this with this shellscript: """ MESSAGE='HELLO' echo Request: echo $MESSAGE echo echo Response: curl -d "$MESSAGE" http://localhost:60000/Echo echo """ #