source: TI05-delivery/ows_framework/branches/ows_framework-refactor/ows_common/ows_common/pylons/ows_controller.py @ 3372

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI05-delivery/ows_framework/branches/ows_framework-refactor/ows_common/ows_common/pylons/ows_controller.py@3372
Revision 3372, 5.3 KB checked in by spascoe, 13 years ago (diff)

Removed most of the decorator stuff. Use OwsController? methods to deal with parameters instead.

Line 
1"""
2Base controller for OGC Web Services (OWS).
3
4@author: Stephen Pascoe
5@todo: Add pluggable security so replicate what was previously implemented
6    for the NDG discovery portal in ows_server.lib.BaseController.
7"""
8
9
10from pylons import request, response, config
11from pylons.controllers import WSGIController
12from pylons.templating import render
13
14from ows_common import exceptions as OWS_E
15from ows_common.util import negotiate_version
16from ows_common.pylons.decorators import ows_operation
17
18# Import exceptions template
19# This won't work if you haven't enabled Kid importing (already done by pylons)
20from ows_common.pylons.templates import exception_report
21
22try:
23    from xml.etree import ElementTree as ET
24except ImportError:
25    from elementtree import ElementTree as ET
26
27import logging
28logger = logging.getLogger(__name__)
29
30# Configure
31#!TODO: rename this configuration object to something non-NDG specific
32#EXCEPTION_TYPE = request.environ['ndgConfig'].get('OWS_SERVER', 'exception_type', 'ogc').lower()
33EXCEPTION_TYPE = config.get('ows_server.exception_type', 'ogc')
34
35
36class OwsControllerBase(WSGIController):
37    """
38    @ivar owsParams: A dictionary of parameters passed to the service.  Initially these
39        comes from the query string but could come from a HTTP POST in future.
40    """
41    def __call__(self, environ, start_response):
42
43        self._loadOwsParams()
44
45        # If the EXCEPTION_TYPE is 'pylons' let Pylons catch any exceptions.
46        # Otherwise send an OGC exception report for any OWS_E.OwsError
47        if 'pylons' in EXCEPTION_TYPE:
48            self._fixOwsAction(environ)
49            return super(OwsControllerBase, self).__call__(environ, start_response)
50        else:
51            try:
52                self._fixOwsAction(environ)
53                return super(OwsControllerBase, self).__call__(environ, start_response)
54            except OWS_E.OwsError, e:
55                logger.exception(e)
56
57                response.write(exception_report.serialize(report=e.report))
58                response.headers['content-type'] = 'text/xml'
59                return response
60
61    def _loadOwsParams(self):
62        # All OWS parameter names are case insensitive.
63        self._owsParams = {}
64        for k in request.params:
65            self._owsParams[k.lower()] = request.params[k]
66
67    def _fixOwsAction(self, environ):
68        rdict = environ['pylons.routes_dict']
69       
70        # Override the Routes action from the request query parameter
71        action = self.getOwsParam('request')
72
73        # Check action is a method in self and is defined as an OWS operation
74        try:
75            op = getattr(self, action)
76            name = op._ows_name
77        except AttributeError:
78            raise OWS_E.InvalidParameterValue('request=%s not supported' % action,
79                                              'REQUEST')
80        rdict['action'] = action
81
82    def getOwsParam(self, param, **kwargs):
83        """
84        Returns the value of a OWS parameter passed to the operation.
85        If argv['default'] is given it is taken to be the default
86        value otherwise the parameter is treated as manditory and an
87        exception is raised if the parameter is not present.
88
89        """
90        try:
91            return self._owsParams[param.lower()]
92        except KeyError:
93            if 'default' in kwargs:
94                return kwargs['default']
95            else:
96                raise OWS_E.MissingParameterValue('%s parameter is not specified' % param,
97                                                  param)
98
99
100class OwsController(OwsControllerBase):
101    """
102    Adds basic GetCapabilities response to OwsControllerBase.
103
104    @cvar validVersions: A list of version numbers supported bu this OWS.
105   
106    """
107
108    validVersions = NotImplemented
109
110    def getUpdateSequence(self, uri):
111        """
112        Override in subclasses to return a valid updateSequence for the uri.
113        """
114        return None
115
116    def getCapabilitiesTemplate(self, version, format):
117        """
118        Get the capabilities template.
119        Override in subclases to return a valid template name.
120
121        @param version: the version as a sequence of numbers
122        @param format: the format as a string
123       
124        @return: a template as expected  by pylons.render()
125        """
126        raise NotImplementedError
127
128   
129    @ows_operation
130    def GetCapabilities(self, url, service, version=None, format='text/xml',
131                        updatesequence=None):
132
133        # Retrieve Operation parameters
134        service = self.getOwsParam('service')
135        version = self.getOwsParam('version', default=None)
136        format = self.getOwsParam('format', default='text/xml')
137        updatesequence = self.getOwsParam('updatesequence', default=None)
138
139        # Check update sequence
140        serverUpdateSequence = self.getUpdateSequence(uri)
141        if updatesequence and serverUpdateSequence:
142            if updatesequence == serverUpdateSequence:
143                raise OWS_E.CurrentUpdateSequence
144            elif updatesequence > serverUpdateSequence:
145                raise OWS_E.InvalidUpdateSequence
146
147        # Do version negotiation
148        version = negotiate_version(version, self.validVersions)
149           
150        # Render the capabilities document
151        response.headers['content-type'] = format
152        return render(self.getCapabilitiesTemplate(version, format),
153                      format='xml')
154       
155
Note: See TracBrowser for help on using the repository browser.