From d6a4da6050eac45ed5d8f8e7f1e202ca0cdaf767 Mon Sep 17 00:00:00 2001 From: Peter Hamilton Date: Tue, 21 Jul 2015 08:54:44 -0400 Subject: [PATCH] Adding customizable timeout support to the KMIP client This change adds support for a customizable timeout option for the KMIP client. The client will stop attempting connections or operations once the timeout is exceeded instead of waiting for the default system timeout. The default timeouts is 30 seconds. --- kmip/core/config_helper.py | 4 ++++ kmip/kmipconfig.ini | 1 + kmip/services/kmip_client.py | 23 +++++++++++++++++++---- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/kmip/core/config_helper.py b/kmip/core/config_helper.py index bdfb93a..0ab7726 100644 --- a/kmip/core/config_helper.py +++ b/kmip/core/config_helper.py @@ -36,6 +36,9 @@ class ConfigHelper(object): DEFAULT_USERNAME = None DEFAULT_PASSWORD = None + # Timeout measured in seconds + DEFAULT_TIMEOUT = 30 + def __init__(self): self.logger = logging.getLogger(__name__) @@ -78,6 +81,7 @@ class ConfigHelper(object): return_value = default_value self.logger.debug(DEFAULT_MSG.format(default_value, config_option_name)) + # TODO (peter-hamilton): Think about adding better value validation if return_value == self.NONE_VALUE: return None else: diff --git a/kmip/kmipconfig.ini b/kmip/kmipconfig.ini index 1adc533..783f864 100644 --- a/kmip/kmipconfig.ini +++ b/kmip/kmipconfig.ini @@ -10,6 +10,7 @@ do_handshake_on_connect=True suppress_ragged_eofs=True username=None password=None +timeout=30 [server] host=127.0.0.1 diff --git a/kmip/services/kmip_client.py b/kmip/services/kmip_client.py index 77c245b..c68f815 100644 --- a/kmip/services/kmip_client.py +++ b/kmip/services/kmip_client.py @@ -78,7 +78,7 @@ class KMIPProxy(KMIP): cert_reqs=None, ssl_version=None, ca_certs=None, do_handshake_on_connect=None, suppress_ragged_eofs=None, - username=None, password=None, config='client'): + username=None, password=None, timeout=30, config='client'): super(KMIPProxy, self).__init__() self.logger = logging.getLogger(__name__) self.credential_factory = CredentialFactory() @@ -87,7 +87,7 @@ class KMIPProxy(KMIP): self._set_variables(host, port, keyfile, certfile, cert_reqs, ssl_version, ca_certs, do_handshake_on_connect, suppress_ragged_eofs, - username, password) + username, password, timeout) self.batch_items = [] self.conformance_clauses = [ @@ -217,7 +217,13 @@ class KMIPProxy(KMIP): suppress_ragged_eofs=self.suppress_ragged_eofs) self.protocol = KMIPProtocol(self.socket) - self.socket.connect((self.host, self.port)) + self.socket.settimeout(self.timeout) + + try: + self.socket.connect((self.host, self.port)) + except socket.timeout as e: + self.logger.error("timeout occurred while connecting to appliance") + raise e def close(self): self.socket.shutdown(socket.SHUT_RDWR) @@ -816,7 +822,7 @@ class KMIPProxy(KMIP): def _set_variables(self, host, port, keyfile, certfile, cert_reqs, ssl_version, ca_certs, do_handshake_on_connect, suppress_ragged_eofs, - username, password): + username, password, timeout): conf = ConfigHelper() self.host = conf.get_valid_value( @@ -859,3 +865,12 @@ class KMIPProxy(KMIP): self.password = conf.get_valid_value( password, self.config, 'password', conf.DEFAULT_PASSWORD) + + self.timeout = conf.get_valid_value( + timeout, self.config, 'timeout', conf.DEFAULT_TIMEOUT) + if self.timeout < 0: + self.logger.warning( + "Negative timeout value specified, " + "resetting to safe default of {0} seconds".format( + conf.DEFAULT_TIMEOUT)) + self.timeout = conf.DEFAULT_TIMEOUT