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

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@3257
Revision 3257, 4.4 KB checked in by spascoe, 13 years ago (diff)

Made OwsController? much simpler. Features will be reintroduced gradualy
or left to subclasses. Included hooks for updateSequence and version
negotiation.

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