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

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@3364
Revision 3364, 4.5 KB checked in by spascoe, 12 years ago (diff)

Moving exception template to ows_common

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
18try:
19    from xml.etree import ElementTree as ET
20except ImportError:
21    from elementtree import ElementTree as ET
22
23import logging
24logger = logging.getLogger(__name__)
25
26# Configure
27#!TODO: rename this configuration object to something non-NDG specific
28#EXCEPTION_TYPE = request.environ['ndgConfig'].get('OWS_SERVER', 'exception_type', 'ogc').lower()
29EXCEPTION_TYPE = config.get('ows_server.exception_type', 'ogc')
30
31
32class OwsControllerBase(WSGIController):
33    def __call__(self, environ, start_response):
34
35        # All OWS parameter names are case insensitive.
36        self.ows_params = {}
37        for k in request.params:
38            self.ows_params[k.lower()] = request.params[k]       
39
40        # If the EXCEPTION_TYPE is 'pylons' let Pylons catch any exceptions.
41        # Otherwise send an OGC exception report for any OWS_E.OwsError
42        if 'pylons' in EXCEPTION_TYPE:
43            self._fixOwsAction(environ)
44            return super(OwsController, self).__call__(environ, start_response)
45        else:
46            try:
47                self._fixOwsAction(environ)
48                return super(OwsController, self).__call__(environ, start_response)
49            except OWS_E.OwsError, e:
50                logger.exception(e)
51
52                r=render('exception_report', report=e.report, format='xml')
53                r.headers['content-type'] = 'text/xml'
54                return r
55
56
57    def _fixOwsAction(self, environ):
58        # Override the Routes action from the request query parameter
59        try:
60            action = self.ows_params['request']
61        except KeyError:
62            raise OWS_E.MissingParameterValue('REQUEST parameter not specified',
63                                              'REQUEST')
64
65        # Check action is a method in self and is defined as an OWS operation
66        try:
67            op = getattr(self, action)
68            name = op._ows_name
69        except AttributeError:
70            raise OWS_E.InvalidParameterValue('request=%s not supported' % action,
71                                              'REQUEST')
72
73        # Check all required parameters are present
74        for param in op._ows_required_parameters:
75            if param.lower() not in self.ows_params:
76                raise OWS_E.MissingParameterValue('%s parameter not specified'%param,
77                                                  param)
78
79        # override routes action with request
80        environ['pylons.routes_dict']['action'] = action
81        del self.ows_params['request']
82
83
84
85class OwsController(OwsControllerBase):
86    """
87    Adds basic GetCapabilities response to OwsControllerBase.
88
89    @cvar validVersions: A list of version numbers supported bu this OWS.
90   
91    """
92
93    validVersions = NotImplemented
94
95    def getUpdateSequence(self, uri):
96        """
97        Override in subclasses to return a valid updateSequence for the uri.
98        """
99        return None
100
101    def getCapabilitiesTemplate(self, version, format):
102        """
103        Get the capabilities template.
104
105        @param version: the version as a sequence of numbers
106        @param format: the format as a string
107       
108        @return: a template as expected  by pylons.render()
109        """
110        raise NotImplementedError
111
112   
113    @ows_operation(['service'], ['version', 'format', 'updateSequence'])
114    def GetCapabilities(self, url, service, version=None, format='text/xml',
115                        updatesequence=None):
116
117        # Check update sequence
118        serverUpdateSequence = self.getUpdateSequence(uri)
119        if updatesequence and serverUpdateSequence:
120            if updatesequence == serverUpdateSequence:
121                raise OWS_E.CurrentUpdateSequence
122            elif updatesequence > serverUpdateSequence:
123                raise OWS_E.InvalidUpdateSequence
124
125        # Do version negotiation
126        version = negotiate_version(version, self.validVersions)
127           
128        # Render the capabilities document
129        response.headers['content-type'] = format
130        return render(self.getCapabilitiesTemplate(version, format),
131                      format='xml')
132       
133
Note: See TracBrowser for help on using the repository browser.