summaryrefslogtreecommitdiffstats
path: root/veslibrary/ves_clibrary/evel/evel-test-collector/code/collector/rest_dispatcher.py
blob: e3b51aa6e47e31c4557529ff81e3ba37493822f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/usr/bin/env python
'''
Simple dispatcher for the REST API.

Only intended for test purposes.

License
-------

 * ===================================================================
 * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
 * ===================================================================
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.

'''

import logging
logger = logging.getLogger('collector.disp')

base_url = ''

template_404 = b'''POST {0}'''

def set_404_content(url):
    '''
    Called at initialization to set the base URL so that we can serve helpful
    diagnostics as part of the 404 response. 
    '''
    global base_url
    base_url = url
    return

def notfound_404(environ, start_response):
    '''
    Serve the 404 Not Found response.
    
    Provides diagnostics in the 404 response showing the hierarchy of valid
    REST resources.
    '''
    logger.warning('Unexpected URL/Method: {0} {1}'.format(
                                             environ['REQUEST_METHOD'].upper(),
                                             environ['PATH_INFO']))
    start_response('404 Not Found', [ ('Content-type', 'text/plain') ])
    return [template_404.format(base_url)]

class PathDispatcher:
    '''
    A dispatcher which can take HTTP requests in a WSGI environment and invoke
    appropriate methods for each request.
    '''
    def __init__(self):
        '''Constructor: initialize the pathmap to be empty.'''
        self.pathmap = { }

    def __call__(self, environ, start_response):
        '''
        The main callable that the WSGI app will invoke with each request.
        '''
        #----------------------------------------------------------------------
        # Extract the method and path from the environment.
        #----------------------------------------------------------------------
        method = environ['REQUEST_METHOD'].lower()
        path = environ['PATH_INFO']
        logger.info('Dispatcher called for: {0} {1}'.format(method, path))
        logger.debug('Dispatcher environment is: {0}'.format(environ))

        #----------------------------------------------------------------------
        # See if we have a handler for this path, and if so invoke it.
        # Otherwise, return a 404.
        #----------------------------------------------------------------------
        handler = self.pathmap.get((method, path), notfound_404)
        logger.debug('Dispatcher will use handler: {0}'.format(handler))
        return handler(environ, start_response)

    def register(self, method, path, function):
        '''
        Register a handler for a method/path, adding it to the pathmap.
        '''
        logger.debug('Registering for {0} at {1}'.format(method, path))
        print('Registering for {0} at {1}'.format(method, path))
        self.pathmap[method.lower(), path] = function
        return function