Changeset 3257


Ignore:
Timestamp:
22/01/08 14:02:41 (12 years ago)
Author:
spascoe
Message:

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

Location:
TI05-delivery/ows_framework/branches/ows_framework-refactor/ows_common/ows_common
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • TI05-delivery/ows_framework/branches/ows_framework-refactor/ows_common/ows_common/exceptions.py

    r2507 r3257  
    3131        OwsError.__init__(self, 'InvalidUpdateSequence', text, locator) 
    3232 
     33class CurrentUpdateSequence(OwsError): 
     34    def __init__(self, text, locator=None): 
     35        OwsError.__init__(self, 'CurrentUpdateSequence', text, locator) 
     36 
    3337class NoApplicableCode(OwsError): 
    3438    def __init__(self, text, locator=None): 
  • TI05-delivery/ows_framework/branches/ows_framework-refactor/ows_common/ows_common/pylons/decorators.py

    r3235 r3257  
    8787    A decorator which defines a method as a OWS operation. 
    8888 
    89     The argument signature of the wrapped method is deduced from the decorator 
    90     arguments to allow other decorators to be used below this one 
    91     (e.g. typecheck decorators) and still work as Pylons actions. 
     89    The method is anotated with the attributes of the OWS protocol which are then 
     90    interogated during dispatch by OwsController to enforce OWS operation calling 
     91    behaviour. 
    9292 
    9393    Parameter names should be lowerCamelCase to that match the method 
     
    102102 
    103103    def f(method): 
    104         wrapper = _wrap_sig(method, 
    105                                  ['self'] + [x.lower() for x in requiredParameters], 
    106                                  [x.lower() for x in optionalParameters]) 
    107         wrapper._ows_name = method.__name__ 
    108         wrapper._ows_required_parameters = requiredParameters 
    109         wrapper._ows_optional_parameters = optionalParameters 
    110  
    111         return wrapper 
     104        method._ows_name = method.__name__ 
     105        method._ows_required_parameters = requiredParameters 
     106        method._ows_optional_parameters = optionalParameters 
     107 
     108        return method 
    112109 
    113110    return f 
  • TI05-delivery/ows_framework/branches/ows_framework-refactor/ows_common/ows_common/pylons/ows_controller.py

    r3236 r3257  
    33 
    44@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. 
    57""" 
    68 
    79 
    8 from pylons import Response, c, g, cache, request, session 
     10from pylons import request, response 
    911from pylons.controllers import WSGIController 
    10 from pylons.decorators import jsonify, validate 
    11 from pylons.templating import render, render_response 
    12 from pylons.helpers import abort, redirect_to, etag_cache 
    13  
    14 import webhelpers as h 
    15  
    16 #!TODO: Replace this with a pluggable security system 
    17 from ows_server.lib.security_util import setSecuritySession, LoginServiceQuery 
     12from pylons.templating import render 
    1813 
    1914from ows_common import exceptions as OWS_E 
    20 from ows_common.operations_metadata import OperationsMetadata, Operation, RequestMethod 
    21 from ows_common.get_capabilities import ServiceMetadata 
    22 import ows_common.xml 
    23  
     15from ows_common util import negotiate_version 
    2416 
    2517try: 
     
    3729 
    3830 
    39 class OwsController(WSGIController): 
     31class OwsControllerBase(WSGIController): 
    4032    def __call__(self, environ, start_response): 
    4133 
    4234        # All OWS parameter names are case insensitive. 
    43         req = request._current_obj() 
    4435        self.ows_params = {} 
    45         for k in req.params: 
    46             self.ows_params[k.lower()] = req.params[k]         
     36        for k in request.params: 
     37            self.ows_params[k.lower()] = request.params[k]         
    4738 
    4839        # If the EXCEPTION_TYPE is 'pylons' let Pylons catch any exceptions. 
     
    9081 
    9182 
    92     def _loadCapabilities(self): 
     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): 
    9395        """ 
    94         creates an ows_common.get_capabilities.ServiceMetadata object 
    95         by consulting the paste configuration and annotations in the 
    96         controller definition. 
     96        Override in subclasses to return a valid updateSequence for the uri. 
     97        """ 
     98        return None 
    9799 
     100    def getCapabilitiesTemplate(self, version, format): 
    98101        """ 
    99         # Deduce ows_endpoint from routes 
    100         ows_endpoint = h.url_for(controller=request.environ['pylons.routes_dict']['controller']) 
     102        Get the capabilities template. 
     103 
     104        @param version: the version as a sequence of numbers 
     105        @param format: the format as a string 
    101106         
    102         #Deduce base_url from config 
    103         base_url =request.environ['ndgConfig'].get('DEFAULT','server') 
     107        @return: a template as expected  by pylons.render() 
     108        """ 
     109        raise NotImplementedError 
    104110 
     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') 
    105131         
    106         # Get the server-level configuration data from an XML file 
    107         config = request.environ['paste.config'] 
    108         sm_tree = ET.parse(config['ows_common_config']) 
    109         sm = ows_common.xml.service_metadata(sm_tree.getroot()) 
    110          
    111         # Extract service-level parameters and constraint 
    112         parameters = getattr(self, '_ows_parameters', {}) 
    113         constraints = getattr(self, '_ows_constraints', {}) 
    114         versions = getattr(self, '_ows_versions', []) 
    115          
    116         # Extract operation-level parameters and constraints 
    117         od = {} 
    118         for attr in dir(self): 
    119             op = getattr(self, attr) 
    120             if hasattr(op, '_ows_name'): 
    121                 p = getattr(op, '_ows_parameters', {}) 
    122                 c = getattr(op, '_ows_constraints', {}) 
    123                 od[op._ows_name] = Operation(get=RequestMethod(href=base_url+ows_endpoint), 
    124                                              post=None, 
    125                                              parameters=p, 
    126                                              constraints=c, 
    127                                              name=op._ows_name) 
    128          
    129         sm.operationsMetadata = OperationsMetadata(od, constraints, parameters) 
    130         sm.serviceIdentification.serviceTypeVersions = versions 
    131         return sm 
    132132 
    133     def _renderCapabilities(self, template='ows/get_capabilities'): 
    134         """ 
    135         The standard way of returning a Capabilities document. 
    136  
    137         Each subclass should implement self._load_capabilities() and call 
    138         this method to return a response object. 
    139  
    140         """ 
    141         c.service_metadata = self._loadCapabilities()         
    142         r = render_response(template, format='xml') 
    143         r.headers['content-type'] = 'text/xml' 
    144         return r 
    145  
  • TI05-delivery/ows_framework/branches/ows_framework-refactor/ows_common/ows_common/util.py

    r2570 r3257  
    2929    return Domain(defaultValue=value, possibleValues=pv, **kwargs) 
    3030 
     31 
     32 
     33 
     34def parse_version(version): 
     35    return tuple(int(x) for x in version.split('.')) 
     36 
     37def negotiate_version(serverVersions, clientVersion=None): 
     38    versions = [parse_version(v) for v in serverVersions] 
     39    versions.sort() 
     40     
     41    if clientVersion is None: 
     42        return versions[-1] 
     43     
     44    cv = parse_version(clientVersion) 
     45 
     46    pv = versions[0] 
     47    for v in versions: 
     48        if cv == v: 
     49            return v 
     50        if cv < v: 
     51            return pv 
     52        pv = v 
     53 
     54    return pv 
     55 
     56 
     57#----------------------------------------------------------------------------- 
     58 
     59_test_versions = ['1.0', '1.1.1', '1.3.0'] 
     60def test_version_negotiation1(): 
     61    assert negotiate_version(_test_versions) == (1, 3, 0) 
     62def test_version_negotiation2(): 
     63    assert negotiate_version(_test_versions, '0.1') == (1, 0) 
     64def test_version_negotiation3(): 
     65    assert negotiate_version(_test_versions, '1.4') == (1,3,0) 
     66def test_version_negotiation4(): 
     67    assert negotiate_version(_test_versions, '1.1.1') == (1,1,1) 
     68def test_version_negotiation5(): 
     69    assert negotiate_version(_test_versions, '1.2') == (1,1,1) 
     70 
Note: See TracChangeset for help on using the changeset viewer.