def initialise_routing(): spine_route_lookup_url = config.get_config('SPINE_ROUTE_LOOKUP_URL') spine_org_code = config.get_config('SPINE_ORG_CODE') route_data_dir = pathlib.Path(definitions.ROOT_DIR) / "route" certificates = certs.Certs.create_certs_files( route_data_dir, private_key=secrets.get_secret_config('SPINE_ROUTE_LOOKUP_CLIENT_KEY', default=None), local_cert=secrets.get_secret_config('SPINE_ROUTE_LOOKUP_CLIENT_CERT', default=None), ca_certs=secrets.get_secret_config('SPINE_ROUTE_LOOKUP_CA_CERTS', default=None)) route_proxy_host = config.get_config('SPINE_ROUTE_LOOKUP_HTTP_PROXY', default=None) route_proxy_port = None if route_proxy_host is not None: route_proxy_port = int( config.get_config('SPINE_ROUTE_LOOKUP_HTTP_PROXY_PORT', default="3128")) return routing_reliability.RoutingAndReliability( spine_route_lookup_url, spine_org_code, client_cert=certificates.local_cert_path, client_key=certificates.private_key_path, ca_certs=certificates.ca_certs_path, http_proxy_host=route_proxy_host, http_proxy_port=route_proxy_port)
def initialise_workflows(transmission: outbound_transmission.OutboundTransmission, party_key: str, work_description_store: persistence_adaptor.PersistenceAdaptor, sync_async_store: persistence_adaptor.PersistenceAdaptor, max_request_size: int, persistence_store_retries: int, routing: routing_reliability.RoutingAndReliability) \ -> Dict[str, workflow.CommonWorkflow]: """Initialise the workflows :param transmission: The transmission object to be used to make requests to the spine endpoints :param party_key: The party key to use to identify this MHS. :param work_description_store: The persistence adaptor for the state database. :param sync_async_store: The persistence adaptor for the sync-async database. :param max_request_size: The maximum size of the request body that gets sent to Spine. :param persistence_store_retries The number of times to retry storing values in the work description or sync-async databases. :param routing: The routing and reliability component to use to request routing/reliability details from. :return: The workflows that can be used to handle messages. """ resynchroniser = resync.SyncAsyncResynchroniser( sync_async_store, int(config.get_config('RESYNC_RETRIES', '20')), float(config.get_config('RESYNC_INTERVAL', '1.0')), float(config.get_config('RESYNC_INITIAL_DELAY', '0'))) return workflow.get_workflow_map( party_key, work_description_store=work_description_store, transmission=transmission, resynchroniser=resynchroniser, max_request_size=max_request_size, persistence_store_max_retries=persistence_store_retries, routing=routing)
def main(): config.setup_config("MHS") secrets.setup_secret_config("MHS") log.configure_logging() if config.get_config('NO_TLS', default='False') == 'True': certificates = certs.Certs() else: certificates = certs.Certs.create_certs_files( definitions.ROOT_DIR, private_key=secrets.get_secret_config('CLIENT_KEY'), local_cert=secrets.get_secret_config('CLIENT_CERT'), ca_certs=secrets.get_secret_config('CA_CERTS')) party_key = secrets.get_secret_config('PARTY_KEY') workflows = initialise_workflows() store = dynamo_persistence_adaptor.DynamoPersistenceAdaptor( table_name=config.get_config('STATE_TABLE_NAME')) interactions_config_file = pathlib.Path( definitions.ROOT_DIR) / 'data' / "interactions" / "interactions.json" config_manager = configuration_manager.ConfigurationManager( str(interactions_config_file)) start_inbound_server(certificates.local_cert_path, certificates.ca_certs_path, certificates.private_key_path, party_key, workflows, store, config_manager)
def resolve_read_task(self): colour = self.check_colour() if (self.task_performance is False): print("wykonuje sie") if (colour == eval(get_config("task", "cables"))): cables = Cables() self.task_performance = cables.run() cables.log() elif (colour == eval(get_config("task", "reactor"))): reactor = UnlockReactor() self.task_performance = reactor.run() reactor.log() elif (colour == eval(get_config("task", "swipe_card"))): swipe_card = SwipeCard() self.task_performance = swipe_card.run() swipe_card.log() elif (colour == eval(get_config("task", "download_data"))): download_data = DownloadData() self.task_performance = download_data.run() download_data.log() self.task_performance = False
def __init__(self): self.pause_duration = int( config.get_config('MOCK_LDAP_PAUSE', default="0")) self.mode = config.get_config('MOCK_LDAP_MODE', default="STRICT").upper() self.mock_mhs_data = None self.mock_as_data = None self._read_mock_data()
def get_sds_client(): use_mock = str2bool( config.get_config('MOCK_LDAP_RESPONSE', default=str(False))) if use_mock: pause_duration = int(config.get_config('MOCK_LDAP_PAUSE', default="0")) logger.warning( "!!! IMPORTANT !!! Using LDAP mock response with %sms delay", pause_duration) return SDSMockClient() else: sds_connection = sds_connection_factory.create_connection() search_base = config.get_config("LDAP_SEARCH_BASE") return SDSClient(sds_connection, search_base)
def initialise_workflows() -> Dict[str, workflow.CommonWorkflow]: """Initialise the workflows :return: The workflows that can be used to handle messages. """ queue_adaptor = proton_queue_adaptor.ProtonQueueAdaptor( host=config.get_config('INBOUND_QUEUE_URL'), username=secrets.get_secret_config('INBOUND_QUEUE_USERNAME'), password=secrets.get_secret_config('INBOUND_QUEUE_PASSWORD')) raw_queue_adaptor = proton_queue_adaptor.ProtonQueueAdaptor( host=config.get_config('INBOUND_RAW_QUEUE_URL'), username=secrets.get_secret_config('INBOUND_QUEUE_USERNAME'), password=secrets.get_secret_config('INBOUND_QUEUE_PASSWORD')) sync_async_store = dynamo_persistence_adaptor.DynamoPersistenceAdaptor( table_name=config.get_config('SYNC_ASYNC_STATE_TABLE_NAME')) inbound_queue_max_retries = int( config.get_config('INBOUND_QUEUE_MAX_RETRIES', default='3')) inbound_queue_retry_delay = int( config.get_config('INBOUND_QUEUE_RETRY_DELAY', default='100')) persistence_store_max_retries = int( config.get_config('STATE_STORE_MAX_RETRIES', default='3')) sync_async_delay = int( config.get_config('SYNC_ASYNC_STORE_RETRY_DELAY', default='100')) work_description_store = dynamo_persistence_adaptor.DynamoPersistenceAdaptor( table_name=config.get_config('STATE_TABLE_NAME')) return workflow.get_workflow_map( raw_queue_adaptor=raw_queue_adaptor, inbound_async_queue=queue_adaptor, work_description_store=work_description_store, sync_async_store=sync_async_store, persistence_store_max_retries=persistence_store_max_retries, sync_async_store_retry_delay=sync_async_delay, inbound_queue_max_retries=inbound_queue_max_retries, inbound_queue_retry_delay=inbound_queue_retry_delay)
def create_connection() -> ldap3.Connection: if config.get_config( sds_mock_connection_factory.LDAP_MOCK_DATA_URL_CONFIG_KEY, default=None): return sds_mock_connection_factory.build_mock_sds_connection() else: sds_url = config.get_config("SDS_URL") disable_tls_flag = config.get_config("DISABLE_SDS_TLS", None) use_tls = disable_tls_flag != "True" logger.info('Configuring connection to SDS using {url} {tls}', fparams={ "url": sds_url, "tls": use_tls }) return build_real_sds_connection(sds_url, use_tls)
def configure_logging(): """ A general method to load the overall config of the system, specifically it modifies the root handler to output to stdout and sets the default log levels and format. This is expected to be called once at the start of a application. """ class _CustomFormatter(logging.Formatter): """ A private formatter class, this is required to provide microsecond precision timestamps and utc conversion """ converter = dt.datetime.utcfromtimestamp def formatTime(self, record, datefmt): ct = self.converter(record.created) return ct.strftime(datefmt) logging.addLevelName(AUDIT, "AUDIT") logger = logging.getLogger() log_level = config.get_config('LOG_LEVEL') logger.setLevel(log_level) handler = logging.StreamHandler(sys.stdout) formatter = _CustomFormatter( fmt= '[%(asctime)sZ] %(message)s pid=%(process)d LogLevel=%(levelname)s LoggerName=%(name)s', datefmt='%Y-%m-%dT%H:%M:%S.%f') handler.setFormatter(formatter) logger.handlers = [] logger.addHandler(handler) _check_for_insecure_log_level(log_level)
def main(): config.setup_config("MHS") secrets.setup_secret_config("MHS") log.configure_logging('spine-directory-service') routing = initialise_routing(search_base=config.get_config("SDS_SEARCH_BASE")) start_tornado_server(routing)
def start_tornado_server(routing: routing_reliability.RoutingAndReliability) -> None: """Start the Tornado server :param routing: The routing/reliability component to be used when servicing requests. """ handler_dependencies = {"routing": routing} application = tornado.web.Application([ ("/routing", routing_handler.RoutingRequestHandler, handler_dependencies), ("/reliability", reliability_handler.ReliabilityRequestHandler, handler_dependencies), ("/routing-reliability", routing_reliability_handler.RoutingReliabilityRequestHandler, handler_dependencies), ("/healthcheck", healthcheck_handler.HealthcheckHandler) ]) server = tornado.httpserver.HTTPServer(application) server_port = int(config.get_config('SPINE_ROUTE_LOOKUP_SERVER_PORT', default='80')) server.listen(server_port) logger.info('Starting router server at port {server_port}', fparams={'server_port': server_port}) tornado_io_loop = tornado.ioloop.IOLoop.current() try: tornado_io_loop.start() except KeyboardInterrupt: logger.warning('Keyboard interrupt') pass finally: tornado_io_loop.stop() tornado_io_loop.close(True) logger.info('Server shut down, exiting...')
def load_cache_implementation(): cache_expiry_time = int(config.get_config("SDS_CACHE_EXPIRY_TIME", cache_adaptor.FIFTEEN_MINUTES_IN_SECONDS)) redis_host = config.get_config("SDS_REDIS_CACHE_HOST") redis_port = int(config.get_config("SDS_REDIS_CACHE_PORT", "6379")) disable_tls_flag = config.get_config("SDS_REDIS_DISABLE_TLS", None) use_tls = disable_tls_flag != "True" logger.info('Using the Redis cache with {redis_host}, {redis_port}, {cache_expiry_time}, {use_tls}', fparams={ 'redis_host': redis_host, 'redis_port': redis_port, 'cache_expiry_time': cache_expiry_time, 'use_tls': use_tls }) return redis_cache.RedisCache(redis_host, redis_port, cache_expiry_time, use_tls)
def __init__(self, table_name: str, max_retries: int, retry_delay: float): """ Constructs a DynamoDB version of a :class:`PersistenceAdaptor <sds.common.state.persistence_adaptor.PersistenceAdaptor>`. The kwargs provided should contain the following information: * table_name: The Table Name used to identify the dynamo table containing required items. * max_retries: The number of max retries object should make if there is an error connecting with the DB * retry_delay: The delay between retries :param table_name: Table name to be used in this adaptor. """ self.table_name = table_name self.retry_delay = retry_delay self.max_retries = max_retries self.endpoint_url = config.get_config('DB_ENDPOINT_URL', None) self.region_name = config.get_config('CLOUD_REGION', 'eu-west-2')
async def get_as_details(self, ods_code: str, interaction_id: str, managing_organization: str = None, party_key: str = None) -> List[Dict]: """ Returns the device details for the given parameters :return: Dictionary of the attributes of the device associated with the given parameters """ if not ods_code or not interaction_id: raise SDSException("org_code and interaction_id must be provided") query_parts = [("nhsIDCode", ods_code), ("objectClass", "nhsAs"), ("nhsAsSvcIA", interaction_id), ("nhsMhsManufacturerOrg", managing_organization), ("nhsMHSPartyKey", party_key)] # TODO: can't use atm with Opentest as it lacks required schema attribute if str2bool( config.get_config('DISABLE_MANUFACTURER_ORG_SEARCH_PARAM', default=str(False))): query_parts.remove( ("nhsMhsManufacturerOrg", managing_organization)) result = await self._get_ldap_data(query_parts, AS_ATTRIBUTES) return result
def start_tornado_server(sds_client: SDSClient) -> None: """Start the Tornado server :param sds_client: The sds client component to be used when servicing requests. """ handler_dependencies = {"sds_client": sds_client} application = tornado.web.Application( [("/Endpoint", routing_reliability_handler.RoutingReliabilityRequestHandler, handler_dependencies), ("/Device", accredited_system_handler.AccreditedSystemRequestHandler, handler_dependencies), ("/healthcheck", healthcheck_handler.HealthcheckHandler)], default_handler_class=ErrorHandler) server = tornado.httpserver.HTTPServer(application) server_port = int(config.get_config('SERVER_PORT', default='9000')) server.listen(server_port) logger.info('Starting router server at port {server_port}', fparams={'server_port': server_port}) tornado_io_loop = tornado.ioloop.IOLoop.current() try: tornado_io_loop.start() except KeyboardInterrupt: logger.warning('Keyboard interrupt') pass finally: tornado_io_loop.stop() tornado_io_loop.close(True) logger.info('Server shut down, exiting...')
def _read_real_server_data(output_path, nhs_id_code): ldap_address = config.get_config('SDS_URL') logger.info( "Downloading real server data from '%s' for nhs id code '%s' and saving data at '%s'", ldap_address, nhs_id_code, output_path) server = Server(ldap_address, get_info=ALL) connection = Connection(server, auto_bind=True) server_info_path = os.path.join(output_path, _SERVER_INFO_FILE) logger.info("Saving real server info at '%s'", server_info_path) server.info.to_file(server_info_path) server_schema_path = os.path.join(output_path, _SERVER_SCHEMA_FILE) logger.info("Saving real server schema at '%s'", server_schema_path) server.schema.to_file(server_schema_path) if connection.search('ou=Services,o=nhs', f'(nhsIDCode={nhs_id_code})', attributes=ALL_ATTRIBUTES): server_entries_path = os.path.join(output_path, _SERVER_ENTRIES_FILE) logger.info("Saving server entries at '%s'", server_entries_path) connection.response_to_file(server_entries_path, raw=True) else: logger.error("LDAP search yield no results") connection.unbind()
def create_connection() -> ldap3.Connection: ldap_url = config.get_config("LDAP_URL") disable_tls_flag = config.get_config("LDAP_DISABLE_TLS", None) use_tls = disable_tls_flag != "True" logger.info('Configuring connection to LDAP using {url} {tls}', fparams={"url": ldap_url, "tls": use_tls}) if use_tls: client_key = secrets.get_secret_config('CLIENT_KEY') client_cert = secrets.get_secret_config('CLIENT_CERT') ca_certs = secrets.get_secret_config('CA_CERTS') sds_connection = _build_sds_connection_tls(ldap_address=ldap_url, private_key=client_key, local_cert=client_cert, ca_certs=ca_certs) else: sds_connection = _build_sds_connection(ldap_address=ldap_url) return sds_connection
def test_get_config_no_config_variable_found(self, mock_stdout, mock_environ): mock_environ["PREFIX_LOG_LEVEL"] = "INFO" config.setup_config("PREFIX") def remove_logging_handler(): logging.getLogger().handlers = [] self.addCleanup(remove_logging_handler) integration_adaptors_logger.configure_logging() with self.assertRaises(KeyError): config.get_config("BLAH") output = mock_stdout.getvalue() self.assertIn( 'Failed to get config ConfigName="BLAH" ProcessKey=CONFIG003', output) self.assertIn("LogLevel=ERROR", output)
def resolve_task(self): try: download_btn = pyautogui.center( pyautogui.locateOnScreen( f"assets/tasks/download_data/main.png", confidence=0.7)) pyautogui.click(download_btn[0], download_btn[1]) time.sleep(int(get_config("task_sec_delay", "download_data"))) return True except Exception as e: print(e)
def start_inbound_server( local_certs_file: str, ca_certs_file: str, key_file: str, party_key: str, workflows: Dict[str, workflow.CommonWorkflow], persistence_store: persistence_adaptor.PersistenceAdaptor, config_manager: configuration_manager.ConfigurationManager) -> None: """ :param persistence_store: persistence store adaptor for message information :param local_certs_file: The filename of the certificate to present for authentication. :param ca_certs_file: The filename of the CA certificates as passed to ssl.SSLContext.load_verify_locations :param key_file: The filename of the private key for the certificate identified by local_certs_file. :param workflows: The workflows to be used to handle messages. :param config_manager: The config manager used to obtain interaction details :param party_key: The party key to use to identify this MHS. """ handlers = [(r"/.*", async_request_handler.InboundHandler, dict(workflows=workflows, party_id=party_key, work_description_store=persistence_store, config_manager=config_manager))] healthcheck_endpoint = ("/healthcheck", healthcheck_handler.HealthcheckHandler) # Ensure Client authentication if not config.get_config('NO_TLS', default='False') == 'True': ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ssl_ctx.load_cert_chain(local_certs_file, key_file) # The docs suggest we have to specify both that we must verify the client cert and the locations ssl_ctx.verify_mode = ssl.CERT_REQUIRED ssl_ctx.load_verify_locations(ca_certs_file) inbound_server = tornado.httpserver.HTTPServer( tornado.web.Application(handlers), ssl_options=ssl_ctx) inbound_server.listen(443) logger.info('011', 'Started main handler listener at 443') handlers.insert(0, healthcheck_endpoint) # Start health check on port 80, and mhs service too for testing healthcheck_application = tornado.web.Application(handlers) healthcheck_application.listen(80) logger.info('011', 'Started listener at 80') else: # Add health check endpoint handlers.insert(0, healthcheck_endpoint) inbound_server = tornado.httpserver.HTTPServer( tornado.web.Application(handlers)) inbound_server.listen(80) logger.info('011', 'Started main handler and health check listener at 80') logger.info('011', 'Starting inbound server') tornado.ioloop.IOLoop.current().start()
def build_mock_sds_connection(): url = config.get_config(LDAP_MOCK_DATA_URL_CONFIG_KEY) parsed_url = urlparse(url) _MOCK_DATA_LOADERS[parsed_url.scheme](parsed_url) fake_spine_url = config.get_config(FAKE_SPINE_URL_CONFIG_KEY, default=None) if fake_spine_url: _modify_spine_url(fake_spine_url) else: logger.info( "Skipping spine url modification as config key '%s' is not present", FAKE_SPINE_URL_CONFIG_KEY) fake_server = Server.from_definition('fake_server', _MOCK_DATA_SERVER_INFO_FILE_PATH, _MOCK_DATA_SERVER_SCHEMA_FILE_PATH) fake_connection = Connection(fake_server, client_strategy=MOCK_ASYNC) fake_connection.strategy.entries_from_json( _MOCK_DATA_SERVER_ENTRIES_FILE_PATH) fake_connection.bind() return fake_connection
async def __get_dynamo_table(self): """ Creates a connection to the table referenced by this instance. :return: The table to be used by this instance. """ async with aioboto3.resource('dynamodb', region_name='eu-west-2', endpoint_url=config.get_config( 'DYNAMODB_ENDPOINT_URL', None)) as dynamo_resource: logger.info('008', 'Establishing connection to {table_name}', {'table_name': self.table_name}) yield dynamo_resource.Table(self.table_name)
def _configure_ldap_connection(server) -> ldap3.Connection: lazy_ldap = str2bool(config.get_config("LAZY_LDAP", default=str(True))) if lazy_ldap: connection = ldap3.Connection(server, lazy=True, auto_bind=ldap3.AUTO_BIND_NO_TLS, client_strategy=ldap3.ASYNC) else: connection = ldap3.Connection(server, auto_bind=True, client_strategy=ldap3.REUSABLE) logger.info('LDAP connection configured successfully') return connection
def configure_logging(project_name: str = None): """ A general method to load the overall config of the system, specifically it modifies the root handler to output to stdout and sets the default log levels and format. This is expected to be called once at the start of a application. """ global _project_name, _log_format _project_name = project_name _log_format = config.get_config("LOG_FORMAT", default=LOG_FORMAT_STRING) logging.addLevelName(AUDIT, "AUDIT") logger = logging.getLogger() log_level = config.get_config('LOG_LEVEL') logger.setLevel(log_level) handler = logging.StreamHandler(sys.stdout) formatter = CustomFormatter() handler.setFormatter(formatter) logger.handlers = [] logger.addHandler(handler) _check_for_insecure_log_level(log_level)
def build_app(): interactions = { 'SCR_GP_SUMMARY_UPLOAD': gp_summary_upload.GpSummaryUpload() } address = config.get_config('MHS_ADDRESS') certificates = certs.Certs.create_certs_files(definitions.ROOT_DIR, ca_certs=secrets.get_secret_config('MHS_CA_CERTS', default=None)) sender = message_sender.MessageSender(address, ca_certs=certificates.ca_certs_path) forwarder = message_forwarder.MessageForwarder(interactions, sender) app = tornado.web.Application([(r"/", summary_care_record.SummaryCareRecord, dict(forwarder=forwarder))]) return app
def get_persistence_adaptor(*args, **kwargs) -> PersistenceAdaptor: """ Builds a new persistence adaptor of type defined in environment variable PERSISTENCE_ADAPTOR Must be one of the defined in mhs.common.state.persistence_adaptor_factory._PERSISTENCE_ADAPTOR_TYPES :class:`PersistenceAdaptor <mhs.common.state.persistence_adaptor.PersistenceAdaptor>`. :param args: passed downstream to persistence adaptor constructor :param kwargs: passed downstream to persistence adaptor constructor :return: new instance of persistence adaptor """ persistence_adaptor = config.get_config('PERSISTENCE_ADAPTOR', default=DYNAMO_DB) logger.info("Building persistence adaptor using '%s' type", persistence_adaptor) return PERSISTENCE_ADAPTOR_TYPES[persistence_adaptor.lower()](*args, **kwargs)
def __init__(self, table_name: str, max_retries: int, retry_delay: float): """ Constructs a MongoDB version of a :class:`PersistenceAdaptor <sds.common.state.persistence_adaptor.PersistenceAdaptor>`. The kwargs provided should contain the following information: * table_name: The Table Name used to identify the mongo collection containing required items. * max_retries: The number of max retries object should make if there is an error connecting with the DB * retry_delay: The delay between retries :param table_name: Table name to be used in this adaptor. """ self.table_name = table_name self.retry_delay = retry_delay self.max_retries = max_retries client = AsyncIOMotorClient(config.get_config('DB_ENDPOINT_URL')) self.collection = client[_DB_NAME][table_name]
def _s3_mock_data_loader(parsed_url: ParseResult) -> None: aws_profile = config.get_config('AWS_PROFILE', default=None) bucket_name = parsed_url.netloc key_base = parsed_url.path[1:] session = boto3.Session(profile_name=aws_profile) s3 = session.client('s3') file_names = [_SERVER_INFO_FILE, _SERVER_SCHEMA_FILE, _SERVER_ENTRIES_FILE] for file_name in file_names: src_file_path = os.path.join(key_base, file_name) dest_file_path = os.path.join(_MOCK_DATA_BASE_PATH, file_name) logger.info("Downloading S3 file from '%s' to '%s'", src_file_path, dest_file_path) s3.download_file(bucket_name, src_file_path, dest_file_path)
async def handle_outbound_message(self, from_asid: Optional[str], message_id: str, correlation_id: str, interaction_details: dict, payload: str, wdo: Optional[wd.WorkDescription]) \ -> Tuple[int, str, Optional[wd.WorkDescription]]: logger.info( '0001', 'Entered async forward reliable workflow to handle outbound message' ) logger.audit('0100', 'Outbound {WorkflowName} workflow invoked.', {'WorkflowName': self.workflow_name}) wdo = await self._create_new_work_description_if_required( message_id, wdo, self.workflow_name) try: details = await self._lookup_endpoint_details(interaction_details) url = config.get_config("FORWARD_RELIABLE_ENDPOINT_URL") to_party_key = details[self.ENDPOINT_PARTY_KEY] cpa_id = details[self.ENDPOINT_CPA_ID] except Exception: await wdo.set_outbound_status( wd.MessageStatus.OUTBOUND_MESSAGE_PREPARATION_FAILED) return 500, 'Error obtaining outbound URL', None reliability_details = await self._lookup_reliability_details( interaction_details, interaction_details.get('ods-code')) retry_interval_xml_datetime = reliability_details[ common_asynchronous.MHS_RETRY_INTERVAL] try: retry_interval = DateUtilities.convert_xml_date_time_format_to_seconds( retry_interval_xml_datetime) except isoerror.ISO8601Error: await wdo.set_outbound_status( wd.MessageStatus.OUTBOUND_MESSAGE_PREPARATION_FAILED) return 500, 'Error when converting retry interval: {} to seconds'.format( retry_interval_xml_datetime), None error, http_headers, message = await self._serialize_outbound_message( message_id, correlation_id, interaction_details, payload, wdo, to_party_key, cpa_id) if error: return error[0], error[1], None return await self._make_outbound_request_with_retries_and_handle_response( url, http_headers, message, wdo, reliability_details, retry_interval)
def main(): config.setup_config("MHS") secrets.setup_secret_config("MHS") log.configure_logging() data_dir = pathlib.Path(definitions.ROOT_DIR) / "data" configure_http_client() routing = initialise_routing() certificates = certs.Certs.create_certs_files( data_dir / '..', private_key=secrets.get_secret_config('CLIENT_KEY'), local_cert=secrets.get_secret_config('CLIENT_CERT'), ca_certs=secrets.get_secret_config('CA_CERTS')) max_retries = int( config.get_config('OUTBOUND_TRANSMISSION_MAX_RETRIES', default="3")) retry_delay = int( config.get_config('OUTBOUND_TRANSMISSION_RETRY_DELAY', default="100")) http_proxy_host = config.get_config('OUTBOUND_HTTP_PROXY', default=None) http_proxy_port = None if http_proxy_host is not None: http_proxy_port = int( config.get_config('OUTBOUND_HTTP_PROXY_PORT', default="3128")) transmission = outbound_transmission.OutboundTransmission( certificates.local_cert_path, certificates.private_key_path, certificates.ca_certs_path, max_retries, retry_delay, http_proxy_host, http_proxy_port) party_key = secrets.get_secret_config('PARTY_KEY') work_description_store = dynamo_persistence_adaptor.DynamoPersistenceAdaptor( table_name=config.get_config('STATE_TABLE_NAME')) sync_async_store = dynamo_persistence_adaptor.DynamoPersistenceAdaptor( table_name=config.get_config('SYNC_ASYNC_STATE_TABLE_NAME')) store_retries = int( config.get_config('STATE_STORE_MAX_RETRIES', default='3')) max_request_size = int(config.get_config('SPINE_REQUEST_MAX_SIZE')) workflows = initialise_workflows(transmission, party_key, work_description_store, sync_async_store, max_request_size, store_retries, routing) start_tornado_server(data_dir, workflows)