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