github.com/anuvu/tyk@v2.9.0-beta9-dl-apic+incompatible/coprocess/python/dispatcher.py (about) 1 from glob import glob 2 from os import getcwd, chdir, path 3 4 import tyk 5 from tyk.middleware import TykMiddleware 6 from tyk.object import TykCoProcessObject 7 from tyk.event import TykEvent 8 9 from gateway import TykGateway as tyk 10 11 import sys 12 def except_hook(type, value, traceback): 13 tyk.log_error("{0}".format(value)) 14 15 sys.excepthook = except_hook 16 17 class TykDispatcher: 18 '''A simple dispatcher''' 19 20 def __init__(self, bundle_root_path): 21 tyk.log("Initializing dispatcher", "info") 22 self.bundle_root_path = bundle_root_path 23 self.bundles = [] 24 self.hook_table = {} 25 26 def find_bundle(self, bundle_id): 27 found = None 28 for bundle in self.bundles: 29 if bundle.bundle_id == bundle_id: 30 found = bundle 31 break 32 return found 33 34 def load_bundle(self, bundle_path): 35 path_splits = bundle_path.split('/') 36 bundle_id = path_splits[-1] 37 bundle = self.find_bundle(bundle_id) 38 if not bundle: 39 bundle = TykMiddleware(bundle_id, bundle_root_path=self.bundle_root_path) 40 self.bundles.append(bundle) 41 self.update_hook_table(with_bundle=bundle) 42 43 def update_hook_table(self, with_bundle=None): 44 new_hook_table = {} 45 # Disable any previous bundle associated with an API: 46 if with_bundle: 47 # First check if this API exists in the hook table: 48 hooks = {} 49 if with_bundle.api_id in self.hook_table: 50 hooks = self.hook_table[with_bundle.api_id] 51 if len(hooks) > 0: 52 # Pick the first hook and get the current bundle: 53 bundle_in_use = list(hooks.values())[0].middleware 54 # If the bundle is already in use, skip the hook table update: 55 if bundle_in_use.bundle_id == with_bundle.bundle_id: 56 return 57 self.hook_table[with_bundle.api_id] = with_bundle.build_hooks_and_event_handlers() 58 59 def find_hook(self, api_id, hook_name): 60 hooks = self.hook_table.get(api_id) 61 # TODO: handle this situation and also nonexistent hooks 62 if not hooks: 63 raise Exception('No hooks defined for API: {0}'.format(api_id)) 64 65 hook = hooks.get(hook_name) 66 if hook: 67 return hook.middleware, hook 68 else: 69 raise Exception('Hook is not defined: {0}'.format(hook_name)) 70 71 def dispatch_hook(self, object_msg): 72 object = TykCoProcessObject(object_msg) 73 api_id = object.spec['APIID'] 74 middleware, hook_handler = self.find_hook(api_id, object.hook_name) 75 try: 76 object = middleware.process(hook_handler, object) 77 except Exception as e: 78 raise Exception("Hook '{0}' returned an error: {1}".format(object.hook_name, e)) 79 return object.dump() 80 81 def dispatch_event(self, event_json): 82 try: 83 event = TykEvent(event_json) 84 api_id = event.spec['APIID'] 85 middleware, hook_handler = self.find_hook(api_id, event.handler_name) 86 middleware.process(hook_handler, event) 87 except Exception as e: 88 raise Exception("Couldn't dispatch '{0}' event: {1}", event.handler_name, e) 89 90 def reload(self): 91 tyk.log("Reloading event handlers and middlewares.", "info")