class LightweightPyDAP(SimpleProcess): def on_start(self): try: SimpleProcess.on_start(self) self.pydap_host = self.CFG.get_safe( 'container.pydap_gateway.web_server.host', 'localhost') self.pydap_port = self.CFG.get_safe( 'container.pydap_gateway.web_server.port', '8001') self.pydap_data_path = self.CFG.get_safe('server.pydap.data_path', 'RESOURCE:ext/pydap') self.pydap_data_path = FileSystem.get_extended_url( self.pydap_data_path) self.app = make_app(None, self.pydap_data_path, 'ion/core/static/templates/') self.log = getLogger('pydap') self.log.write = self.log.info self.server = WSGIServer((self.pydap_host, int(self.pydap_port)), self.app, log=self.log) self.server.start() except: log.exception('Unable to start PyDAP server') raise def on_quit(self): self.server.stop() super(LightweightPyDAP, self).on_quit()
def run(ctx, **kwargs): if ctx.invoked_subcommand is None: from raiden.api.python import RaidenAPI from raiden.ui.console import Console slogging.configure(kwargs['logging'], log_file=kwargs['logfile']) # TODO: # - Ask for confirmation to quit if there are any locked transfers that did # not timeout. (listen_host, listen_port) = split_endpoint(kwargs['listen_address']) with socket_factory(listen_host, listen_port) as mapped_socket: kwargs['mapped_socket'] = mapped_socket app_ = ctx.invoke(app, **kwargs) domain_list = [] if kwargs['rpccorsdomain']: if ',' in kwargs['rpccorsdomain']: for domain in kwargs['rpccorsdomain'].split(','): domain_list.append(str(domain)) else: domain_list.append(str(kwargs['rpccorsdomain'])) http_server = None if ctx.params['rpc']: raiden_api = RaidenAPI(app_.raiden) rest_api = RestAPI(raiden_api) api_server = APIServer(rest_api, cors_domain_list=domain_list) (api_host, api_port) = split_endpoint(kwargs["api_address"]) http_server = WSGIServer((api_host, api_port), api_server.flask_app, log=slogging.getLogger('flask')) http_server.start() print( "The Raiden API RPC server is now running at http://{}:{}/.\n\n" "See the Raiden documentation for all available endpoints at\n" "https://github.com/raiden-network/raiden/blob/master" "/docs/Rest-Api.rst".format( api_host, api_port, )) if ctx.params['console']: console = Console(app_) console.start() # wait for interrupt event = gevent.event.Event() gevent.signal(signal.SIGQUIT, event.set) gevent.signal(signal.SIGTERM, event.set) gevent.signal(signal.SIGINT, event.set) event.wait() if http_server: http_server.stop(5) app_.stop(leave_channels=False)
def serve(app): gevent.monkey.patch_all() if app.config['DEBUG']: from werkzeug.debug import DebuggedApplication app = DebuggedApplication(app) http_server = WSGIServer(('0.0.0.0', 0), app) http_server.start() return http_server
class ServiceGatewayService(BaseServiceGatewayService): """ The Service Gateway Service is the service that uses a gevent web server and Flask to bridge HTTP requests to AMQP RPC ION process service calls. """ def on_init(self): #defaults self.http_server = None self.server_hostname = DEFAULT_WEB_SERVER_HOSTNAME self.server_port = DEFAULT_WEB_SERVER_PORT self.web_server_enabled = True self.logging = None #retain a pointer to this object for use in ProcessRPC calls global service_gateway_instance service_gateway_instance = self #get configuration settings if specified if 'web_server' in self.CFG: web_server_cfg = self.CFG['web_server'] if web_server_cfg is not None: if 'hostname' in web_server_cfg: self.server_hostname = web_server_cfg['hostname'] if 'port' in web_server_cfg: self.server_port = web_server_cfg['port'] if 'enabled' in web_server_cfg: self.web_server_enabled = web_server_cfg['enabled'] if 'log' in web_server_cfg: self.logging = web_server_cfg['log'] #need to figure out how to redirect HTTP logging to a file if self.web_server_enabled: self.start_service(self.server_hostname,self.server_port) def on_quit(self): self.stop_service() def start_service(self, hostname=DEFAULT_WEB_SERVER_HOSTNAME, port=DEFAULT_WEB_SERVER_PORT): """Responsible for starting the gevent based web server.""" if self.http_server is not None: self.stop_service() self.http_server = WSGIServer((hostname, port), app, log=self.logging) self.http_server.start() return True def stop_service(self): """Responsible for stopping the gevent based web server.""" if self.http_server is not None: self.http_server.stop() return True
def start(self, *args, **kwargs): self.logger.info("Stratum server starting up on {address}:{port}" .format(**self.config)) # Monkey patch the wsgi logger Logger.logger = self.logger WSGIServer.start(self, *args, **kwargs) Component.start(self)
def start(self, *args, **kwargs): WSGIServer.__init__(self, self.settings['ui_address'], self.app, spawn=100, log=Logger()) self.logger.info("Monitoring port listening on {}" .format(self.settings['ui_address'])) # Monkey patch the wsgi logger Logger.logger = self.logger WSGIServer.start(self, *args, **kwargs)
def start(self, *args, **kwargs): listener = (self.config['address'], self.config['port'] + self.manager.config['server_number']) WSGIServer.__init__(self, listener, self.app, spawn=100, log=Logger()) self.logger.info("Monitoring port listening on {}".format(listener)) # Monkey patch the wsgi logger Logger.logger = self.logger WSGIServer.start(self, *args, **kwargs) Component.start(self)
class Larigira(object): def __init__(self): self.log = logging.getLogger('larigira') self.conf = get_conf() self.controller = Controller(self.conf) self.controller.link_exception(on_main_crash) self.http_server = WSGIServer(('', 5000), create_app(self.controller.q, self)) def start(self): self.controller.start() self.http_server.start()
def start(self, *args, **kwargs): WSGIServer.__init__(self, self.settings['ui_address'], self.app, spawn=100, log=Logger()) self.logger.info("Monitoring port listening on {}".format( self.settings['ui_address'])) # Monkey patch the wsgi logger Logger.logger = self.logger WSGIServer.start(self, *args, **kwargs)
class AdminUI(SimpleProcess): """ A simple Web UI to introspect the container and the ION datastores. """ def on_init(self): self.http_server = None self.server_hostname = self.CFG.get_safe(CFG_PREFIX + '.web_server.hostname', DEFAULT_WEB_SERVER_HOSTNAME) self.server_port = self.CFG.get_safe(CFG_PREFIX + '.web_server.port', DEFAULT_WEB_SERVER_PORT) self.url_prefix = self.CFG.get_safe(CFG_PREFIX + '.url_prefix') or "" self.web_server_enabled = True self.logging = None self.interaction_observer = None self.plugin = None app.secret_key = self.__class__.__name__ # Enables sessions (for mscweb) #retain a pointer to this object for use in ProcessRPC calls global adminui_instance adminui_instance = self #Start the gevent web server unless disabled if self.web_server_enabled: self.start_service(self.server_hostname, self.server_port) plugin_cls = CFG.get_safe(CFG_PREFIX + '.plugin') if plugin_cls: cls = named_any(plugin_cls) self.plugin = cls(app, self) def on_quit(self): if self.interaction_observer and self.interaction_observer.started: self.interaction_observer.stop() self.stop_service() def start_service(self, hostname=DEFAULT_WEB_SERVER_HOSTNAME, port=DEFAULT_WEB_SERVER_PORT): """Responsible for starting the gevent based web server.""" if self.http_server is not None: self.stop_service() self.http_server = WSGIServer((hostname, port), app, log=self.logging) self.http_server.start() return True def stop_service(self): """Responsible for stopping the gevent based web server.""" if self.http_server is not None: self.http_server.stop() return True
def start(config): from .wsgi import DummyWSGILogger, WSGIHandlerWithWorkarounds from gevent.wsgi import WSGIServer from werkzeug.contrib.fixers import ProxyFix from werkzeug.debug import DebuggedApplication from flask.ext.cors import CORS from os import getpid app = FlaskApp.from_config(config) app.jinja_options['extensions'].append("jinja2.ext.loopcontrols") cors = CORS(app, send_wildcard=True) app_wrapper = ProxyFix(DebuggedApplication(app, True)) args = (config.webserver.address, config.webserver.port) server = WSGIServer(args, app_wrapper, log=DummyWSGILogger, handler_class=WSGIHandlerWithWorkarounds) server.start() logger.info(">>> starting HTTP server on {1}:{2}, pid={0} <<<".format(getpid(), *args)) return server
def gevent_controller(port, serve_forever=True): http_server = WSGIServer(('', int(port)), app) addresses = get_ipaddresses() sys.stderr.write("Web Client listening on:\n") for interface, ip in addresses: if ip != '0.0.0.0': sys.stderr.write(" http://%s:%d (%s)\n" % (ip, port, interface)) else: sys.stderr.write(" %s has no ip address to listen on\n" % interface) sys.stderr.flush() if serve_forever: print "... starting serve_forever()" http_server.serve_forever() print "... serve_forever finished." else: http_server.start() return http_server
def monitor_runner(net_state, config, stratum_clients, server_state, agent_clients, exit_event): logger.info("Monitor server starting up; Thread ID {}" .format(threading.current_thread())) monitor_app.config.update(config['monitor']) monitor_app.config.update(dict(net_state=net_state, config=config, stratum_clients=stratum_clients, agent_clients=agent_clients, server_state=server_state)) wsgiserver = WSGIServer((config['monitor']['address'], config['monitor']['port']), monitor_app) wsgiserver.start() try: exit_event.wait() finally: logger.info("Server monitor shutting down...") Greenlet.spawn(wsgiserver.stop, timeout=None).join()
class RunServerInGreenlet(Greenlet): def __init__(self, mock_server): self._httpd = None self._mock_server = mock_server super(RunServerInGreenlet, self).__init__() def run(self): self._httpd = WSGIServer( (self._mock_server.host, self._mock_server.port), self._mock_server, log='default' if self._mock_server.debug else None, ) self._httpd.start() def stop(self): if self._httpd: self._httpd.stop()
class RunServerInGreenlet(Greenlet): def __init__(self, mock_server): self._httpd = None self._mock_server = mock_server super(RunServerInGreenlet, self).__init__() def run(self): self._httpd = WSGIServer( (self._mock_server.config.HOST, self._mock_server.config.PORT), self._mock_server, log='default' if self._mock_server.config.DEBUG else None, ) self._httpd.start() def stop(self): if self._httpd: self._httpd.stop()
def monitor_runner(net_state, config, stratum_clients, server_state, agent_clients, exit_event): logger.info("Monitor server starting up; Thread ID {}".format( threading.current_thread())) monitor_app.config.update(config['monitor']) monitor_app.config.update( dict(net_state=net_state, config=config, stratum_clients=stratum_clients, agent_clients=agent_clients, server_state=server_state)) wsgiserver = WSGIServer( (config['monitor']['address'], config['monitor']['port']), monitor_app) wsgiserver.start() try: exit_event.wait() finally: logger.info("Server monitor shutting down...") Greenlet.spawn(wsgiserver.stop, timeout=None).join()
class LightweightPyDAP(SimpleProcess): def on_start(self): super(LightweightPyDAP,self).on_start() self.pydap_host = self.CFG.get_safe('server.pydap.host', 'localhost') self.pydap_port = self.CFG.get_safe('server.pydap.port', '8001') self.pydap_data_path = self.CFG.get_safe('server.pydap.data_path', 'RESOURCE:ext/pydap') self.pydap_data_path = FileSystem.get_extended_url(self.pydap_data_path) self.app = make_app(None, self.pydap_data_path, 'ion/core/static/templates/') self.log = getLogger('pydap') self.log.write = self.log.info self.server = WSGIServer((self.pydap_host, int(self.pydap_port)), self.app, log=self.log) self.server.start() def on_quit(self): self.server.stop() super(LightweightPyDAP,self).on_quit()
class ContainerUI(StandaloneProcess): """ A simple Web UI to introspect the container and the ION datastores. """ def on_init(self): # defaults self.http_server = None self.server_hostname = DEFAULT_WEB_SERVER_HOSTNAME self.server_port = self.CFG.get_safe("container.flask_webapp.port", DEFAULT_WEB_SERVER_PORT) self.web_server_enabled = True self.logging = None # retain a pointer to this object for use in ProcessRPC calls global containerui_instance containerui_instance = self # Start the gevent web server unless disabled if self.web_server_enabled: self.start_service(self.server_hostname, self.server_port) def on_quit(self): self.stop_service() def start_service(self, hostname=DEFAULT_WEB_SERVER_HOSTNAME, port=DEFAULT_WEB_SERVER_PORT): """Responsible for starting the gevent based web server.""" if self.http_server is not None: self.stop_service() self.http_server = WSGIServer((hostname, port), app, log=self.logging) self.http_server.start() return True def stop_service(self): """Responsible for stopping the gevent based web server.""" if self.http_server is not None: self.http_server.stop() return True
class ContainerUI(StandaloneProcess): """ A simple Web UI to introspect the container and the ION datastores. """ def on_init(self): #defaults self.http_server = None self.server_hostname = DEFAULT_WEB_SERVER_HOSTNAME self.server_port = DEFAULT_WEB_SERVER_PORT self.web_server_enabled = True self.logging = None #retain a pointer to this object for use in ProcessRPC calls global containerui_instance containerui_instance = self #Start the gevent web server unless disabled if self.web_server_enabled: self.start_service(self.server_hostname, self.server_port) def on_quit(self): self.stop_service() def start_service(self, hostname=DEFAULT_WEB_SERVER_HOSTNAME, port=DEFAULT_WEB_SERVER_PORT): """Responsible for starting the gevent based web server.""" if self.http_server is not None: self.stop_service() self.http_server = WSGIServer((hostname, port), app, log=self.logging) self.http_server.start() return True def stop_service(self): """Responsible for stopping the gevent based web server.""" if self.http_server is not None: self.http_server.stop() return True
from web import app from gevent.wsgi import WSGIServer if __name__ == '__main__': http_server = WSGIServer(('', 5001), app) http_server.start() http_server.serve_forever()
def gfa_thermal_main(): from gfa_thermal import config, system_names from gfa_thermal.system import SystemGFAThermal from entropyfw.logger import log import logging from logging.handlers import RotatingFileHandler from gevent.wsgi import WSGIServer from flask import Flask, url_for from flask.templating import DispatchingJinjaLoader app = Flask(__name__) server = WSGIServer(("", 5000), app) server.start() @app.errorhandler(Exception) def all_exception_handler(error): log.exception('Whatever exception') @app.errorhandler(404) def handle_bad_request(e): log.exception('Whatever exception') formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s') if config.STREAM_LOG: ch = logging.StreamHandler() ch.setLevel(config.STREAM_LOG_LEVEL) ch.setFormatter(formatter) log.addHandler(ch) if config.FILE_LOG: ch = RotatingFileHandler(config.FILE_LOG_PATH, mode='a', maxBytes=config.FILE_LOG_MAX_SIZE, backupCount=config.FILE_LOG_BACKUP, encoding=None, delay=0) ch.setLevel(config.FILE_LOG_LEVEL) ch.setFormatter(formatter) log.addHandler(ch) s = SystemGFAThermal(flask_app=app) print(app.url_map) # Enable channel for chan in range(9): conf_val = getattr(config, 'TC08_CHAN_{}'.format(chan)) if conf_val['enable']: log.info('Enabling Channel {}'.format(chan)) s.enable_tc08_channel(chan, tc_type=conf_val['tc_type'], units=conf_val['units']) # connect to tticpx log.info('Connecting to power supply at {}:{}'.format( config.TTiCPX_IP, config.TTiCPX_PORT)) s.connect_power_supply(ip=config.TTiCPX_IP, port=config.TTiCPX_PORT) # Register temperatures and applied V, I for electro cooler calculator log.info('Electro cooler calculator - registering temperature event') s.ot15.register_temp_event( '{}.temperatures'.format(system_names.TC08_MOD), tc_keyword='channel_{}'.format(config.TEMPERATURE_CHANNEL_TC_COLD), th_keyword='channel_{}'.format(config.TEMPERATURE_CHANNEL_TC_HOT)) log.info( 'Electro cooler calculator - registering power supply values event') s.ot15.register_event_iv_applied(pattern='{}.status.{}'.format( system_names.TTiCPX_MOD, config.TTiCPX_OUTPUT), i_keyword='current', v_keyword='voltage') # Set configuration values for controller s.controller.register_temperatures_callback( event_name='{}.temperatures'.format(system_names.TC08_MOD), temp_control_channel=config.TEMPERATURE_CHANNEL_CONTROL, cold_threshold=config.CONTROL_COLD_THRESHOLD, hot_threshold=config.CONTROL_HOT_THRESHOLD) # s.controller.set_thresholds(t_cold=config.CONTROL_COLD_THRESHOLD, # t_hot=config.CONTROL_HOT_THRESHOLD) # Register event for control # s.controller.set_channels(control_temp=config.TEMPERATURE_CHANNEL_CONTROL, # cooler_cold_side=config.TEMPERATURE_CHANNEL_TC_COLD, # cooler_hot_side=config.TEMPERATURE_CHANNEL_TC_HOT) s.controller.register_electrocooler_calc( event_name='{}.constant_qc_vi'.format(system_names.LAIRD_MOD)) # Configure logger values to save s.elogger.add_log('{}.{}'.format(system_names.TC08_MOD, 'temperatures')) s.elogger.add_log('{}.{}'.format(system_names.LAIRD_MOD, 'status')) s.elogger.add_log('{}.{}'.format(system_names.LAIRD_MOD, 'constant_qc_vi')) s.elogger.add_log('{}.{}'.format(system_names.TTiCPX_MOD, 'status.1')) s.elogger.add_log('{}.{}'.format(system_names.TTiCPX_MOD, 'status.2')) # start loop on tc08 and tticpx every x seconds set at config s.tticpx.start_timer(config.SENSORS_LOOP_INTERVAL) s.pico.start_timer(config.SENSORS_LOOP_INTERVAL) print(s.list_callbacks()) try: server.serve_forever() finally: s.tticpx.stop_timer() s.pico.stop_timer() print(s.list_callbacks()) s.exit()
local_souma = Souma.query.get(app.config["SOUMA_ID"]) except OperationalError: app.logger.info("Setting up database") db.create_all() app.logger.info("Setting up Nucleus for <Souma [{}]>".format(app.config['SOUMA_ID'][:6])) local_souma = Souma(id=app.config['SOUMA_ID']) local_souma.generate_keys() local_souma.starmap = Starmap(id=uuid4().hex, kind="index") db.session.add(local_souma) db.session.commit() if app.config['USE_DEBUG_SERVER']: # flask development server app.run(app.config['LOCAL_HOSTNAME'], app.config['LOCAL_PORT']) else: shutdown = gevent.event.Event() # Synapse app.logger.info("Starting Synapses") synapse = Synapse() # Web UI if not app.config['NO_UI']: app.logger.info("Starting Web-UI") local_server = WSGIServer(('', app.config['LOCAL_PORT']), app) local_server.start() shutdown.wait()
if environ['PATH_INFO'] == '/ws': environ['ws4py.app'] = self return self.ws(environ, start_response) return None def favicon(self, environ, start_response): status = '200 OK' headers = [('Content-type', 'text/plain')] start_response(status, headers) return "" if __name__ == "__main__": kill_event = Event() gui = Gui(kill_event) gui.start() gui.set_status_server(True) http_server = WSGIServer((HOST, PORT), app) http_server.start() websocket_application = EchoWebSocketApplication(HOST, PORT_WS) websocket_server = WSGIServer((HOST, PORT_WS), websocket_application) websocket_server.start() while not kill_event.is_set(): gsleep(0.1) http_server.stop()
from web import app from gevent.wsgi import WSGIServer if __name__ == '__main__': http_server = WSGIServer(('', 5000), app) http_server.start() http_server.serve_forever()
return self.favicon(environ, start_response) if environ['PATH_INFO'] == '/ws': environ['ws4py.app'] = self return self.ws(environ, start_response) return None def favicon(self, environ, start_response): status = '200 OK' headers = [('Content-type', 'text/plain')] start_response(status, headers) return "" if __name__ == "__main__": kill_event = Event() gui = Gui(kill_event) gui.start() gui.set_status_server(True) http_server = WSGIServer((HOST, PORT), app) http_server.start() websocket_application = EchoWebSocketApplication(HOST, PORT_WS) websocket_server = WSGIServer((HOST, PORT_WS), websocket_application) websocket_server.start() while not kill_event.is_set(): gsleep(0.1) http_server.stop()
from synapse import Synapse from sqlalchemy.exc import OperationalError # Initialize database try: db.session.execute("SELECT * FROM 'starmap' LIMIT 1") except OperationalError: app.logger.info("Initializing database") db.create_all() db.session.add(Starmap(app.config['SOMA_ID'])) db.session.commit() if app.config['USE_DEBUG_SERVER']: # flask development server app.run(app.config['LOCAL_HOSTNAME'], app.config['LOCAL_PORT']) else: shutdown = gevent.event.Event() # Synapse app.logger.info("Starting Synapses") synapse = Synapse(('0.0.0.0', app.config['SYNAPSE_PORT'])) synapse.start() # gevent server if not app.config['NO_UI']: app.logger.info("Starting Web-UI") local_server = WSGIServer(('', app.config['LOCAL_PORT']), app) local_server.start() shutdown.wait()
def __init__(self, flask_app): System.__init__(self, flask_app) self.add_module(EntropyTTiCPX()) if __name__ == "__main__": from entropyfw.logger import log, formatter import logging from gevent.wsgi import WSGIServer from flask import Flask, url_for from flask.templating import DispatchingJinjaLoader app = Flask(__name__) server = WSGIServer(("", 5000), app) server.start() @app.errorhandler(Exception) def all_exception_handler(error): log.exception('Whatever exception') @app.errorhandler(404) def handle_bad_request(e): log.exception('Whatever exception') def list_routes(): import urllib output = [] for rule in app.url_map.iter_rules():
class APIServer: """ Runs the API-server that routes the endpoint to the resources. The API is wrapped in multiple layers, and the Server should be invoked this way:: # instance of the raiden-api raiden_api = RaidenAPI(...) # wrap the raiden-api with rest-logic and encoding rest_api = RestAPI(raiden_api) # create the server and link the api-endpoints with flask / flask-restful middleware api_server = APIServer(rest_api) # run the server api_server.run('127.0.0.1', 5001, debug=True) """ _api_prefix = '/api/1' def __init__(self, rest_api, cors_domain_list=None, web_ui=False, eth_rpc_endpoint=None): if rest_api.version != 1: raise ValueError('Invalid api version: {}'.format( rest_api.version)) flask_app = Flask(__name__) if cors_domain_list: CORS(flask_app, origins=cors_domain_list) if eth_rpc_endpoint: if not eth_rpc_endpoint.startswith('http'): eth_rpc_endpoint = 'http://{}'.format(eth_rpc_endpoint) flask_app.config['WEB3_ENDPOINT'] = eth_rpc_endpoint blueprint = create_blueprint() flask_api_context = Api(blueprint, prefix=self._api_prefix) restapi_setup_type_converters( flask_app, {'hexaddress': HexAddressConverter}, ) restapi_setup_urls( flask_api_context, rest_api, URLS_V1, ) self.rest_api = rest_api self.flask_app = flask_app self.blueprint = blueprint self.flask_api_context = flask_api_context self.wsgiserver = None self.flask_app.register_blueprint(self.blueprint) self.flask_app.config['WEBUI_PATH'] = '../ui/web/dist/' if is_frozen(): # Inside frozen pyinstaller image self.flask_app.config[ 'WEBUI_PATH'] = '{}/raiden/ui/web/dist/'.format(sys.prefix) self.flask_app.errorhandler(HTTPStatus.NOT_FOUND)(endpoint_not_found) if web_ui: for route in ('/ui/<path:file_name>', '/ui', '/ui/', '/index.html', '/'): self.flask_app.add_url_rule( route, route, view_func=self._serve_webui, methods=('GET', ), ) def _serve_webui(self, file_name='index.html'): # pylint: disable=redefined-builtin try: assert file_name web3 = self.flask_app.config.get('WEB3_ENDPOINT') if web3 and 'config.' in file_name and file_name.endswith('.json'): host = request.headers.get('Host') if any(h in web3 for h in ('localhost', '127.0.0.1')) and host: _, _port = split_endpoint(web3) _host, _ = split_endpoint(host) web3 = 'http://{}:{}'.format(_host, _port) response = jsonify({'raiden': self._api_prefix, 'web3': web3}) else: response = send_from_directory( self.flask_app.config['WEBUI_PATH'], file_name) except (NotFound, AssertionError): response = send_from_directory(self.flask_app.config['WEBUI_PATH'], 'index.html') return response def run(self, host='127.0.0.1', port=5001, **kwargs): self.flask_app.run(host=host, port=port, **kwargs) def start(self, host='127.0.0.1', port=5001): self.wsgiserver = WSGIServer((host, port), self.flask_app, log=log, error_log=log) self.wsgiserver.start() def stop(self, timeout=5): if getattr(self, 'wsgiserver', None): self.wsgiserver.stop(timeout) self.wsgiserver = None
class APIServer: """ Runs the API-server that routes the endpoint to the resources. The API is wrapped in multiple layers, and the Server should be invoked this way:: # instance of the raiden-api raiden_api = RaidenAPI(...) # wrap the raiden-api with rest-logic and encoding rest_api = RestAPI(raiden_api) # create the server and link the api-endpoints with flask / flask-restful middleware api_server = APIServer(rest_api) # run the server api_server.run('127.0.0.1', 5001, debug=True) """ _api_prefix = '/api/1' def __init__(self, rest_api, cors_domain_list=None, web_ui=False, eth_rpc_endpoint=None): if rest_api.version != 1: raise ValueError( 'Invalid api version: {}'.format(rest_api.version) ) flask_app = Flask(__name__) if cors_domain_list: CORS(flask_app, origins=cors_domain_list) if eth_rpc_endpoint: if not eth_rpc_endpoint.startswith('http'): eth_rpc_endpoint = 'http://{}'.format(eth_rpc_endpoint) flask_app.config['WEB3_ENDPOINT'] = eth_rpc_endpoint blueprint = create_blueprint() flask_api_context = Api(blueprint, prefix=self._api_prefix) restapi_setup_type_converters( flask_app, {'hexaddress': HexAddressConverter}, ) restapi_setup_urls( flask_api_context, rest_api, URLS_V1, ) self.rest_api = rest_api self.flask_app = flask_app self.blueprint = blueprint self.flask_api_context = flask_api_context self.wsgiserver = None self.flask_app.register_blueprint(self.blueprint) self.flask_app.config['WEBUI_PATH'] = '../ui/web/dist/' if is_frozen(): # Inside frozen pyinstaller image self.flask_app.config['WEBUI_PATH'] = '{}/raiden/ui/web/dist/'.format(sys.prefix) if web_ui: for route in ('/ui/<path:file_name>', '/ui', '/ui/', '/index.html', '/'): self.flask_app.add_url_rule( route, route, view_func=self._serve_webui, methods=('GET', ), ) def _serve_webui(self, file_name='index.html'): # pylint: disable=redefined-builtin try: assert file_name web3 = self.flask_app.config.get('WEB3_ENDPOINT') if web3 and 'config.' in file_name and file_name.endswith('.json'): host = request.headers.get('Host') if any(h in web3 for h in ('localhost', '127.0.0.1')) and host: _, _port = split_endpoint(web3) _host, _ = split_endpoint(host) web3 = 'http://{}:{}'.format(_host, _port) response = jsonify({'raiden': self._api_prefix, 'web3': web3}) else: response = send_from_directory(self.flask_app.config['WEBUI_PATH'], file_name) except (NotFound, AssertionError): response = send_from_directory(self.flask_app.config['WEBUI_PATH'], 'index.html') return response def run(self, host='127.0.0.1', port=5001, **kwargs): self.flask_app.run(host=host, port=port, **kwargs) def start(self, host='127.0.0.1', port=5001): self.wsgiserver = WSGIServer((host, port), self.flask_app, log=log, error_log=log) self.wsgiserver.start() def stop(self, timeout=5): if getattr(self, 'wsgiserver', None): self.wsgiserver.stop(timeout) self.wsgiserver = None
class Application(Singleton): """ Main class of your application. Pass options to constructor and all subsystems(eventer, router) will be configured. """ def __init__(self, options): self.init_options(options) self.init_eventer() self.init_router() self.init_templater() self.eventer.publish("BeforeDatabaseEngineConfiguration", self) self.init_db() self.eventer.publish("AfterDatabaseEngineConfiguration", self) self.init_session() self.eventer.publish("BeforeInitStatic", self) self.init_static() self.eventer.publish("AfterInitStatic", self) self.eventer.publish("BeforeInitServer", self) self.init_server() self.eventer.publish("AfterInitServer", self) self.eventer.publish("BeforeApplicationStarted", self) def init_options(self, options): logging.basicConfig(level=logging.CRITICAL) default_options = { "application": { "address": "127.0.0.1", "port": 8080, "system": { "log": None } }, "urls": {}, "views": { "templates_path": [], "templates_extensions": ["compressinja.html.HtmlCompressor", "jinja2.ext.i18n"], "static_path": [], "static_not_compile": [], "static_build": True, 'session_type': "cookie", "session_auto": True, 'session_cookie_expires': True, 'session_encrypt_key': 'sldk24j0jf09w0jfg24', 'session_validate_key': ';l[pfghopkqeq1234,fs' }, "events": {} } self.options = Dict.merge(default_options, options) def init_eventer(self): self.eventer = Eventer(self.options["events"]) def init_router(self): self.router = Router(self.options) def init_templater(self): self.templater = Templater(self) def init_static(self): static_builder = None self.add_static( self.options["views"]["static_path"], not_compile=self.options["views"]["static_not_compile"], merge=False, build=self.options["views"]["static_build"]) def add_static(self, sps, not_compile=[], url_path="/", merge=True, build=True): static_path = [] for sp in sps: try: sp = Importer.module_path(sp) except: pass try: static_path.append(sp) static_builder = StaticBuilder(sp, not_compile) if build: static_builder.build() if build: self.wsgi_app = SharedDataMiddleware( self.wsgi_app, {url_path: sp + "/build"}, cache=False) else: self.wsgi_app = SharedDataMiddleware(self.wsgi_app, {url_path: sp}, cache=False) except: pass if merge: self.options["views"]["static_path"] = self.options["views"][ "static_path"] + static_path else: self.options["views"]["static_path"] = static_path def init_db(self): if "models" in self.options: metadata.bind = self.options["models"]["connection"] metadata.bind.echo = False def init_session(self): session_options = { 'session.type': self.options["views"]['session_type'], "session.auto": self.options["views"]["session_auto"], 'session.cookie_expires': self.options["views"]['session_cookie_expires'], 'session.encrypt_key': self.options["views"]['session_encrypt_key'], 'session.validate_key': self.options["views"]['session_validate_key'] } self.wsgi_app = SessionMiddleware(self.wsgi_app, session_options, environ_key="session") def init_server(self): #kwargs = dict(filter(lambda item: item[0] not in ["address", "port"], self.options["application"].iteritems())) kwargs = {} if "system" in self.options["application"]: kwargs = self.options["application"]["system"] self.server = WSGIServer((self.options["application"]["address"], self.options["application"]["port"]), self.wsgi_app, **kwargs) def wsgi_app(self, options, start_response): request = Request(options) response = self.router.route(request) return response(options, start_response) def start(self): gevent.signal(signal.SIGTERM, self.stop) gevent.signal(signal.SIGINT, self.stop) self.eventer.publish("ApplicationStarted", self) self.server.serve_forever() def start_no_wait(self): self.eventer.publish("ApplicationStarted", self) self.server.start() def stop(self): self.eventer.publish("ApplicationStopped", self) self.server.stop()
class APIServer(object): """ Runs the API-server that routes the endpoint to the resources. The API is wrapped in multiple layers, and the Server should be invoked this way:: # instance of the raiden-api raiden_api = RaidenAPI(...) # wrap the raiden-api with rest-logic and encoding rest_api = RestAPI(raiden_api) # create the server and link the api-endpoints with flask / flask-restful middleware api_server = APIServer(rest_api) # run the server api_server.run('127.0.0.1', 5001, debug=True) """ # flask TypeConverter # links argument-placeholder in route (e.g. '/<hexaddress: channel_address>') to the Converter _type_converter_mapping = {'hexaddress': HexAddressConverter} _api_prefix = '/api/1' def __init__(self, rest_api, cors_domain_list=None, web_ui=False, eth_rpc_endpoint=None): self.rest_api = rest_api self.blueprint = create_blueprint() if self.rest_api.version == 1: self.flask_api_context = Api( self.blueprint, prefix=self._api_prefix, ) else: raise ValueError('Invalid api version: {}'.format( self.rest_api.version)) self.flask_app = Flask(__name__) if cors_domain_list: CORS(self.flask_app, origins=cors_domain_list) self._add_default_resources() self._register_type_converters() self.flask_app.register_blueprint(self.blueprint) self.flask_app.config['WEBUI_PATH'] = '../ui/web/dist/' if eth_rpc_endpoint: if not eth_rpc_endpoint.startswith('http'): eth_rpc_endpoint = 'http://' + eth_rpc_endpoint self.flask_app.config['WEB3_ENDPOINT'] = eth_rpc_endpoint if web_ui: for route in [ '/ui/<path:file>', '/ui', '/ui/', '/index.html', '/' ]: self.flask_app.add_url_rule( route, route, view_func=self._serve_webui, methods=['GET'], ) def _add_default_resources(self): self.add_resource(AddressResource, '/address') self.add_resource(ChannelsResource, '/channels') self.add_resource(ChannelsResourceByChannelAddress, '/channels/<hexaddress:channel_address>') self.add_resource(TokensResource, '/tokens') self.add_resource(PartnersResourceByTokenAddress, '/tokens/<hexaddress:token_address>/partners') self.add_resource(RegisterTokenResource, '/tokens/<hexaddress:token_address>') self.add_resource(NetworkEventsResource, '/events/network') self.add_resource(TokenEventsResource, '/events/tokens/<hexaddress:token_address>') self.add_resource(ChannelEventsResource, '/events/channels/<hexaddress:channel_address>') self.add_resource( TokenSwapsResource, '/token_swaps/<hexaddress:target_address>/<int:identifier>') self.add_resource( TransferToTargetResource, '/transfers/<hexaddress:token_address>/<hexaddress:target_address>' ) self.add_resource(ConnectionsResource, '/connection/<hexaddress:token_address>') def _serve_webui(self, file='index.html'): try: assert file web3 = self.flask_app.config.get('WEB3_ENDPOINT') if web3 and 'config.' in file and file.endswith('.json'): response = jsonify({'raiden': self._api_prefix, 'web3': web3}) else: response = send_from_directory( self.flask_app.config['WEBUI_PATH'], file) except (NotFound, AssertionError): response = send_from_directory(self.flask_app.config['WEBUI_PATH'], 'index.html') return response def _register_type_converters(self, additional_mapping=None): # an additional mapping concats to class-mapping and will overwrite existing keys if additional_mapping: mapping = dict(self._type_converter_mapping, **additional_mapping) else: mapping = self._type_converter_mapping for key, value in mapping.items(): self.flask_app.url_map.converters[key] = value def add_resource(self, resource_cls, route): self.flask_api_context.add_resource( resource_cls, route, resource_class_kwargs={'rest_api_object': self.rest_api}) def run(self, host='127.0.0.1', port=5001, **kwargs): self.flask_app.run(host=host, port=port, **kwargs) def start(self, host='127.0.0.1', port=5001): self.wsgiserver = WSGIServer((host, port), self.flask_app) self.wsgiserver.start() def stop(self, timeout=5): if getattr(self, 'wsgiserver', None): self.wsgiserver.stop(timeout) self.wsgiserver = None
class PlatformRuntime(object): def __init__(self, registry, srnodes, container, attach=False): self.registry = registry self.container = container self.srnodes = srnodes self.attach = attach self._resolve = _ProxyResolver(self.registry) self._init() def _init(self): self._proxy = WSGIServer(('', 0), ProxyApp(self._resolve)) self._proxy.start() def dispose(self): self._proxy.stop() def _make_port_specs(self, ports): return [str(port) for port in ports] def make_config(self): """Given a L{Container}, construct a Docker config.""" ports = self._make_port_specs(self.container.ports) return self._container_config(self.container.image, self.container.command, hostname=self.container.instance, environment=self._make_environment(), tty=self.container.tty, stdin_open=self.attach, ports=ports) def _make_environment(self): proxy_netloc = 'http://%s:%d' % (_DOCKER_GATEWAY, self._proxy.server_port) environment = self.container.env or {} environment = environment.copy() for (n, v) in (('GILLIAM_FORMATION', self.container.formation), ('GILLIAM_SERVICE', self.container.service), ('GILLIAM_INSTANCE', self.container.instance), ('GILLIAM_SERVICE_REGISTRY_NODES', self.srnodes), ('GILLIAM_SERVICE_REGISTRY', self.srnodes), ('HTTP_PROXY', proxy_netloc), ('http_proxy', proxy_netloc), ('HTTPS_PROXY', proxy_netloc)): if v is not None: environment[n] = v return _convert_environment_dict_to_array(environment) def _container_config(self, image, command, hostname=None, user=None, detach=False, stdin_open=False, tty=False, mem_limit=0, ports=None, environment=None, dns=None, volumes=None, volumes_from=None): if isinstance(command, six.string_types): command = shlex.split(str(command)) d = { 'Hostname': hostname, 'PortSpecs': ports, 'User': user, 'Tty': tty, 'OpenStdin': stdin_open, 'Memory': mem_limit, 'AttachStdin': self.attach, 'AttachStdout': self.attach, 'AttachStderr': self.attach, 'Env': environment, 'Cmd': command, 'Dns': dns, 'Image': image, 'Volumes': volumes, 'VolumesFrom': volumes_from, } #print "CONFIG", d return d
class APIServer(object): """ Runs the sikorka API server """ # flask TypeConverter # links argument-placeholder in route (e.g. '/<hexaddress: channel_address>') to the Converter _type_converter_mapping = {'hexaddress': HexAddressConverter} _api_prefix = '/api/1' def __init__(self, rest_api, cors_domain_list=None, eth_rpc_endpoint=None, webui=False): self.rest_api = rest_api self.blueprint = create_blueprint() # TODO: Make configurable version self.rest_api.version = 1 if self.rest_api.version == 1: self.flask_api_context = Api( self.blueprint, prefix=self._api_prefix, ) else: raise ValueError('Invalid api version: {}'.format( self.rest_api.version)) rootpath = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) self.flask_app = Flask(__name__, static_url_path='/static', static_folder=os.path.join( rootpath, 'ui', 'static')) if cors_domain_list: CORS(self.flask_app, origins=cors_domain_list) self._add_default_resources() self._register_type_converters() self.flask_app.register_blueprint(self.blueprint) self.flask_app.config['WEBUI_PATH'] = os.path.join(rootpath, 'ui') if webui: for route in ['/index.html', '/']: self.flask_app.add_url_rule( route, route, view_func=self._serve_webui, methods=['GET'], ) def _add_default_resources(self): self.add_resource(AddressResource, '/address') self.add_resource(DetectorSignResource, '/detector_sign/<hexaddress:user_address>') def _register_type_converters(self, additional_mapping=None): # an additional mapping concats to class-mapping and will overwrite existing keys if additional_mapping: mapping = dict(self._type_converter_mapping, **additional_mapping) else: mapping = self._type_converter_mapping for key, value in mapping.items(): self.flask_app.url_map.converters[key] = value def add_resource(self, resource_cls, route): self.flask_api_context.add_resource( resource_cls, route, resource_class_kwargs={'rest_api_object': self.rest_api}) def _serve_webui(self, file='index.html'): try: assert file response = send_from_directory(self.flask_app.config['WEBUI_PATH'], file) except (NotFound, AssertionError): response = send_from_directory(self.flask_app.config['WEBUI_PATH'], 'index.html') return response def run(self, host='127.0.0.1', port=5011, **kwargs): self.flask_app.run(host=host, port=port, **kwargs) def start(self, host='127.0.0.1', port=5011): self.wsgiserver = WSGIServer((host, port), self.flask_app, log=log, error_log=log) self.wsgiserver.start() def stop(self, timeout=5): if getattr(self, 'wsgiserver', None): self.wsgiserver.stop(timeout) self.wsgiserver = None
if args.prepare or len(os.listdir(args.workdir)) == 0: GlastopfHoneypot.prepare_environment(args.workdir) conf_parser = ConfigParser() if not os.path.isfile("glastopf.cfg"): sys.exit("Could not find configuration file: glastopf.cfg") conf_parser.read("glastopf.cfg") if conf_parser.getboolean("logging", "filelog_enabled"): logfile = conf_parser.get("logging", "logfile") else: logfile = None logconsole = conf_parser.getboolean("logging", "consolelog_enabled") logger = logging.getLogger() setup_logging(logconsole, logfile) host = conf_parser.get("webserver", "host") port = conf_parser.getint("webserver", "port") honeypot = GlastopfHoneypot(work_dir=args.workdir) wsgi_wrapper = GlastopfWSGI(honeypot) try: server = WSGIServer((host, port), wsgi_wrapper.application, log=None) wsgi_greenlet = Greenlet(server.start()) #start background worker and drop privs honeypot.start_background_workers() gevent.joinall([wsgi_greenlet]) except KeyboardInterrupt as ex: honeypot.stop_background_workers()
def gfa_thermal_monitor(): from gfa_thermal import config, system_names from gfa_thermal.monitor_system import SystemMonitorGFAThermal from entropyfw.logger import log import logging from logging.handlers import RotatingFileHandler from gevent.wsgi import WSGIServer from flask import Flask, url_for from flask.templating import DispatchingJinjaLoader app = Flask(__name__) server = WSGIServer(("", 5000), app) server.start() @app.errorhandler(Exception) def all_exception_handler(error): log.exception('Whatever exception') @app.errorhandler(404) def handle_bad_request(e): log.exception('Whatever exception') formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s') if config.STREAM_LOG: ch = logging.StreamHandler() ch.setLevel(config.STREAM_LOG_LEVEL) ch.setFormatter(formatter) log.addHandler(ch) if config.FILE_LOG: ch = RotatingFileHandler(config.FILE_LOG_PATH, mode='a', maxBytes=config.FILE_LOG_MAX_SIZE, backupCount=config.FILE_LOG_BACKUP, encoding=None, delay=0) ch.setLevel(config.FILE_LOG_LEVEL) ch.setFormatter(formatter) log.addHandler(ch) s = SystemMonitorGFAThermal(flask_app=app) print(app.url_map) # Enable channel for chan in range(9): conf_val = getattr(config, 'TC08_CHAN_{}'.format(chan)) if conf_val['enable']: log.info('Enabling Channel {}'.format(chan)) s.enable_tc08_channel(chan, tc_type=conf_val['tc_type'], units=conf_val['units']) # # chan = config.TEMPERATURE_CHANNEL_AMBIENT # conf_val = getattr(config, 'TC08_CHAN_{}'.format(chan)) # if conf_val['enable']: # log.info('Enabling Channel {}'.format(chan)) # s.enable_tc08_channel(chan, tc_type=conf_val['tc_type'], units=conf_val['units']) # Configure logger values to save s.elogger.add_log('{}.{}'.format(system_names.TC08_MOD, 'temperatures')) # s.elogger.add_log('{}.{}'.format(system_names.TTiCPX_MOD, 'status.1')) # s.elogger.add_log('{}.{}'.format(system_names.TTiCPX_MOD, 'status.2')) # start loop on tc08 and tticpx every x seconds set at config # s.tticpx.start_timer(config.SENSORS_LOOP_INTERVAL) s.pico.start_timer(config.SENSORS_LOOP_INTERVAL) print(s.list_callbacks()) try: server.serve_forever() finally: # s.tticpx.stop_timer() s.pico.stop_timer() print(s.list_callbacks()) s.exit()
class UIServer(SimpleProcess): """ Process to start a generic UI server that can be extended with content and service gateway """ def on_init(self): # Retain a pointer to this object for use in routes global ui_instance ui_instance = self # Main references to basic components (if initialized) self.http_server = None self.socket_io = None self.service_gateway = None self.oauth = oauth # Configuration self.server_enabled = self.CFG.get_safe(CFG_PREFIX + ".server.enabled") is True self.server_debug = self.CFG.get_safe(CFG_PREFIX + ".server.debug") is True # Note: this may be the empty string. Using localhost does not make the server publicly accessible self.server_hostname = self.CFG.get_safe(CFG_PREFIX + ".server.hostname", DEFAULT_WEB_SERVER_HOSTNAME) self.server_port = self.CFG.get_safe(CFG_PREFIX + ".server.port", DEFAULT_WEB_SERVER_PORT) self.server_log_access = self.CFG.get_safe(CFG_PREFIX + ".server.log_access") is True self.server_log_errors = self.CFG.get_safe(CFG_PREFIX + ".server.log_errors") is True self.server_socket_io = self.CFG.get_safe(CFG_PREFIX + ".server.socket_io") is True self.server_secret = self.CFG.get_safe(CFG_PREFIX + ".security.secret") or "" self.session_timeout = int(self.CFG.get_safe(CFG_PREFIX + ".security.session_timeout") or DEFAULT_SESSION_TIMEOUT) self.extend_session_timeout = self.CFG.get_safe(CFG_PREFIX + ".security.extend_session_timeout") is True self.max_session_validity = int(self.CFG.get_safe(CFG_PREFIX + ".security.max_session_validity") or DEFAULT_SESSION_TIMEOUT) self.remember_user = self.CFG.get_safe(CFG_PREFIX + ".security.remember_user") is True self.set_cors_headers = self.CFG.get_safe(CFG_PREFIX + ".server.set_cors") is True self.develop_mode = self.CFG.get_safe(CFG_PREFIX + ".server.develop_mode") is True self.oauth_enabled = self.CFG.get_safe(CFG_PREFIX + ".oauth.enabled") is True self.oauth_scope = self.CFG.get_safe(CFG_PREFIX + ".oauth.default_scope") or "scioncc" self.has_service_gateway = self.CFG.get_safe(CFG_PREFIX + ".service_gateway.enabled") is True self.service_gateway_prefix = self.CFG.get_safe(CFG_PREFIX + ".service_gateway.url_prefix", DEFAULT_GATEWAY_PREFIX) self.extensions = self.CFG.get_safe(CFG_PREFIX + ".extensions") or [] self.extension_objs = [] # TODO: What about https? self.base_url = "http://%s:%s" % (self.server_hostname or "localhost", self.server_port) self.gateway_base_url = None self.idm_client = IdentityManagementServiceProcessClient(process=self) # One time setup if self.server_enabled: app.secret_key = self.server_secret or self.__class__.__name__ # Enables encrypted session cookies if self.server_debug: app.debug = True if self.server_socket_io: self.socket_io = SocketIO(app) if self.has_service_gateway: from ion.service.service_gateway import ServiceGateway, sg_blueprint self.gateway_base_url = self.base_url + self.service_gateway_prefix self.service_gateway = ServiceGateway(process=self, config=self.CFG, response_class=app.response_class) app.register_blueprint(sg_blueprint, url_prefix=self.service_gateway_prefix) for ext_cls in self.extensions: try: cls = named_any(ext_cls) except AttributeError as ae: # Try to nail down the error import importlib importlib.import_module(ext_cls.rsplit(".", 1)[0]) raise self.extension_objs.append(cls()) for ext_obj in self.extension_objs: ext_obj.on_init(self, app) if self.extensions: log.info("UI Server: %s extensions initialized", len(self.extensions)) # Start the web server self.start_service() log.info("UI Server: Started server on %s" % self.base_url) else: log.warn("UI Server: Server disabled in config") def on_quit(self): self.stop_service() def start_service(self): """ Starts the web server. """ if self.http_server is not None: self.stop_service() if self.server_socket_io: self.http_server = SocketIOServer((self.server_hostname, self.server_port), app.wsgi_app, resource='socket.io', log=None) self.http_server._gl = gevent.spawn(self.http_server.serve_forever) log.info("UI Server: Providing web sockets (socket.io) server") else: self.http_server = WSGIServer((self.server_hostname, self.server_port), app, log=None) self.http_server.start() if self.service_gateway: self.service_gateway.start() log.info("UI Server: Service Gateway started on %s", self.gateway_base_url) for ext_obj in self.extension_objs: ext_obj.on_start() return True def stop_service(self): """ Responsible for stopping the gevent based web server. """ for ext_obj in self.extension_objs: ext_obj.on_stop() if self.http_server is not None: self.http_server.stop() if self.service_gateway: self.service_gateway.stop() # Need to terminate the server greenlet? return True # ------------------------------------------------------------------------- # Authentication def auth_external(self, username, ext_user_id, ext_id_provider="ext"): """ Given username and user identifier from an external identity provider (IdP), retrieve actor_id and establish user session. Return user info from session. Convention is that system local username is ext_id_provider + ":" + username, e.g. "ext_johnbean" Return NotFound if user not registered in system. Caller can react and create a user account through the normal system means @param username the user name the user recognizes. @param ext_user_id a unique identifier coming from the external IdP @param ext_id_provider identifies the external IdP service """ try: if ext_user_id and ext_id_provider and username: local_username = "******" % (ext_id_provider, username) actor_id = self.idm_client.find_actor_identity_by_username(local_username) user_info = self._set_server_session(actor_id, local_username) return build_json_response(user_info) else: raise BadRequest("External user info missing") except Exception: return build_json_error() def login(self): """ Explicit (non-token) login and creation of a server session (Cookie based). """ try: username = get_arg("username") password = get_arg("password") if username and password: actor_id = self.idm_client.check_actor_credentials(username, password) user_info = self._set_server_session(actor_id, username) return build_json_response(user_info) else: raise BadRequest("Username or password missing") except Exception: return build_json_error() def _set_server_session(self, actor_id, username=None): """ Sets server session based on user_id and ActorIdentity. """ actor_user = self.idm_client.read_identity_details(actor_id) if actor_user.type_ != OT.UserIdentityDetails: raise BadRequest("Bad identity details") full_name = actor_user.contact.individual_names_given + " " + actor_user.contact.individual_name_family valid_until = int(get_ion_ts_millis() / 1000 + self.session_timeout) set_auth(actor_id, username, full_name, valid_until=valid_until, roles=actor_user.contact.roles) user_info = get_auth() return user_info def get_session(self): """ Returns user session information for current authentication. This can be polled regularly by client code to detect changes in session state and expiration. """ def call_extend_session_attrs(session_attrs, actor_user): """ Call UI extensions to make additions to user session """ for ext_obj in self.extension_objs: func = getattr(ext_obj, "extend_user_session_attributes", None) if func: try: func(session_attrs, actor_user) except Exception: log.exception("Error calling UI extension extend_user_session_attributes()") try: # Get user session from OAuth access token in HTTP Authorization header auth_hdr = request.headers.get("authorization", None) if auth_hdr: valid, req = self.oauth.verify_request([self.oauth_scope]) # Note: Do NOT extend session timeout here! if valid: actor_id = flask.g.oauth_user.get("actor_id", "") actor_user = self.idm_client.read_actor_identity(actor_id) session_attrs = dict(is_logged_in=True, is_registered=True, attributes={"roles": actor_user.details.contact.roles}, roles={}) if actor_user.session: session_attrs.update(actor_user.session) call_extend_session_attrs(session_attrs, actor_user) return build_json_response(session_attrs) if self.remember_user: # Get user session from user_id/access_token placed inside server session (Cookie) # This is a feature to allow returning users to resume a session if still valid access_token = flask.session.get("access_token", None) actor_id = flask.session.get("actor_id", None) if access_token and actor_id: actor_user = self.idm_client.read_actor_identity(actor_id) session_attrs = dict(access_token=access_token, is_logged_in=True, is_registered=True, attributes={"roles": actor_user.details.contact.roles}, roles={}) if actor_user.session: # Check validity in persisted user session if 0 < int(actor_user.session.get("valid_until", 0)) * 1000 < current_time_millis(): clear_auth() return build_json_response(get_auth()) session_attrs.update(actor_user.session) else: # No trace of existing session in user object clear_auth() return build_json_response(get_auth()) call_extend_session_attrs(session_attrs, actor_user) return build_json_response(session_attrs) # Get user session from Flask session and cookie (non-token mode) user_info = get_auth() if 0 < int(user_info.get("valid_until", 0)) * 1000 < current_time_millis(): clear_auth() # Clear expired session user_info = get_auth() call_extend_session_attrs(user_info, None) return build_json_response(user_info) except Exception: return build_json_error() def logout(self): try: access_token = get_req_bearer_token() or flask.session.get("access_token", None) if access_token: try: # Invalidate access token token_id = str("access_token_%s" % access_token) token_obj = ui_instance.container.object_store.read(token_id) token_obj.status = "CANCELLED" token_obj.attributes["cancel_ts"] = get_ion_ts_millis() token_obj.attributes["cancel_msg"] = "User logout" ui_instance.container.object_store.update(token_obj) log.info("Invalidated stored access token for user=%s", token_obj.actor_id) except NotFound: pass except Exception: log.exception("Error invalidating access token") clear_auth() return build_json_response("OK") except Exception: return build_json_error()
class Application(Singleton): """ Main class of your application. Pass options to constructor and all subsystems(eventer, router, db_engine) will be configured. """ def __init__(self, options): self.init_options(options) self.init_eventer() self.init_router() self.init_templater() self.eventer.publish("BeforeDatabaseEngineConfiguration", self) self.init_db() self.eventer.publish("AfterDatabaseEngineConfiguration", self) self.init_session() self.eventer.publish("BeforeInitStatic", self) self.init_static() self.eventer.publish("AfterInitStatic", self) self.eventer.publish("BeforeInitServer", self) self.init_server() self.eventer.publish("AfterInitServer", self) self.eventer.publish("BeforeApplicationStarted", self) def init_options(self, options): logging.basicConfig(level=logging.CRITICAL) default_options = { "application": { "address": "127.0.0.1", "port": 8080 }, "urls": {}, "views": { "templates_path": [], "templates_extensions": ["compressinja.html.HtmlCompressor", "jinja2.ext.i18n"], "static_path": [], 'session_type': "cookie", "session_auto": True, 'session_cookie_expires': True, 'session_encrypt_key':'sldk24j0jf09w0jfg24', 'session_validate_key':';l[pfghopkqeq1234,fs' }, "events": {} } self.options = Dict.merge(default_options, options) def init_eventer(self): self.eventer = Eventer(self.options["events"]) def init_router(self): self.router = Router(self.options) def init_templater(self): self.templater = Templater(self) def init_static(self): static_builder = None self.add_static(self.options["views"]["static_path"], merge=False) def add_static(self, sps, url_path="/", merge=True): static_path = [] for sp in sps: try: sp = Importer.module_path(sp) except: pass try: static_path.append(sp) static_builder = StaticBuilder(sp) static_builder.build() self.wsgi_app = SharedDataMiddleware(self.wsgi_app, {url_path : sp + "/build"}, cache=False) except: pass if merge: self.options["views"]["static_path"] = self.options["views"]["static_path"] + static_path else: self.options["views"]["static_path"] = static_path def init_db(self): if "models" in self.options: metadata.bind = self.options["models"]["connection"] metadata.bind.echo = False def init_session(self): session_options = { 'session.type': self.options["views"]['session_type'], "session.auto": self.options["views"]["session_auto"], 'session.cookie_expires': self.options["views"]['session_cookie_expires'], 'session.encrypt_key': self.options["views"]['session_encrypt_key'], 'session.validate_key': self.options["views"]['session_validate_key'] } self.wsgi_app = SessionMiddleware(self.wsgi_app, session_options, environ_key="session") def init_static_server(self): for sp in self.options["views"]["static_path"]: self.wsgi_app = SharedDataMiddleware(self.wsgi_app, {'/': sp + "/build"}) def init_server(self): kwargs = dict(filter(lambda item: item[0] not in ["address", "port"], self.options["application"].iteritems())) self.server = WSGIServer((self.options["application"]["address"], self.options["application"]["port"]), self.wsgi_app, **kwargs) def wsgi_app(self, options, start_response): request = Request(options) response = self.router.route(request) return response(options, start_response) def start(self): gevent.signal(signal.SIGTERM, self.stop) gevent.signal(signal.SIGINT, self.stop) self.eventer.publish("ApplicationStarted", self) self.server.serve_forever() def start_no_wait(self): self.eventer.publish("ApplicationStarted", self) self.server.start() def stop(self): self.eventer.publish("ApplicationStopped", self) self.server.stop() if self.db_engine: self.db_engine.close()
class UIServer(SimpleProcess): """ Process to start a generic UI server that can be extended with content and service gateway """ def on_init(self): # Retain a pointer to this object for use in routes global ui_instance ui_instance = self # Main references to basic components (if initialized) self.http_server = None self.socket_io = None self.service_gateway = None self.oauth = oauth # Configuration self.server_enabled = self.CFG.get_safe(CFG_PREFIX + ".server.enabled") is True self.server_debug = self.CFG.get_safe(CFG_PREFIX + ".server.debug") is True # Note: this may be the empty string. Using localhost does not make the server publicly accessible self.server_hostname = self.CFG.get_safe(CFG_PREFIX + ".server.hostname", DEFAULT_WEB_SERVER_HOSTNAME) self.server_port = self.CFG.get_safe(CFG_PREFIX + ".server.port", DEFAULT_WEB_SERVER_PORT) self.server_log_access = self.CFG.get_safe(CFG_PREFIX + ".server.log_access") is True self.server_log_errors = self.CFG.get_safe(CFG_PREFIX + ".server.log_errors") is True self.server_socket_io = self.CFG.get_safe(CFG_PREFIX + ".server.socket_io") is True self.server_secret = self.CFG.get_safe(CFG_PREFIX + ".security.secret") or "" self.session_timeout = int(self.CFG.get_safe(CFG_PREFIX + ".security.session_timeout") or DEFAULT_SESSION_TIMEOUT) self.extend_session_timeout = self.CFG.get_safe(CFG_PREFIX + ".security.extend_session_timeout") is True self.max_session_validity = int(self.CFG.get_safe(CFG_PREFIX + ".security.max_session_validity") or DEFAULT_SESSION_TIMEOUT) self.remember_user = self.CFG.get_safe(CFG_PREFIX + ".security.remember_user") is True self.set_cors_headers = self.CFG.get_safe(CFG_PREFIX + ".server.set_cors") is True self.develop_mode = self.CFG.get_safe(CFG_PREFIX + ".server.develop_mode") is True self.oauth_enabled = self.CFG.get_safe(CFG_PREFIX + ".oauth.enabled") is True self.oauth_scope = self.CFG.get_safe(CFG_PREFIX + ".oauth.default_scope") or "scioncc" self.has_service_gateway = self.CFG.get_safe(CFG_PREFIX + ".service_gateway.enabled") is True self.service_gateway_prefix = self.CFG.get_safe(CFG_PREFIX + ".service_gateway.url_prefix", DEFAULT_GATEWAY_PREFIX) self.extensions = self.CFG.get_safe(CFG_PREFIX + ".extensions") or [] self.extension_objs = [] # TODO: What about https? self.base_url = "http://%s:%s" % (self.server_hostname or "localhost", self.server_port) self.gateway_base_url = None self.idm_client = IdentityManagementServiceProcessClient(process=self) # One time setup if self.server_enabled: app.secret_key = self.server_secret or self.__class__.__name__ # Enables encrypted session cookies if self.server_debug: app.debug = True if self.server_socket_io: self.socket_io = SocketIO(app) if self.has_service_gateway: from ion.services.service_gateway import ServiceGateway, sg_blueprint self.gateway_base_url = self.base_url + self.service_gateway_prefix self.service_gateway = ServiceGateway(process=self, config=self.CFG, response_class=app.response_class) app.register_blueprint(sg_blueprint, url_prefix=self.service_gateway_prefix) for ext_cls in self.extensions: try: cls = named_any(ext_cls) except AttributeError as ae: # Try to nail down the error import importlib importlib.import_module(ext_cls.rsplit(".", 1)[0]) raise self.extension_objs.append(cls()) for ext_obj in self.extension_objs: ext_obj.on_init(self, app) if self.extensions: log.info("UI Server: %s extensions initialized", len(self.extensions)) # Start the web server self.start_service() log.info("UI Server: Started server on %s" % self.base_url) else: log.warn("UI Server: Server disabled in config") def on_quit(self): self.stop_service() def start_service(self): """ Starts the web server. """ if self.http_server is not None: self.stop_service() if self.server_socket_io: self.http_server = SocketIOServer((self.server_hostname, self.server_port), app.wsgi_app, resource='socket.io', log=None) self.http_server._gl = gevent.spawn(self.http_server.serve_forever) log.info("UI Server: Providing web sockets (socket.io) server") else: self.http_server = WSGIServer((self.server_hostname, self.server_port), app, log=None) self.http_server.start() if self.service_gateway: self.service_gateway.start() log.info("UI Server: Service Gateway started on %s", self.gateway_base_url) for ext_obj in self.extension_objs: ext_obj.on_start() return True def stop_service(self): """ Responsible for stopping the gevent based web server. """ for ext_obj in self.extension_objs: ext_obj.on_stop() if self.http_server is not None: self.http_server.stop() if self.service_gateway: self.service_gateway.stop() # Need to terminate the server greenlet? return True # ------------------------------------------------------------------------- # Authentication def auth_external(self, username, ext_user_id, ext_id_provider="ext"): """ Given username and user identifier from an external identity provider (IdP), retrieve actor_id and establish user session. Return user info from session. Convention is that system local username is ext_id_provider + ":" + username, e.g. "ext_johnbean" Return NotFound if user not registered in system. Caller can react and create a user account through the normal system means @param username the user name the user recognizes. @param ext_user_id a unique identifier coming from the external IdP @param ext_id_provider identifies the external IdP service """ try: if ext_user_id and ext_id_provider and username: local_username = "******" % (ext_id_provider, username) actor_id = self.idm_client.find_actor_identity_by_username(local_username) user_info = self._set_server_session(actor_id, local_username) return build_json_response(user_info) else: raise BadRequest("External user info missing") except Exception: return build_json_error() def login(self): """ Explicit (non-token) login and creation of a server session (Cookie based). """ try: username = get_arg("username") password = get_arg("password") if username and password: actor_id = self.idm_client.check_actor_credentials(username, password) user_info = self._set_server_session(actor_id, username) return build_json_response(user_info) else: raise BadRequest("Username or password missing") except Exception: return build_json_error() def _set_server_session(self, actor_id, username=None): """ Sets server session based on user_id and ActorIdentity. """ actor_user = self.idm_client.read_identity_details(actor_id) if actor_user.type_ != OT.UserIdentityDetails: raise BadRequest("Bad identity details") full_name = actor_user.contact.individual_names_given + " " + actor_user.contact.individual_name_family valid_until = int(get_ion_ts_millis() / 1000 + self.session_timeout) set_auth(actor_id, username, full_name, valid_until=valid_until, roles=actor_user.contact.roles) user_info = get_auth() return user_info def get_session(self): """ Returns user session information for current authentication. This can be polled regularly by client code to detect changes in session state and expiration. """ def call_extend_session_attrs(session_attrs, actor_user): """ Call UI extensions to make additions to user session """ for ext_obj in self.extension_objs: func = getattr(ext_obj, "extend_user_session_attributes", None) if func: try: func(session_attrs, actor_user) except Exception: log.exception("Error calling UI extension extend_user_session_attributes()") try: # Get user session from OAuth access token in HTTP Authorization header auth_hdr = request.headers.get("authorization", None) if auth_hdr: valid, req = self.oauth.verify_request([self.oauth_scope]) # Note: Do NOT extend session timeout here! if valid: actor_id = flask.g.oauth_user.get("actor_id", "") actor_user = self.idm_client.read_actor_identity(actor_id) session_attrs = dict(is_logged_in=True, is_registered=True, attributes={"roles": actor_user.details.contact.roles}, roles={}) if actor_user.session: session_attrs.update(actor_user.session) call_extend_session_attrs(session_attrs, actor_user) return build_json_response(session_attrs) if self.remember_user: # Get user session from user_id/access_token placed inside server session (Cookie) # This is a feature to allow returning users to resume a session if still valid access_token = flask.session.get("access_token", None) actor_id = flask.session.get("actor_id", None) if access_token and actor_id: actor_user = self.idm_client.read_actor_identity(actor_id) session_attrs = dict(access_token=access_token, is_logged_in=True, is_registered=True, attributes={"roles": actor_user.details.contact.roles}, roles={}) if actor_user.session: # Check validity in persisted user session if 0 < int(actor_user.session.get("valid_until", 0)) * 1000 < current_time_millis(): clear_auth() return build_json_response(get_auth()) session_attrs.update(actor_user.session) else: # No trace of existing session in user object clear_auth() return build_json_response(get_auth()) call_extend_session_attrs(session_attrs, actor_user) return build_json_response(session_attrs) # Get user session from Flask session and cookie (non-token mode) user_info = get_auth() if 0 < int(user_info.get("valid_until", 0)) * 1000 < current_time_millis(): clear_auth() # Clear expired session user_info = get_auth() call_extend_session_attrs(user_info, None) return build_json_response(user_info) except Exception: return build_json_error() def logout(self): try: access_token = get_req_bearer_token() or flask.session.get("access_token", None) if access_token: try: # Invalidate access token token_id = str("access_token_%s" % access_token) token_obj = ui_instance.container.object_store.read(token_id) token_obj.status = "CANCELLED" token_obj.attributes["cancel_ts"] = get_ion_ts_millis() token_obj.attributes["cancel_msg"] = "User logout" ui_instance.container.object_store.update(token_obj) log.info("Invalidated stored access token for user=%s", token_obj.actor_id) except NotFound: pass except Exception: log.exception("Error invalidating access token") clear_auth() return build_json_response("OK") except Exception: return build_json_error()
class SlackAdapter(object): """ This adapter exposes a webhook that listens for slack messages. The web listener for this is independent of Jeev's WSGI server. They cannot run on the same port. This adapter works the same as Slack's Hubot adapter. So, when integrating with Jeev, from Slack's integration, use Hubot, and point it to the the adapter's listen host and port. """ def __init__(self, jeev, opts): self._jeev = jeev self._opts = opts self._server = WSGIServer((self._opts.get('slack_listen_host', '0.0.0.0'), int(self._opts.get('slack_listen_port', 8080))), self._wsgi_app) self._link_names = str(self._opts.get('slack_link_names', False)).upper() == 'TRUE' self._channel_id_cache = {} self._requests = requests.Session() self._send_url = 'https://%s.slack.com/services/hooks/hubot?token=%s' % (self._opts['slack_team_name'], self._opts['slack_token']) def _wsgi_app(self, environ, start_response): if environ['PATH_INFO'] == '/hubot/slack-webhook' and environ['REQUEST_METHOD'] == 'POST': status = '200 OK' data = environ['wsgi.input'].read() self._parse_message(data) else: status = '404 Not Found' start_response(status, []) return [''] def _parse_message(self, data): data = dict(urlparse.parse_qsl(data)) if data['token'] == self._opts['slack_token'] and data['team_domain'] == self._opts['slack_team_name']: self._channel_id_cache[data['channel_name']] = data['channel_id'] message = Message(data, data['channel_name'], data['user_name'], data['text']) self._jeev._handle_message(message) def start(self): self._server.start() def stop(self): self._server.stop() def send_message(self, channel, message): if channel not in self._channel_id_cache: return args = { 'username': self._jeev.name, 'text': message, 'link_names': self._link_names, 'channel': self._channel_id_cache[channel] } spawn_raw(self._requests.post, self._send_url, json.dumps(args)) def send_messages(self, channel, *messages): for message in messages: self.send_message(channel, message) def send_attachment(self, channel, *attachments): if channel in self._channel_id_cache: channel = self._channel_id_cache[channel] elif not channel.startswith('#'): channel = '#' + channel args = { 'username': self._jeev.name, 'link_names': self._link_names, 'channel': channel, 'attachments': [a.serialize() for a in attachments] } for a in attachments: if not a.has_message_overrides: continue for k, v in a.message_overrides.items(): args[k] = v spawn_raw(self._requests.post, self._send_url, json.dumps(args))
class ServiceGatewayService(BaseServiceGatewayService): """ The Service Gateway Service is the service that uses a gevent web server and Flask to bridge HTTP requests to AMQP RPC ION process service calls. """ def on_init(self): #defaults self.http_server = None #retain a pointer to this object for use in ProcessRPC calls global service_gateway_instance ###### # to prevent cascading failure, here's an attempted hack if service_gateway_instance is not None and service_gateway_instance.http_server is not None: service_gateway_instance.http_server.stop() # end hack ###### service_gateway_instance = self self.server_hostname = self.CFG.get_safe( 'container.service_gateway.web_server.hostname', DEFAULT_WEB_SERVER_HOSTNAME) self.server_port = self.CFG.get_safe( 'container.service_gateway.web_server.port', DEFAULT_WEB_SERVER_PORT) self.web_server_enabled = self.CFG.get_safe( 'container.service_gateway.web_server.enabled', True) self.web_logging = self.CFG.get_safe( 'container.service_gateway.web_server.log') self.log_errors = self.CFG.get_safe( 'container.service_gateway.log_errors', True) #Optional list of trusted originators can be specified in config. self.trusted_originators = self.CFG.get_safe( 'container.service_gateway.trusted_originators') if not self.trusted_originators: self.trusted_originators = None log.info( "Service Gateway will not check requests against trusted originators since none are configured." ) #Get the user_cache_size self.user_cache_size = self.CFG.get_safe( 'container.service_gateway.user_cache_size', DEFAULT_USER_CACHE_SIZE) #Initialize an LRU Cache to keep user roles cached for performance reasons #maxSize = maximum number of elements to keep in cache #maxAgeMs = oldest entry to keep self.user_role_cache = LRUCache(self.user_cache_size, 0, 0) #Start the gevent web server unless disabled if self.web_server_enabled: log.info("Starting service gateway on %s:%s", self.server_hostname, self.server_port) self.start_service(self.server_hostname, self.server_port) #Configure subscriptions for user_cache events self.user_role_event_subscriber = EventSubscriber( event_type=OT.UserRoleModifiedEvent, origin_type="Org", callback=self.user_role_event_callback) self.add_endpoint(self.user_role_event_subscriber) self.user_role_reset_subscriber = EventSubscriber( event_type=OT.UserRoleCacheResetEvent, callback=self.user_role_reset_callback) self.add_endpoint(self.user_role_reset_subscriber) def on_quit(self): self.stop_service() def start_service(self, hostname=DEFAULT_WEB_SERVER_HOSTNAME, port=DEFAULT_WEB_SERVER_PORT): """Responsible for starting the gevent based web server.""" if self.http_server is not None: self.stop_service() self.http_server = WSGIServer((hostname, port), service_gateway_app, log=self.web_logging) self.http_server.start() return True def stop_service(self): """Responsible for stopping the gevent based web server.""" if self.http_server is not None: self.http_server.stop() return True def is_trusted_address(self, requesting_address): if self.trusted_originators is None: return True for addr in self.trusted_originators: if requesting_address == addr: return True return False def user_role_event_callback(self, *args, **kwargs): """ This method is a callback function for receiving Events when User Roles are modified. """ user_role_event = args[0] org_id = user_role_event.origin actor_id = user_role_event.actor_id role_name = user_role_event.role_name log.debug("User Role modified: %s %s %s" % (org_id, actor_id, role_name)) #Evict the user and their roles from the cache so that it gets updated with the next call. if service_gateway_instance.user_role_cache and service_gateway_instance.user_role_cache.has_key( actor_id): log.debug('Evicting user from the user_role_cache: %s' % actor_id) service_gateway_instance.user_role_cache.evict(actor_id) def user_role_reset_callback(self, *args, **kwargs): ''' This method is a callback function for when an event is received to clear the user data cache ''' self.user_role_cache.clear()
class PlatformRuntime(object): def __init__(self, registry, srnodes, container, attach=False): self.registry = registry self.container = container self.srnodes = srnodes self.attach = attach self._resolve = _ProxyResolver(self.registry) self._init() def _init(self): self._proxy = WSGIServer(('', 0), ProxyApp(self._resolve)) self._proxy.start() def dispose(self): self._proxy.stop() def _make_port_specs(self, ports): return [str(port) for port in ports] def make_config(self): """Given a L{Container}, construct a Docker config.""" ports = self._make_port_specs(self.container.ports) return self._container_config(self.container.image, self.container.command, hostname=self.container.instance, environment=self._make_environment(), tty=self.container.tty, stdin_open=self.attach, ports=ports) def _make_environment(self): proxy_netloc = 'http://%s:%d' % (_DOCKER_GATEWAY, self._proxy.server_port) environment = self.container.env or {} environment = environment.copy() for (n, v) in ( ('GILLIAM_FORMATION', self.container.formation), ('GILLIAM_SERVICE', self.container.service), ('GILLIAM_INSTANCE', self.container.instance), ('GILLIAM_SERVICE_REGISTRY_NODES', self.srnodes), ('GILLIAM_SERVICE_REGISTRY', self.srnodes), ('HTTP_PROXY', proxy_netloc), ('http_proxy', proxy_netloc), ('HTTPS_PROXY', proxy_netloc)): if v is not None: environment[n] = v return _convert_environment_dict_to_array(environment) def _container_config(self, image, command, hostname=None, user=None, detach=False, stdin_open=False, tty=False, mem_limit=0, ports=None, environment=None, dns=None, volumes=None, volumes_from=None): if isinstance(command, six.string_types): command = shlex.split(str(command)) d = { 'Hostname': hostname, 'PortSpecs': ports, 'User': user, 'Tty': tty, 'OpenStdin': stdin_open, 'Memory': mem_limit, 'AttachStdin': self.attach, 'AttachStdout': self.attach, 'AttachStderr': self.attach, 'Env': environment, 'Cmd': command, 'Dns': dns, 'Image': image, 'Volumes': volumes, 'VolumesFrom': volumes_from, } #print "CONFIG", d return d
class ServiceGatewayService(BaseServiceGatewayService): """ The Service Gateway Service is the service that uses a gevent web server and Flask to bridge HTTP requests to AMQP RPC ION process service calls. """ def on_init(self): #defaults self.http_server = None #retain a pointer to this object for use in ProcessRPC calls global service_gateway_instance ###### # to prevent cascading failure, here's an attempted hack if service_gateway_instance is not None and service_gateway_instance.http_server is not None: service_gateway_instance.http_server.stop() # end hack ###### service_gateway_instance = self self.server_hostname = self.CFG.get_safe('container.service_gateway.web_server.hostname', DEFAULT_WEB_SERVER_HOSTNAME) self.server_port = self.CFG.get_safe('container.service_gateway.web_server.port', DEFAULT_WEB_SERVER_PORT) self.web_server_enabled = self.CFG.get_safe('container.service_gateway.web_server.enabled', True) self.web_logging = self.CFG.get_safe('container.service_gateway.web_server.log') self.log_errors = self.CFG.get_safe('container.service_gateway.log_errors', False) #Optional list of trusted originators can be specified in config. self.trusted_originators = self.CFG.get_safe('container.service_gateway.trusted_originators') if not self.trusted_originators: self.trusted_originators = None log.info("Service Gateway will not check requests against trusted originators since none are configured.") #Get the user_cache_size self.user_cache_size = self.CFG.get_safe('container.service_gateway.user_cache_size', DEFAULT_USER_CACHE_SIZE) #Initialize an LRU Cache to keep user roles cached for performance reasons #maxSize = maximum number of elements to keep in cache #maxAgeMs = oldest entry to keep self.user_data_cache = LRUCache(self.user_cache_size,0,0) #Start the gevent web server unless disabled if self.web_server_enabled: log.info("Starting service gateway on %s:%s", self.server_hostname, self.server_port) self.start_service(self.server_hostname, self.server_port) #Configure subscriptions for user_cache events self.user_role_event_subscriber = EventSubscriber(event_type=OT.UserRoleModifiedEvent, origin_type="Org", callback=self.user_role_event_callback) self.user_role_event_subscriber.start() self.user_role_reset_subscriber = EventSubscriber(event_type=OT.UserRoleCacheResetEvent, callback=self.user_role_reset_callback) self.user_role_reset_subscriber.start() def on_quit(self): self.stop_service() if self.user_role_event_subscriber is not None: self.user_role_event_subscriber.stop() if self.user_role_reset_subscriber is not None: self.user_role_reset_subscriber.stop() def start_service(self, hostname=DEFAULT_WEB_SERVER_HOSTNAME, port=DEFAULT_WEB_SERVER_PORT): """Responsible for starting the gevent based web server.""" if self.http_server is not None: self.stop_service() self.http_server = WSGIServer((hostname, port), service_gateway_app, log=self.web_logging) self.http_server.start() return True def stop_service(self): """Responsible for stopping the gevent based web server.""" if self.http_server is not None: self.http_server.stop() return True def is_trusted_address(self, requesting_address): if self.trusted_originators is None: return True for addr in self.trusted_originators: if requesting_address == addr: return True return False def user_role_event_callback(self, *args, **kwargs): """ This method is a callback function for receiving Events when User Roles are modified. """ user_role_event = args[0] org_id = user_role_event.origin actor_id = user_role_event.actor_id role_name = user_role_event.role_name log.debug("User Role modified: %s %s %s" % (org_id, actor_id, role_name)) #Evict the user and their roles from the cache so that it gets updated with the next call. if service_gateway_instance.user_data_cache and service_gateway_instance.user_data_cache.has_key(actor_id): log.debug('Evicting user from the user_data_cache: %s' % actor_id) service_gateway_instance.user_data_cache.evict(actor_id) def user_role_reset_callback(self, *args, **kwargs): ''' This method is a callback function for when an event is received to clear the user data cache ''' self.user_data_cache.clear()
try: return jsonify({'buffer' : list(logapp.messages[idx_decode])}) except: traceback.print_exc(file=sys.stderr) abort(408) else: abort(404) @webapp.route('/lost') def lost(): return str(logapp.lost) # run servers if __name__ == '__main__': logsrv = StreamServer(('', 23456), logapp.handle_new_connection) websrv = WSGIServer(('', 8080), webapp) print 'Starting servers...' logsrv.start() websrv.start() try: print 'Listening...' Event().wait() except: print 'Stopping servers' logsrv.stop() websrv.stop() print 'Exiting'