def begin_session(handler, scenario_name, session_name, mode, system_date=None, warm_cache=False): log.debug('begin_session') response = {'version': version} scenario_col = Scenario() cache = Cache(get_hostname(handler.request)) if cache.blacklisted(): raise exception_response( 400, title="Sorry the host URL '{0}' has been " "blacklisted. Please contact Stub-O-Matic support.".format( cache.host)) scenario_name_key = cache.scenario_key_name(scenario_name) scenario = scenario_col.get(scenario_name_key) cache.assert_valid_session(scenario_name, session_name) if mode == 'record': log.debug('begin_session, mode=record') # precond: delete/stubs?scenario={scenario_name} if scenario: err = exception_response( 400, title='Duplicate scenario found - {0}'.format( scenario_name_key)) raise err if scenario_col.stub_count(scenario_name_key) != 0: raise exception_response( 500, title='stub_count !=0 for scenario: {0}'.format( scenario_name_key)) scenario_id = scenario_col.insert(name=scenario_name_key) log.debug('new scenario: {0}'.format(scenario_id)) session_payload = { 'status': 'record', 'scenario': scenario_name_key, 'scenario_id': str(scenario_id), 'session': str(session_name) } cache.set_session(scenario_name, session_name, session_payload) log.debug('new redis session: {0}:{1}'.format(scenario_name_key, session_name)) response["data"] = { 'message': 'Record mode initiated....', } response["data"].update(session_payload) cache.set_session_map(scenario_name, session_name) log.debug('finish record') elif mode == 'playback': if not scenario: raise exception_response( 400, title='Scenario not found - {0}'.format(scenario_name_key)) recordings = cache.get_sessions_status(scenario_name, status=('record'), local=False) if recordings: raise exception_response(400, title='Scenario recordings taking ' \ 'place - {0}. Found the following record sessions: {1}'.format( scenario_name_key, recordings)) cache.create_session_cache(scenario_name, session_name, system_date) if warm_cache: # iterate over stubs and call get/response for each stub matchers # to build the request & request_index cache # reset request_index to 0 log.debug("warm cache for session '{0}'".format(session_name)) scenario_col = Scenario() for payload in scenario_col.get_stubs(scenario_name_key): stub = Stub(payload['stub'], scenario_name_key) mock_request = " ".join(stub.contains_matchers()) handler.request.body = mock_request get_response(handler, session_name) cache.reset_request_index(scenario_name) response["data"] = {"message": "Playback mode initiated...."} response["data"].update({ "status": "playback", "scenario": scenario_name_key, "session": str(session_name) }) else: raise exception_response(400, title='Mode of playback or record required') return response
def get_response(handler, session_name): request = handler.request stubo_request = StuboRequest(request) request_body = stubo_request.request_body() if not request_body: # TODO: not an error if they match on other attrs raise exception_response(400, title='No text in body') cache = Cache(get_hostname(request)) if cache.blacklisted(): raise exception_response( 400, title="Sorry the host URL '{0}' has been " "blacklisted. Please contact Stub-O-Matic support.".format( cache.host)) scenario_key = cache.find_scenario_key(session_name) scenario_name = scenario_key.partition(':')[-1] handler.track.scenario = scenario_name request_id = compute_hash(request_body) module_system_date = handler.get_argument('system_date', None) url_args = handler.track.request_params if not module_system_date: # BA LEGACY module_system_date = handler.get_argument('stubbedSystemDate', None) trace_matcher = TrackTrace(handler.track, 'matcher') user_cache = handler.settings['ext_cache'] # check cached requests cached_request = cache.get_request(scenario_name, session_name, request_id) if cached_request: response_ids, delay_policy_name, recorded, system_date, module_info, request_index_key = cached_request else: retry_count = 5 if handler.settings.get('is_cluster', False) else 1 session, retries = cache.get_session_with_delay( scenario_name, session_name, retry_count=retry_count, retry_interval=1) if retries > 0: log.warn("replication was slow for session: {0} {1}, it took {2} "\ "secs!".format(scenario_key, session_name, retries+1)) if session['status'] != 'playback': raise exception_response( 500, title='cache status != playback. session={0}'.format(session)) system_date = session['system_date'] if not system_date: raise exception_response( 500, title="slave session {0} not available for scenario {1}". format(session_name, scenario_key)) session['ext_cache'] = user_cache results = match(stubo_request, session, trace_matcher, as_date(system_date), url_args=url_args, hooks=handler.settings['hooks'], module_system_date=module_system_date) # 0 is best match hits_info, stub = results[0] log.debug(u'match result: (hits_info={0}, stub={1})'.format( hits_info, stub.payload)) hits, stub_number = hits_info if not hits: raise exception_response(400, title='E017:No matching response found') response_ids = stub.response_ids() delay_policy_name = stub.delay_policy_name() recorded = stub.recorded() module_info = stub.module() request_index_key = add_request( session, request_id, stub, system_date, stub_number, handler.settings['request_cache_limit']) if not stub.response_body(): stub.set_response_body( stub.get_response_body_from_cache(request_index_key)) if delay_policy_name: stub.load_delay_from_cache(delay_policy_name) if cached_request: stub = StubCache({}, scenario_key, session_name) stub.load_from_cache(response_ids, delay_policy_name, recorded, system_date, module_info, request_index_key) trace_response = TrackTrace(handler.track, 'response') if module_info: trace_response.info('module used', str(module_info)) response_text = stub.response_body() if not response_text: raise exception_response( 500, title='Unable to find response in ' 'cache using session: {0}:{1}, response_ids: {2}'.format( scenario_key, session_name, response_ids)) # get latest delay policy delay_policy = stub.delay_policy() if delay_policy: delay = calculate_delay(delay_policy) if delay: msg = 'apply delay: {0} => {1}'.format(delay_policy, delay) log.debug(msg) handler.track['delay'] = delay trace_response.info(msg) trace_response.info('found response') module_system_date = as_date(module_system_date) if module_system_date \ else module_system_date stub, _ = transform(stub, stubo_request, module_system_date=module_system_date, system_date=as_date(system_date), function='get/response', cache=user_cache, hooks=handler.settings['hooks'], stage='response', trace=trace_response, url_args=url_args) transfomed_response_text = stub.response_body()[0] # Note transformed_response_text can be encoded in utf8 if response_text[0] != transfomed_response_text: trace_response.diff('response:transformed', dict(response=response_text[0]), dict(response=transfomed_response_text)) return transfomed_response_text
def begin_session(handler, scenario_name, session_name, mode, system_date=None, warm_cache=False): """ Begins session for given scenario :param handler: request handler class :param scenario_name: scenario name :param session_name: session name :param mode: mode - record, playback :param system_date: :param warm_cache: :return: :raise exception_response: """ log.debug('begin_session') response = { 'version': version } scenario_manager = Scenario() cache = Cache(get_hostname(handler.request)) if cache.blacklisted(): raise exception_response(400, title="Sorry the host URL '{0}' has been " "blacklisted. Please contact Stub-O-Matic support.".format(cache.host)) # checking whether full name (with hostname) was passed, if not - getting full name # scenario_name_key = "localhost:scenario_1" if ":" not in scenario_name: scenario_name_key = cache.scenario_key_name(scenario_name) else: # setting scenario full name scenario_name_key = scenario_name # removing hostname from scenario name scenario_name = scenario_name.split(":")[1] # get scenario document scenario_doc = scenario_manager.get(scenario_name_key) if not scenario_doc: raise exception_response(404, title='Scenario not found - {0}. To begin a' ' session - create a scenario.'.format(scenario_name_key)) cache.assert_valid_session(scenario_name, session_name) if mode == 'record': log.debug('begin_session, mode=record') # check if there are any existing stubs in this scenario if scenario_manager.stub_count(scenario_name_key) > 0: err = exception_response(400, title='Scenario ({0}) has existing stubs, delete them before ' 'recording or create another scenario!'.format(scenario_name_key)) raise err scenario_id = scenario_doc['_id'] log.debug('new scenario: {0}'.format(scenario_id)) session_payload = { 'status': 'record', 'scenario': scenario_name_key, 'scenario_id': str(scenario_id), 'session': str(session_name) } cache.set_session(scenario_name, session_name, session_payload) log.debug('new redis session: {0}:{1}'.format(scenario_name_key, session_name)) response["data"] = { 'message': 'Record mode initiated....', } response["data"].update(session_payload) cache.set_session_map(scenario_name, session_name) log.debug('finish record') elif mode == 'playback': recordings = cache.get_sessions_status(scenario_name, status='record', local=False) if recordings: raise exception_response(400, title='Scenario recordings taking ' 'place - {0}. Found the ' 'following record sessions: {1}'.format(scenario_name_key, recordings)) cache.create_session_cache(scenario_name, session_name, system_date) if warm_cache: # iterate over stubs and call get/response for each stub matchers # to build the request & request_index cache # reset request_index to 0 log.debug("warm cache for session '{0}'".format(session_name)) scenario_manager = Scenario() for payload in scenario_manager.get_stubs(scenario_name_key): stub = Stub(payload['stub'], scenario_name_key) mock_request = " ".join(stub.contains_matchers()) handler.request.body = mock_request get_response(handler, session_name) cache.reset_request_index(scenario_name) response["data"] = { "message": "Playback mode initiated...." } response["data"].update({ "status": "playback", "scenario": scenario_name_key, "session": str(session_name) }) else: raise exception_response(400, title='Mode of playback or record required') return response
def begin_session(handler, scenario_name, session_name, mode, system_date=None, warm_cache=False): log.debug('begin_session') response = { 'version' : version } scenario_col = Scenario() cache = Cache(get_hostname(handler.request)) if cache.blacklisted(): raise exception_response(400, title="Sorry the host URL '{0}' has been " "blacklisted. Please contact Stub-O-Matic support.".format(cache.host)) scenario_name_key = cache.scenario_key_name(scenario_name) scenario = scenario_col.get(scenario_name_key) cache.assert_valid_session(scenario_name, session_name) if mode == 'record': log.debug('begin_session, mode=record') # precond: delete/stubs?scenario={scenario_name} if scenario: err = exception_response(400, title='Duplicate scenario found - {0}'.format(scenario_name_key)) raise err if scenario_col.stub_count(scenario_name_key) != 0: raise exception_response(500, title='stub_count !=0 for scenario: {0}'.format( scenario_name_key)) scenario_id = scenario_col.insert(name=scenario_name_key) log.debug('new scenario: {0}'.format(scenario_id)) session_payload = { 'status' : 'record', 'scenario' : scenario_name_key, 'scenario_id' : str(scenario_id), 'session' : str(session_name) } cache.set_session(scenario_name, session_name, session_payload) log.debug('new redis session: {0}:{1}'.format(scenario_name_key, session_name)) response["data"] = { 'message' : 'Record mode initiated....', } response["data"].update(session_payload) cache.set_session_map(scenario_name, session_name) log.debug('finish record') elif mode == 'playback': if not scenario: raise exception_response(400, title='Scenario not found - {0}'.format(scenario_name_key)) recordings = cache.get_sessions_status(scenario_name, status=('record'), local=False) if recordings: raise exception_response(400, title='Scenario recordings taking ' \ 'place - {0}. Found the following record sessions: {1}'.format( scenario_name_key, recordings)) cache.create_session_cache(scenario_name, session_name, system_date) if warm_cache: # iterate over stubs and call get/response for each stub matchers # to build the request & request_index cache # reset request_index to 0 log.debug("warm cache for session '{0}'".format(session_name)) scenario_col = Scenario() for payload in scenario_col.get_stubs(scenario_name_key): stub = Stub(payload['stub'], scenario_name_key) mock_request = " ".join(stub.contains_matchers()) handler.request.body = mock_request get_response(handler, session_name) cache.reset_request_index(scenario_name) response["data"] = { "message" : "Playback mode initiated...." } response["data"].update({ "status" : "playback", "scenario" : scenario_name_key, "session" : str(session_name) }) else: raise exception_response(400, title='Mode of playback or record required') return response
def get_response(handler, session_name): request = handler.request stubo_request = StuboRequest(request) cache = Cache(get_hostname(request)) if cache.blacklisted(): raise exception_response(400, title="Sorry the host URL '{0}' has been " "blacklisted. Please contact Stub-O-Matic support.".format(cache.host)) scenario_key = cache.find_scenario_key(session_name) scenario_name = scenario_key.partition(':')[-1] handler.track.scenario = scenario_name request_id = stubo_request.id() module_system_date = handler.get_argument('system_date', None) url_args = handler.track.request_params if not module_system_date: # LEGACY module_system_date = handler.get_argument('stubbedSystemDate', None) trace_matcher = TrackTrace(handler.track, 'matcher') user_cache = handler.settings['ext_cache'] # check cached requests cached_request = cache.get_request(scenario_name, session_name, request_id) if cached_request: response_ids, delay_policy_name, recorded, system_date, module_info, request_index_key = cached_request else: retry_count = 5 if handler.settings.get('is_cluster', False) else 1 session, retries = cache.get_session_with_delay(scenario_name, session_name, retry_count=retry_count, retry_interval=1) if retries > 0: log.warn("replication was slow for session: {0} {1}, it took {2} "\ "secs!".format(scenario_key, session_name, retries+1)) if session['status'] != 'playback': raise exception_response(500, title='cache status != playback. session={0}'.format(session)) system_date = session['system_date'] if not system_date: raise exception_response(500, title="slave session {0} not available for scenario {1}".format( session_name, scenario_key)) session['ext_cache'] = user_cache result = match(stubo_request, session, trace_matcher, as_date(system_date), url_args=url_args, hooks=handler.settings['hooks'], module_system_date=module_system_date) if not result[0]: raise exception_response(400, title='E017:No matching response found') _, stub_number, stub = result response_ids = stub.response_ids() delay_policy_name = stub.delay_policy_name() recorded = stub.recorded() module_info = stub.module() request_index_key = add_request(session, request_id, stub, system_date, stub_number, handler.settings['request_cache_limit']) if not stub.response_body(): _response = stub.get_response_from_cache(request_index_key) stub.set_response_body(_response['body']) if delay_policy_name: stub.load_delay_from_cache(delay_policy_name) if cached_request: stub = StubCache({}, scenario_key, session_name) stub.load_from_cache(response_ids, delay_policy_name, recorded, system_date, module_info, request_index_key) trace_response = TrackTrace(handler.track, 'response') if module_info: trace_response.info('module used', str(module_info)) response_text = stub.response_body() if not response_text: raise exception_response(500, title='Unable to find response in ' 'cache using session: {0}:{1}, response_ids: {2}'.format( scenario_key, session_name, response_ids)) # get latest delay policy delay_policy = stub.delay_policy() if delay_policy: delay = Delay.parse_args(delay_policy) if delay: delay = delay.calculate() msg = 'apply delay: {0} => {1}'.format(delay_policy, delay) log.debug(msg) handler.track['delay'] = delay trace_response.info(msg) trace_response.info('found response') module_system_date = as_date(module_system_date) if module_system_date \ else module_system_date stub, _ = transform(stub, stubo_request, module_system_date=module_system_date, system_date=as_date(system_date), function='get/response', cache=user_cache, hooks=handler.settings['hooks'], stage='response', trace=trace_response, url_args=url_args) transfomed_response_text = stub.response_body()[0] # Note transformed_response_text can be encoded in utf8 if response_text[0] != transfomed_response_text: trace_response.diff('response:transformed', dict(response=response_text[0]), dict(response=transfomed_response_text)) if stub.response_status() != 200: handler.set_status(stub.response_status()) if stub.response_headers(): for k, v in stub.response_headers().iteritems(): handler.set_header(k, v) return transfomed_response_text
def begin_session(handler, scenario_name, session_name, mode, system_date=None, warm_cache=False): """ Begins session for given scenario :param handler: request handler class :param scenario_name: scenario name :param session_name: session name :param mode: mode - record, playback :param system_date: :param warm_cache: :return: :raise exception_response: """ log.debug('begin_session') response = {'version': version} scenario_manager = Scenario() cache = Cache(get_hostname(handler.request)) if cache.blacklisted(): raise exception_response( 400, title="Sorry the host URL '{0}' has been " "blacklisted. Please contact Stub-O-Matic support.".format( cache.host)) # checking whether full name (with hostname) was passed, if not - getting full name # scenario_name_key = "localhost:scenario_1" if ":" not in scenario_name: scenario_name_key = cache.scenario_key_name(scenario_name) else: # setting scenario full name scenario_name_key = scenario_name # removing hostname from scenario name scenario_name = scenario_name.split(":")[1] # get scenario document scenario_doc = scenario_manager.get(scenario_name_key) if not scenario_doc: raise exception_response( 404, title='Scenario not found - {0}. To begin a' ' session - create a scenario.'.format(scenario_name_key)) cache.assert_valid_session(scenario_name, session_name) if mode == 'record': log.debug('begin_session, mode=record') # check if there are any existing stubs in this scenario if scenario_manager.stub_count(scenario_name_key) > 0: err = exception_response( 400, title='Scenario ({0}) has existing stubs, delete them before ' 'recording or create another scenario!'.format( scenario_name_key)) raise err scenario_id = scenario_doc['_id'] log.debug('new scenario: {0}'.format(scenario_id)) session_payload = { 'status': 'record', 'scenario': scenario_name_key, 'scenario_id': str(scenario_id), 'session': str(session_name) } cache.set_session(scenario_name, session_name, session_payload) log.debug('new redis session: {0}:{1}'.format(scenario_name_key, session_name)) response["data"] = { 'message': 'Record mode initiated....', } response["data"].update(session_payload) cache.set_session_map(scenario_name, session_name) log.debug('finish record') elif mode == 'playback': recordings = cache.get_sessions_status(scenario_name, status='record', local=False) if recordings: raise exception_response(400, title='Scenario recordings taking ' 'place - {0}. Found the ' 'following record sessions: {1}'.format( scenario_name_key, recordings)) cache.create_session_cache(scenario_name, session_name, system_date) if warm_cache: # iterate over stubs and call get/response for each stub matchers # to build the request & request_index cache # reset request_index to 0 log.debug("warm cache for session '{0}'".format(session_name)) scenario_manager = Scenario() for payload in scenario_manager.get_stubs(scenario_name_key): stub = Stub(payload['stub'], scenario_name_key) mock_request = " ".join(stub.contains_matchers()) handler.request.body = mock_request get_response(handler, session_name) cache.reset_request_index(scenario_name) response["data"] = {"message": "Playback mode initiated...."} response["data"].update({ "status": "playback", "scenario": scenario_name_key, "session": str(session_name) }) else: raise exception_response(400, title='Mode of playback or record required') return response