source: MILK/trunk/milk_server/milk_server/lib/ndgInterface.py @ 4535

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/MILK/trunk/milk_server/milk_server/lib/ndgInterface.py@4535
Revision 4535, 5.4 KB checked in by cbyrom, 11 years ago (diff)

Generalise existing methods to allow data entities to be looked up with
the same code as associated deployments data + add new templates to
display the DEs + extend the javascript to allow multiple callbacks
to retrieve the info + various tidy ups and fixes.

Line 
1# Copyright (C) 2007 STFC & NERC (Science and Technology Facilities Council).
2# This software may be distributed under the terms of the
3# Q Public License, version 1.0 or later.
4# http://ndg.nerc.ac.uk/public_docs/QPublic_license.txt
5"""
6Manages interface to NDG documents and data, including caching
7"""
8
9from cache import Cache
10from csml_cache import CSMLExtractCache
11import os, logging
12from ndgUtils import ndgRetrieve, ndgObject, xmlHandler2
13from pylons import request, session
14
15from pylons import g # for handle to access control PEP interface
16try:
17    from ndg.security.common.authz.pdp import PDPError
18    from ndg.security.common.authz.pep import PEPError
19except ImportError, e:
20    from warnings import warn
21    warn(__name__ + ": access control is disabled: %s" % e, RuntimeWarning)
22
23class ndgInterface:
24   
25    def __init__(self):
26        ''' Instantiate with three level cache:
27                - a file cache
28                - a xmlhandler object cache, and
29                - a parsed CSML object cache.'''
30
31        self.CSMLDataCache=CSMLExtractCache(
32                request.environ['paste.config']['app_conf']['tmp_dir'],max_size=10)
33        self.CSMLDocCache=Cache(max_size=10)
34        self.XMLHCache=Cache(max_size=10)
35       
36
37    def GetXML(self,uri,outputSchema='', useCache=True):
38        '''
39        This method provides a secure interface to the server
40        document cache and a remote NDG exist. It is assumed that
41        the local filesystem is protected in that you can't get to
42        files except via the CSML api
43        @param uri: ndg format uri to locate doc from
44        @keyword outputSchema: format to return doc in
45        @keyword useCache: check for data in the cache and use this, if set to
46        True (the default)   
47        '''
48        #    Note that this method should not be used to obtain
49        #unsecured discovery documents, these are called directly
50        #in the retrieve controller!
51
52        logging.info("Getting XML from uri, '%s' (outputschema: '%s')" \
53                     %(uri, outputSchema))
54        try:
55            ndgO=ndgObject(uri)
56            localFile=0
57        except ValueError:
58            ''' It's a local file not an ndg identifier '''
59            logging.info("File appears to be local - look for it there...")
60            ndgO=uri
61            localFile=1
62       
63        if session and 'ndgCleared' in session:
64            cleared=session['ndgCleared']
65        else:
66            cleared=None
67       
68        if outputSchema or not useCache:
69            #bypass the cache ...
70            status,xmlh=ndgRetrieve(ndgO,
71                                    request.environ['ndgConfig'],
72                                    output=outputSchema,
73                                    discovery=g.standalone)
74        else:
75            try:
76                xmlh=self.XMLHCache[uri]
77                status=1
78                logging.info('XMLH Cache hit for [%s]'%uri)
79            except:
80                logging.info('XMLH Cache miss for [%s]'%uri)
81                if localFile:
82                    status,xmlH=self.__getLocal(uri)
83                else:   
84                    status,xmlh=ndgRetrieve(ndgO,
85                                            request.environ['ndgConfig'],
86                                            output=outputSchema,
87                                            discovery=g.standalone)
88                if status: 
89                    self.XMLHCache[uri]=xmlh
90           
91        if not status: return status,xmlh
92       
93        # convert doc to an XML tree
94        xmlh=xmlHandler2.xmlHandler(xmlh,string=1)
95       
96        # valid values of the return objects SHOULD BE
97        #   ok:         status=1, xmlh=an xml handler instance.
98        #   exceptions, status=0, xmlh='Exception(e)'
99       
100        status,xmlh=self.__gatekeep(ndgO,xmlh)
101        if status:
102            if cleared is None:
103                session['ndgCleared']=[uri]
104            else:
105                session['ndgCleared'].append(uri)
106            session.save()
107       
108        return status,xmlh
109           
110
111    def __gatekeep(self,uri,x):
112        ''' This is the NDG gatekeeper '''
113        if 'ndgSec' in session:
114            securityTokens=session['ndgSec']
115        else:
116            securityTokens=None
117
118        if not hasattr(g, 'pep'):
119            if not g.standalone:
120                raise PEPError(\
121                "Security is disabled but the standalone flag is set to False")
122               
123            logging.info("__gatekeep: access control is disabled - standalone " + \
124                     "config flag is set")
125           
126        try:
127            # Arguments are: a handle to the resource and a handle to the users
128            # security tokens
129            g.pep(dict(uri=uri, doc=x), securityTokens, None)
130            return True, x
131       
132        except PDPError, e:
133            # Caught a known access control condition
134            return False, 'Access Denied for %s %s' % (uri, e)
135
136               
137    def __getLocal(self,uri):
138        ''' Returns a local csml file (used for testing) '''
139        csml_dir = request.environ['paste.config']['app_conf']['csml_dir']
140        path = os.path.join(csml_dir, file)
141        if os.path.exists(path+'.csml'):
142            f = path+'.csml'
143        elif os.path.exists(path+'.xml'):
144            f = path +'.xml'
145        else:
146            return 0, '<p>Cannot find CSML file %s</p>' % file
147        r=f.read()
148        return 1,r     
149       
150
151
152interface=ndgInterface()
Note: See TracBrowser for help on using the repository browser.