source: TI03-DataExtractor/branches/repackaging/server/lib/ndg/dx/server/scripts/DXWSInterface.py @ 1776

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI03-DataExtractor/branches/repackaging/server/lib/ndg/dx/server/scripts/DXWSInterface.py@1776
Revision 1776, 15.0 KB checked in by spascoe, 13 years ago (diff)

Various changes, mainly to config importing.

Autogenerated DXWSInterface script now initialises successfully
(i.e. no import errors).

  • Property svn:executable set to *
Line 
1#!/usr/bin/env python
2
3#   Copyright (C) 2004 CCLRC & NERC( Natural Environment Research Council ).
4#   This software may be distributed under the terms of the
5#   Q Public License, version 1.0 or later. http://ndg.nerc.ac.uk/public_docs/QPublic_license.txt
6
7"""
8DXWSInterface.py
9================
10
11A web service wrapper around the entire package.
12
13Notes about the sessionID and secureToken object
14------------------------------------------------
15
16The sessionID carries information about the current session but has no security
17implications. It is simply a way for the server to keep track of the request
18between calls.
19
20The secureToken is a security object (which should be encoded) that is time limited and provides
21information on what the user is allowed to access on the server. Some servers
22do not run security and so just send around a None type as the secureToken. Those
23implementing security will require that the secureToken (held in a string) is sent
24with each method call. During each call it will updated (to ensure it remains
25time valid) and returned.
26
27
28"""
29
30# Import standard library modules
31import sys
32import re
33import urllib
34import os, types
35
36# Import package modules
37from ndg.dx.server.common import *
38from ndg.dx.server.DXController import *
39from ndg.dx.server.DXRMLHandler import *
40from ndg.dx.server.DXErrors import *
41
42# Set global variables
43timePattern=re.compile("(\d{4})-(\d{1,2})-(\d{1,2}).(\d{1,2}):(\d{1,2}):(\d{1,2}(\.\d+)?)")
44
45# Import configuration
46from ndg.utils.config import config
47configSection = 'ndg.dx.server'
48SOAP_SERVER_PORT = config.get(configSection, 'SOAP_SERVER_PORT')
49
50def callControllerDirectly(argList):
51    """
52    Function wrapper to Controller class. This can be called directly
53    to perform all operations or the other Web Service methods can be
54    called in the appropriate order.
55    """   
56    # Parse startTime and endTime arguments into expected form
57    for key, value in argList:
58        args[key]=value
59        for ts in ("start", "end"):
60            if key.find("%sTime_" % ts)>-1:
61                timeComponents=time.strp(value, "%Y-%m-%d %H:%M:%S")[:6]
62       
63                for tk in TIME_KEYS:
64                    # Set each component e.g. startYear_1, endHour_2
65                    args["%s%s_%s" % (ts, tk, key.split("_")[-1])]=timeComponents[TIME_KEYS.index(tk)]
66
67    # Parse horizontalDomain argumnets into expected form
68    if args.has_key("horizontalDomain"):
69        for hk in HORIZ_KEYS:
70            args[hk]=args["horizontalDomain"][HORIZ_KEYS.index(hk)]
71                       
72    return Controller(args)
73
74
75def getStatus(sessionID, secureToken="undefined"):
76    """
77    Returns the status of a request.
78    """
79    print "\nMethod called: getStatus\n"
80    args={"sessionID":sessionID, "secureToken":secureToken, "action":"getStatus"}
81
82    try:
83        controller=DXController(args)
84    except Exception, error:
85        return str(error)
86
87    if hasattr(controller, "fork") and controller.fork==1:
88         print "CLEAN EXIT?"
89         os._exit()
90
91    status=controller.status
92    errorString=getattr(controller, "errorString", "")
93    print controller.__dict__
94    outputFilePaths=controller.bag["outputFilePaths"]
95
96    secureToken=controller.secureToken
97    return [[status], [errorString], [outputFilePaths], [secureToken]]
98
99
100def startSession(username="undefined", password="undefined", secureToken="undefined"):
101    """
102    Logs a user in and supplies them with a session ID as well
103    as an encoded security token. The session ID connects them to their
104    current request serverside whilst the security token is used to
105    authorise their access.
106    """
107    print "\nMethod called: startSession\n"
108    args={"username":username, "password":password, "secureToken":secureToken} 
109       
110    try:
111        controller=DXController(args)
112    except Exception, error:
113        print "QQQQQQQQQQQQQQQQQQQQQQQQQ"
114        return str(error)           
115       
116    sessionID=controller.bag["sessionID"]
117    secureToken=controller.secureToken
118    # Have to return list of lists for ZSI to work (?!)
119
120    print sessionID, secureToken
121    return [sessionID, secureToken]
122       
123
124def getOptions(sessionID, secureToken="undefined", optionCategoryRequested="undefined"):
125    """
126    Returns a category description of the next set of options (or the option category
127    requested by the user), a list of options based
128    on what the user has yet to request, a string explaining some more about this and a
129    security token.
130   
131    The options will be presented following the heirarchy:
132        DatasetGroups
133        Datasets
134        Variables
135        HorizontalDomain
136        VerticalDomain
137        TemporalDomain
138        OutputFormat
139    """   
140    print "\nMethod called: getOptions\n"
141    print "ARGS: sessionID: %s\nsecureToken: %s, optionCategoryRequested:%s" %        (sessionID, secureToken, optionCategoryRequested)
142    if type(sessionID)==type(u""):
143        sessionID=deUnicodeObject(sessionID)
144       
145    args={"sessionID":sessionID, "secureToken":secureToken, 
146                "optionCategoryRequested":optionCategoryRequested}
147
148    try:
149        controller=DXController(args)
150    except Exception, error:
151        return str(error)
152 
153    optionsObject=controller.options
154    secureToken=controller.secureToken
155    print "Options object:", optionsObject
156
157    summaryString=createSummaryString(controller.bag)
158
159    return [[optionsObject+[summaryString]+[secureToken]]]
160
161
162def selectOptions(sessionID, argList):
163    """
164    Makes a selection based on user requirements. This will typically follow a call
165    to getOptions() to find out what the options are.
166    Returns a call to getOptions() to grab the next set of options available to the
167    user. Alternatively, if it fails, an errorString is returned.
168    """
169    print "\nMethod called: selectOptions\n"   
170    if type(sessionID)==type(u""):
171        sessionID=deUnicodeObject(sessionID)
172    args={"sessionID":sessionID}
173   
174    print "Key, Value..."
175    for key,value in argList:
176        key=deUnicodeObject(key)
177        value=deUnicodeObject(value)
178        if type(key)==type(u""):
179            newkey=str(key)
180        else:
181            newkey=key
182        if type(value)==type(u""):
183            value=str(value)
184        args[newkey]=value   
185        print newkey, value
186
187    try:
188        controller=DXController(args)
189    except Exception, error:
190        try:
191            e0=error[0]
192            if type(e0)==type("jljl") and len(e0)>1:
193                error=e0
194        except:
195            pass
196        return str(error)
197   
198    optionsObject=controller.options
199    secureToken=controller.secureToken
200    print "Options object:", optionsObject
201
202    summaryString=createSummaryString(controller.bag)
203
204    return [[optionsObject+[summaryString]+[secureToken]]]
205    """secureToken=controller.secureToken       
206   
207    if args.has_key("optionCategoryRequested"):
208        optionCategoryRequested=args["optionCategoryRequested"]
209    else:
210        optionCategoryRequested="undefined"
211
212    opts=getOptions(sessionID, secureToken, optionCategoryRequested)
213    print "\n\nReturned from select options:\n", opts, "\n\n"
214    return opts"""
215 
216   
217def isComplete(sessionID, secureToken="undefined"):
218    """
219    Returns 1 if the request is complete (i.e. ready to create output file(s))
220    and 0 if not. Also returns a security token.
221    """
222    print "\nMethod called: isComplete\n"
223    optionsObject=getOptions(sessionID, secureToken)
224    secureToken=optionsObject[-1]
225    if optionsObject==[secureToken]:
226        return [[1], secureToken]
227    else:
228        return [[0], secureToken] 
229   
230
231def createOutput(sessionID, secureToken="undefined"):
232    """
233    Creates the outputs specified by user selections. It writes these files
234    locally and returns a list of paths to the data as either FTP or HTTP
235    locations.
236    Returns a list of paths and a security token.
237    """
238    print "\nMethod called: createOutput\n"
239    args={"sessionID":sessionID, "secureToken":secureToken, "getOutput":"getOutput"}
240     
241    try:
242        controller=DXController(args)
243    except Exception, error:
244        return str(error)
245
246    if hasattr(controller, "fork") and controller.fork==1:
247         print "CLEAN EXIT?"
248         os._exit()
249   
250    secureToken=controller.secureToken
251    print controller.bag
252    pathList=controller.bag["outputFilePaths"]
253
254
255    return [pathList, secureToken]
256
257
258def newSession(sessionID, secureToken="undefined"):
259    """
260    Deletes content of current request.
261    Returns the sessionID and the security token..
262    """
263    print "\nMethod called: newSession\n"   
264    args={"sessionID":sessionID, "secureToken":secureToken, "clearSession":"clearSession"}
265     
266    try:
267        controller=DXController(args)
268    except Exception, error:
269        return str(error) 
270   
271    secureToken=controller.secureToken
272    return [[sessionID], [secureToken]]
273
274
275def setNumberOfDatasets(sessionID, n, secureToken="undefined"):
276    """
277    Re-selects the number of datasets the user wants to deal with in the request.
278    Default is 1.
279    Returns 1 if successful and an errorString if not, as well as a security token.
280    """
281    print "\nMethod called: setNumberOfDatasets\n"
282   
283    args={"sessionID":sessionID, "numberOfDatasets":n, "secureToken":secureToken}
284
285    try:
286        controller=DXController(args)
287    except Exception, error:
288        return str(error)   
289
290    secureToken=controller.secureToken
291    return [[1], [secureToken]]
292       
293       
294def summariseRequest(sessionID, secureToken="undefined"):
295    """
296    Returns a listing of the current request in a string and a security token.
297    """   
298    print "\nMethod called: summariseRequest\n"
299    args={"sessionID":sessionID, "secureToken":secureToken}
300   
301    try:
302        controller=DXController(args)
303    except Exception, error:
304        return str(error)   
305
306    #req=controller.bag
307    summaryString=createSummaryString(controller.bag)
308    """summaryString="\n"+"*"*40
309    summaryString=summaryString+"\nSummary of current request follows\n"
310    summaryString=summaryString+"*"*40+"\n\n"
311   
312    exclusions=("callMethod", "secureToken", "optionCategoryRequested",
313                "action", "targetPage")
314               
315    for key in req.keys():
316        if req[key]!="" and key not in exclusions: 
317            summaryString=summaryString+("%s:\t%s\n" % (key, req[key]))"""
318
319    print "\n"*10, summaryString
320    secureToken=controller.secureToken 
321    return [[summaryString], [secureToken]]
322     
323
324def uploadRequest(sessionID, requestXMLString, secureToken="undefined"):
325    """
326    Allows the user to send a request in the form of a string containing the
327    contents of an XML file conforming to the dx request specification (not
328    yet written). This is also called a Data Subset Specifier.
329    This function parses the XML into a dictionary and then uploads the arguments.
330    Returns a status flag (1=success, None=failure) and the secure token.
331    """
332    print "Calling: uploadRequest\n"
333   
334    try:
335        args=DXRMLParser(requestXMLString).getDictionary()
336    except DXError, error:
337        return "Error parsing the Request XML file you provided:   \n"+str(error)       
338    except Exception, error:
339        return "Error parsing the Request XML file you provided:   \n"+str(error)
340       
341    args["sessionID"]=sessionID
342    args["secureToken"]=secureToken
343   
344    try:
345        controller=DXController(args)
346    except Exception, error:
347        return [[0], [secureToken]]   
348             
349    secureToken=controller.secureToken 
350    return [[1], [secureToken]]
351
352
353def getDataSubsetSpecifier(sessionID, secureToken="undefined"):
354    """
355    Returns the dataSubsetSpecifier XML document (which might be S-metadata)
356    required by a Delivery Service to describe the subset requested, and a
357    security token.
358    """
359    print "\nMethod called: getDataSubsetSpecifier\n"
360    args={"sessionID":sessionID, "secureToken":secureToken}
361   
362    try:
363        controller=DXController(args)
364    except Exception, error:
365        return str(error)     
366   
367    secureToken=controller.secureToken
368    sessionObj=controller.bag
369   
370    try:
371        dataSubsetSpecifierXMLString=DXRMLGenerator(sessionObj).xmlString
372    except Exception, error:
373        return "Could not provide the Request XML string:   "+str(error)
374   
375    print dataSubsetSpecifierXMLStringprint
376    return [[dataSubsetSpecifierXMLString], [secureToken]]
377
378
379def getExtractionCosts(sessionID, secureToken="undefined"):
380    """
381    Returns an estimated duration for the creation of the output data and the
382    estimated volume of the output.
383    """
384    print "\nMethod called: getExtractionCosts\n"   
385    args={"sessionID":sessionID, "secureToken":secureToken, "action":"requestCosts"}
386   
387    try:
388        controller=DXController(args)
389    except Exception, error:
390        print "STOPPED HERE..."
391        return str(error)   
392
393    print "TESTTEST"       
394    secureToken=controller.secureToken
395    (estimatedDuration, estimatedVolume)=(controller.bag["estimatedDuration"], controller.bag["estimatedVolume"])
396    print "Returning...", [estimatedDuration, estimatedVolume, secureToken]
397
398
399    return [estimatedDuration, estimatedVolume, secureToken]       
400
401
402def getDatasetGroupOptions(sessionID, secureToken="undefined"):
403    """
404    Get the dataset group options available.
405    """
406    print "\nMethod called: getDatasetGroupOptions\n\n"
407    return getOptions(sessionID, secureToken="undefined", optionCategoryRequested="datasetGroup")
408   
409
410def makeDatasetGroupSelections(sessionID, secureToken, datasetGroupList):
411    """
412    Make selections for dataset group.
413    """
414    print "Called: makeDatasetGroupSelections\n"
415    argList=[]
416    argList.append(["secureToken", secureToken])
417    counter=1
418    for selection in datasetGroupList:
419        argList.append(["datasetGroup_%s" % counter, selection])
420        counter=counter+1
421       
422    return selectOptions(sessionID, argList)
423
424
425def getDatasetOptions(sessionID, secureToken="undefined"):
426    """
427    Get the dataset options available.
428    """
429    print "\nMethod called: getDatasetOptions\n\n"
430    return getOptions(sessionID, secureToken="undefined", optionCategoryRequested="dataset")
431   
432   
433def makeDatasetSelections(sessionID, secureToken, datasetList):
434    """
435    Make selections for Dataset.
436    """
437    print "Called: makeDatasetSelections\n"
438    argList=[]
439    argList.append(["secureToken", secureToken])
440    counter=1
441    for selection in datasetList:
442        argList.append(["dataset_%s" % counter, selection])
443        counter=counter+1
444       
445    return selectOptions(sessionID, argList)
446
447
448def getVariableOptions(sessionID, secureToken="undefined"):
449    """
450    Get the variable options available.
451    """
452    print "\nMethod called: getVariableOptions\n\n"
453    return getOptions(sessionID, secureToken="undefined", optionCategoryRequested="variable")
454   
455   
456def makeVariableSelections(sessionID, secureToken, variableList):
457    """
458    Make selections for variables.
459    """
460    print "Called: makeVariableSelections\n"
461    argList=[]
462    argList.append(["secureToken", secureToken])
463    counter=1
464    for selection in variableList:
465        argList.append(["variable_%s" % counter, selection])
466        counter=counter+1
467       
468    return selectOptions(sessionID, argList)
469   
470
471if __name__=="__main__": 
472    main()
473   
474def main(args=None):
475    if not args:
476        args = sys.argv[1:]
477
478    config.read(args[0])
479   
480    # Serve all functions as Web Service methods.   
481    print "Setting up server"
482    print "Serving Web Service on port: %s" % SOAP_SERVER_PORT
483    dispatch.AsServer(port=SOAP_SERVER_PORT, rpc=True)   
Note: See TracBrowser for help on using the repository browser.