source: TI12-security/branches/PostAlpha/trunk/python/bin/LogServer.py @ 2007

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/branches/PostAlpha/trunk/python/bin/LogServer.py@2007
Revision 2007, 8.1 KB checked in by pjkersha, 13 years ago (diff)

python/conf/sessionMgrProperties.xml: fixed missing '>'
python/bin/*Server.py: modified do_GET method so that WSDL is picked up from a path
given by the environment variable NDG_SECURITY_WSDL_DIR rather than being hard coded.

  • Property svn:executable set to *
Line 
1#!/usr/bin/env python
2
3"""NDG Logging Web Service server interface
4
5NERC Data Grid Project
6
7P J Kershaw 12/05/06
8
9Copyright (C) 2006 CCLRC & NERC
10
11This software may be distributed under the terms of the Q Public License,
12version 1.0 or later.
13"""
14
15# Handle socket errors from WS
16import socket 
17
18# Command line processing
19import sys
20import os
21import optparse
22
23# Web service interface
24from ZSI import dispatch
25from ZSI.ServiceContainer import ServiceContainer, SOAPRequestHandler
26
27# Logging Web Services stub code generated by wsdl2py and
28# wsdl2dispatch
29from NDG.log_services import *
30from NDG.log_services_server import log
31
32# Logging
33from NDG.Log import *
34
35
36#_____________________________________________________________________________
37class LogSOAPRequestHandler(SOAPRequestHandler):
38     """Add a do_GET method to return the WSDL on HTTP GET requests.
39     Please note that the path to the wsdl file is derived from what
40     the HTTP invocation delivers (which is put into the self.path
41     attribute), so you might want to change this addressing scheme.
42     """
43     def do_GET(self):
44         """Return the WSDL file."""
45         
46         wsdlfile = os.path.expandvars("$NDG_SECURITY_WSDL_DIR/log.wsdl")
47         
48         print "> > > > > using wsdlfile", wsdlfile
49         wsdl = open(wsdlfile).read()
50         self.send_xml(wsdl)
51 
52     def do_POST(self):
53          """Fudge to get _Dispatch to pick up the correct address
54          - seems to be necessary when putting proxy redirect for port in
55          the wsdl e.g. http://glue.badc.rl.ac.uk/log points to the
56          default port for the Logging."""
57          self.path = "/log.wsdl"
58          SOAPRequestHandler.do_POST(self)
59       
60       
61#_____________________________________________________________________________
62# Copied from ZSI.ServiceContainer, extended to instantiate with a custom
63# request handler
64def AsServer(port=80, services=(), RequestHandlerClass=SOAPRequestHandler):
65      """port --
66          services -- list of service instances
67       """
68      address = ("127.0.0.1", port)
69      sc = ServiceContainer(address, RequestHandlerClass=RequestHandlerClass)
70      for service in services:
71           path = service.getPost()
72           sc.setNode(service, path)
73      sc.serve_forever()
74
75
76#_____________________________________________________________________________
77def runInForegnd():
78    """Run Log Server in the same process as this script"""
79       
80    print "Logging Server listening..."
81    try:
82         AsServer(port=options.port, 
83                  services=(log(logSrv, debug=options.debug),), 
84                  RequestHandlerClass=LogSOAPRequestHandler)
85
86    except KeyboardInterrupt:
87        sys.exit(0)
88
89    except socket.error, e:
90        print >>sys.stderr, "Log Server socket error: %s" % e[1]
91        sys.exit(1)
92
93    except Exception, e:
94        print >>sys.stderr, "Log Server: %s" % e
95        sys.exit(1)
96       
97
98#_____________________________________________________________________________
99def fork(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
100    """Run Log Server in a separate child process
101   
102    Thanks to Jorgen Hermann and user contributors for fork code
103   
104    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012
105   
106    """
107   
108    try: 
109        pid = os.fork() 
110        if pid > 0:
111            # exit first parent
112            sys.exit(0) 
113    except OSError, e: 
114        print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror) 
115        sys.exit(1)
116
117    # Decouple from parent environment
118    os.chdir("/") # Allows for current dir path being renamed or deleted
119    os.setsid() 
120    os.umask(0) 
121   
122    # Redirect standard file descriptors
123    si = file(stdin, 'r')
124    so = file(stdout, 'a+')
125    se = file(stderr, 'a+', 0)
126   
127    sys.stdout.flush()
128    sys.stderr.flush()
129
130    os.dup2(si.fileno(), sys.stdin.fileno())
131    os.dup2(so.fileno(), sys.stdout.fileno())
132    os.dup2(se.fileno(), sys.stderr.fileno())
133   
134    # Do second fork
135    try: 
136        pid = os.fork() 
137        if pid > 0:
138            # exit from second parent
139            sys.exit(pid) 
140    except OSError, e: 
141        print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror) 
142        sys.exit(1) 
143
144    # start the daemon main loop
145    try:
146         AsServer(port=options.port, 
147                  services=(log(logSrv, debug=options.debug),), 
148                  RequestHandlerClass=LogSOAPRequestHandler)
149
150    except socket.error, e:
151        print >>sys.stderr, "Log Server socket error: %s" % e[1]
152        sys.exit(1)
153
154    except Exception, e:
155        print >>sys.stderr, "Log Server: %s" % e
156        sys.exit(1)
157
158
159#_____________________________________________________________________________
160if __name__ == '__main__':
161
162    parser = optparse.OptionParser()
163
164
165    # Port may be set from an environment variable.  Note that this will be
166    # overridden if the port command line argument is set
167    logPortNumEnvVarName = 'NDG_LOG_PORT_NUM'
168    defaultPort = 5100
169   
170    initPort = logPortNumEnvVarName in os.environ and \
171                        int(os.environ[logPortNumEnvVarName]) or defaultPort
172                       
173    parser.add_option("-p", 
174                      "--port", 
175                      dest="port",
176                      type="int",
177                      default=initPort,
178                      help=\
179"specify a port number - default is %d or set environment variable \"%s\"" % \
180                                          (defaultPort, logPortNumEnvVarName))
181
182
183    logFileDir = 'log'
184    logFilename = 'ndg.log'
185    logFileDirPath = 'NDG_DIR' in os.environ and \
186                        os.path.join(os.environ['NDG_DIR'], logFileDir) or "."
187
188    parser.add_option("-f", 
189                      "--log-file",
190                      dest="logFilePath",
191                      default=os.path.join(logFileDirPath, logFilename),
192                      help=\
193"""file path for log file - default is $NDG_DIR/%s/%s or /tmp/%s if NDG_DIR
194is not set""" % (logFileDir, logFilename, logFilename))
195   
196    foregndFlags = ("-i", "--foreground")
197    parser.add_option(action="store_true",
198                      dest="foregndProc",
199                      default=False,
200                      help=\
201"run server as process in the foreground.  If not set, fork a child process",
202                      *foregndFlags)
203
204    parser.add_option("-d", 
205                      "--debug",
206                      dest="debug",
207                      action="store_true",
208                      default=False,
209                      help=\
210"set to stop in debugger on receipt of WS request.  %s flag must be set also"\
211                                            % '/'.join(foregndFlags))
212
213    parser.add_option("-c", 
214                      "--console",
215                      dest="console",
216                      action="store_true",
217                      default=False,
218                      help=\
219"echo log messages to stderr at console window.  %s flag must be set also" \
220                                            % '/'.join(foregndFlags))
221
222    (options, args) = parser.parse_args()
223
224
225    # Create server instance at start up
226    try:
227        logSrv = Log(logFilePath=options.logFilePath, console=options.console)
228
229    except Exception, e:
230        print >>sys.stderr, "Initialising Logging: %s\n" % str(e)
231        sys.exit(1)
232
233    if options.foregndProc:
234        runInForegnd()
235    else:
236        if options.debug or options.console:
237            print >>sys.stderr, \
238                            "%s must be set for debug and console options" % \
239                                                    '/'.join(foregndFlags)
240            parser.print_help()
241            sys.exit(1)
242       
243        # Set this flag to True to catch errors raised in the new process
244        # in a log.  Normally stderr is re-directed to /dev/null to avoid
245        # conflists with the parent process   
246        logForkErr = False
247        if logForkErr:
248            import tempfile
249            errLogH, errLogFilePath = tempfile.mkstemp(".err", "LogServer-")
250        else:
251            errLogFilePath = '/dev/null'
252
253        # Run server in separate process
254        fork(stderr=errLogFilePath)   
255       
Note: See TracBrowser for help on using the repository browser.