source: TI03-DataExtractor/branches/titania_install/pygss/GSController.py @ 1520

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI03-DataExtractor/branches/titania_install/pygss/GSController.py@1610
Revision 1520, 10.7 KB checked in by astephen, 14 years ago (diff)

This is the live version on titania - changes have been made so safest to SVN it.

Line 
1#   Copyright (C) 2004 CCLRC & NERC( Natural Environment Research Council ).
2#   This software may be distributed under the terms of the
3#   Q Public License, version 1.0 or later. http://ndg.nerc.ac.uk/public_docs/QPublic_license.txt
4
5"""
6GSController.py
7===============
8
9The core class for controlling the package.
10
11"""
12
13# Import required modules
14import sys
15import os 
16import time 
17
18# Bring package into local scope
19#from serverConfig import BASEDIR
20#sys.path.insert(0, os.path.split(BASEDIR)[0])
21from pygss import *
22
23 
24# Add any other locally required directories in which you have modules.
25#for path in LOCAL_PYTHONPATH:
26#   sys.path.insert(0, path) 
27
28# Add BADC Security
29sys.path.append("/home/badc/software/pythonlib/badc")
30from BADCServerSecurity import *
31
32
33
34class GSController:
35    """
36    Controls the overall process flow of the a session.
37    This class is called through each stage of the interactive process
38    and responds according to the environment and arguments provided.
39    Note that this class is called by the WSInterface
40    class which then reads various instance variables. As a result, very
41    little is returned from the methods below. Instead the data is stored
42    in the instance object.
43    """
44   
45    def __init__(self, args):
46        """
47        Takes in a group of arguments and then calls the appropriate
48        methods to process the user request.
49        """
50        self.username="undefined" 
51        self.password="undefined"
52        self.userRoles=[]
53        self.sessionID=None
54        self.sessionObj=None
55        self.bag=self.sessionObj # alias       
56        self.secureToken="undefined"
57        self.error=None
58   
59        # Parse the arguments
60        try:
61            self._parseArgs(args)
62        except Exception, error:
63            raise Exception, error
64
65        print "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"     
66        # If switched on check security       
67        if self.error==None:
68            if RESTRICTED_DATA==1:
69                try:
70                    self._checkSecurity()
71                except Exception, error:
72                    raise Exception, error   
73            else:
74                self.secureToken="undefined"
75
76        print "JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ"             
77        # Construct the session object
78        if self.error==None:   
79            try:   
80                self._constructSessionObject()   
81            except Exception, error:
82                raise Exception, error
83
84        # Generate the options object
85        if self.error==None:   
86            try:   
87                self._generateOptions()   
88            except Exception, error:
89                raise Exception, error         
90
91        print "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL"
92        # Write request to a file if it has some content
93        if self.error==None:
94          if overlap(["dataset_1", "variable_1", "sessionID", "numberOfDatasets"], 
95                      self.bag.keys()):                       
96            self.bag["accessTime"]=time.time()             
97            self.sessionObjectManager.writeSessionObject(self.bag) 
98   
99            # Validate the selection against known information
100            try:           
101                self._validate()                   
102            except Exception, error:
103                raise Exception, error
104           
105        print "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"
106        # Estimate the cost of the extraction
107        creditChecked=None
108        if self.error==None:   
109          if self.bag.has_key("action") and self.bag["action"]=="checkCredit":     
110            # Check user has sufficient credit
111            try:           
112                self._checkCredit()   
113                creditChecked="yes"                 
114            except Exception, error:
115                raise Exception, error
116
117        # Estimate the cost of the extraction
118        if self.error==None:   
119          if self.bag.has_key("action") and self.bag["action"]=="requestCosts":
120           
121            try:
122                (self.estimatedDuration, self.estimatedVolume)=self._createOutput(costOnly=1)
123                sizeLimitInBytes=REQUEST_SIZE_LIMIT*2L**20
124                # If size is over limit then send a tidy error to the user
125                if self.estimatedVolume>sizeLimitInBytes:
126                    sizeInMB=self.estimatedVolume/(2L**20.)
127                    err="""Your request of %.1f MB is over the current %s MB size limit.       
128The Data Extractor cannot yet deal with such large requests.
129Consider mailing <A HREF="mailto:%s">%s</A> for advice or submit multiple smaller requests.""" % (sizeInMB, 
130                               REQUEST_SIZE_LIMIT, ADMIN_MAIL_ADDRESS, ADMIN_MAIL_ADDRESS)     
131                    errorCatcher=ErrorHandler(None, self.username, self.sessionID)
132                    self.error=errorCatcher.displayError(err)
133                    sys.exit() 
134            except Exception, error:
135                raise Exception, error
136
137        # Process the selections to generate some data
138        if self.error==None:   
139            if (self.bag.has_key("getOutput") or (self.bag.has_key("action") and self.bag["action"]=="createOutput")) and creditChecked==None:
140                # Check user has sufficient credit
141                try:       
142                    self._checkCredit()                     
143                except Exception, error:
144                    raise Exception, error
145                           
146                try:       
147                    self._createOutput()           
148                    self.logger=LogManager(self.bag)       
149                    self.bag["status"]="complete"       
150                    self.logger.logCompletedRequest(self.bag["outputFilePath"])         
151                except Exception, error:
152                    raise Exception, error
153   
154        if self.error==None:
155            print "Saving session details:\n", self.bag, "\n\n" 
156            if self.bag.has_key("action") and self.bag["action"]=="clearRequest":
157                del self.bag["action"]
158            elif self.bag.has_key("action") and self.bag["action"]=="createOutput":
159                del self.bag["action"]
160            elif self.bag.has_key("getOutput"):
161                del self.bag["getOutput"]
162            self.sessionObjectManager.writeSessionObject(self.bag)
163        else:
164            self.logger=LogManager(self.bag) 
165            self.logger.logError(self.error)
166         
167           
168    def _parseArgs(self, args):
169        """
170        Parses the argument dictionary that are sent.
171        """                     
172        self.args={}
173        for key, value in args.items():
174            if type(key)==type(u""):
175                newkey=str(key)
176            else:
177                newkey=key
178                   
179            if type(value)==type(u""):
180                newvalue=str(value)
181            else:
182                newvalue=value
183               
184            self.args[newkey]=newvalue
185           
186   
187        for item in ("username", "password", "secureToken"):
188            if self.args.has_key(item):             
189                value=self.args[item]               
190                setattr(self, item, value)
191                del self.args[item]
192               
193        print "ARGS and SecureToken:", self.args, self.secureToken
194
195
196    def _checkSecurity(self):
197        """
198        Checks security by getting username and
199        allowed groups from whatever implementation you have put in place.
200        """
201        if SECURITY_MODEL=="basic":
202            secChecker=SecurityManager(self.username, self.password, self.secureToken)
203        elif SECURITY_MODEL=="badc":
204            secChecker=BADCServerSecurity(self.username, self.password, self.secureToken)
205        elif SECURITY_MODEL=="ndg":
206            secChecker=NDGSecurityManager(self.username, self.password, self.secureToken)
207        else:
208            raise DXSecurityError, "Security model '%s' not supported." % SECURITY_MODEL
209
210        # Do something about logout here as well
211
212        secCheck=secChecker.validateUser()
213        self.username=secChecker.username
214
215        if type(secCheck)==type(""):
216            raise DXSecurityError, secCheck
217        elif type(secCheck)==type([]):
218            (self.secureToken, self.userRoles)=secCheck
219        else:
220            raise DXSecurityError, str(secCheck)+str(type(secCheck))#"No response from Security class!"
221                             
222
223    def _constructSessionObject(self):
224        """
225        Ensures that all appropriate arguments are being written
226        to the session object in the correct manner. Note that the
227        session object "sessionObj" is just a dictionary but is read
228        in from a shelve object (if it exists already).
229        """     
230        # self.args now holds the input arguments
231        if not self.args.has_key("sessionID"): 
232            self.sessionObjectManager=SessionObject()
233            self.bag=self.sessionObjectManager.dict
234            #self.sessionObj["targetPage"]=STAGES=[0]
235        else: 
236            self.sessionObjectManager=SessionObject(self.args["sessionID"]) 
237            self.bag=self.sessionObjectManager.readSessionObject() 
238            # Clear the session object if requested
239            if self.args.has_key("clearRequest") or self.args.has_key("newRequest"):
240                self.sessionObjectManager.clearSessionObject(self.bag) 
241               
242        if type(self.sessionID)==type(u""):
243            self.sessionID=str(self.sessionID) 
244               
245        # Update session object with allowed roles at each stage (this is checked every reload)
246        self.bag["userRoles"]=self.userRoles
247
248        # Say it is under construction at present
249        self.bag["status"]="constructing"
250       
251        # Add the rest of the arguments to the session object
252        for key in self.args.keys(): 
253            self.bag[key]=self.args[key] 
254
255        # Might need username later
256        if self.bag.has_key("username"):
257            self.username=self.bag["username"]
258        else:
259            self.bag["username"]=self.username
260   
261
262    def _generateOptions(self):
263        """
264        Method that examines the current status of the request to create an appropriate
265        list of options for the user. Made up of many if clauses to control a logical
266        response to the current request.
267        """
268        if keyPatternMatch(self.bag, "fileURI")==0:
269            print self.bag
270            self.options={"AWAITING_FILEURIS":"AWAITING_FILEURIS"}
271            return
272           
273        self.options=OptionHandler(self.username, self.bag["userRoles"], self.bag).options         
274        return
275       
276       
277    def _validate(self):
278        """
279        Validates the selections made by the user. Returns 1 if successful
280        and a string if failure.
281        """
282        validater=ValidateSelection(self.bag)
283        validResponse=validater.validate()
284        if validResponse!=1:
285            raise validResponse
286           
287     
288    def _checkCredit(self):
289        """
290        Checks if the user has the available credit to the selection task. Returns 1 if successful
291        and a string if failure.
292        """
293        creditChecker=CreditManager(self.username, self.bag)
294        creditResponse=creditChecker.creditCheck()
295        if creditResponse!=1:
296            raise creditResponse
297           
298           
299    def _createOutput(self, costOnly=None):
300        """
301        Creates either data file.
302        """   
303        if costOnly==1:
304            requestCoster=RequestCost(self.bag) 
305            return requestCoster.getDurationAndVolume()                     
306
307        # Now really get data...
308        outman=OutputManager(self.bag) 
309
310        if outman.textOnly:
311            print "FOUND POINT VALUE OUTPUT - send to client."
312            self.message=outman.textOnly
313            # Fill in some request values needed by logger
314            for key in ["outputFilePath", "fileFormat"]:
315                self.bag[key]="NOT_APPLICABLE"     
316            return
317       
318        print """Should really fork this process at this point so that we can return
319              something if likely to be large job."""
320        try:
321            outman.createOutputs() 
322        except:
323            raise Exception, "Problem generating requested output file."
324
325        self.bag["outputFilePath"]=outman.localPath       
326        self.bag["outputURLPath"]=outman.URLPath
327   
Note: See TracBrowser for help on using the repository browser.