def _hash_with_service_secret(self, *arg_list): '''Hashes arguments with the shared service secret.''' try: service_secret = hexdigest.read_hexdigest(self.service_secret_path) hash = hmac.new(service_secret, digestmod=hexdigest.HASH_CLASS) [ hash.update(a) for a in arg_list ] except Exception, x: import traceback log.log_exception() logging.error('self: %s' % self.classname()) # logging.error('service_secret: %s' % service_secret) logging.error('arg_list: %s (%s)' % (str(arg_list), type(arg_list))) raise
def _process_api_exception(self, request, exc, user_exception=None): '''Handle exception raised within API method.''' log.log_exception() LOGGER.info('%s: %s %s exception response to %s', self.classname(), request.path, exc.__class__.__name__, self._format_remote_client(request)) try: if user_exception: exc_pickle = pickle.dumps(user_exception) else: exc_pickle = pickle.dumps(exc) # pylint: disable=W0703 except Exception: log.log_exception('error pickling exception') exc_pickle = pickle.dumps(ServerError('server error')) return { WebService._fault_key : exc_pickle }
def validate(self): '''Validate configuration section.''' # List for errors accumulated by validation. error_list = list() # pylint: disable=E1101 logging.debug('validating section \'%s\'', self.name) temp_value_dict = dict() # Iterate over all defined rules. for rule in self._rule_list: # pylint: disable=E1101 logging.debug('validating option \'%s\'', rule.option) # Does section have this attribute? if not hasattr(self, rule.option): # Append error to error list if option doesn't appear in # options for section; skip further processing of this rule. logging.debug('option \'%s\' missing', rule.option) error_list.append(self._make_option_exception(rule, 'required option missing')) continue # If valid rule type specified, perform type conversion. if rule.type: try: value = self._convert_type(rule) temp_value_dict[rule.option.lower()] = value except Config.ValidationError as exc: error_list.append(exc) # pylint: disable=W0703 except Exception as exc: # Append any error produced by type conversion to # error list. log.log_exception() error_list.append \ (self._make_option_exception(rule, 'EXCEPTION: %s' % exc)) # pylint: disable=E1101 logging.debug \ ('option \'%s\' failed to convert to %s', rule.option, rule.type.__name__) continue # pylint: disable=E1101 logging.debug \ ('option \'%s\' converted to %s', rule.option, rule.type.__name__) else: # No type converstion necessary for string option. value = getattr(self, rule.option) # If rule validator callback is specified, call it with # AttrDict consisting of a single rule/value pair. if rule.validator: try: # Call rule validator callback with converted value. self._run_rule_validator(rule, value) except Config.ValidationError as exc: error_list.append(exc) logging.debug('option \'%s\' failed to validate', rule.option) except Exception as exc: # Log exception. log.log_exception() # Append error produced by rule validator to error list. error_list.append(exc) logging.debug('option \'%s\' failed to validate', rule.option) continue logging.debug('option \'%s\' validated', rule.option) # If section validator callback is specified, call it with # AttrDict consisting of a single rule/value pair. if self.validator: try: self._run_section_validator() except Config.ValidationError as exc: error_list.append(exc) except Exception as exc: # Log exception. log.log_exception() # Append error produced by validator callback to error list. error_list.append(exc) else: logging.debug('section \'%s\' failed to validate', self) # Process errors produced by any validation steps. if error_list: raise ConfigError(*error_list) self._value_dict.update(temp_value_dict) return
def request(self, method_name, api_request_object): ''' Submit a request to the web service and process success or failure. ''' # pylint: disable=E1101 request_encoded = self.encode(api_request_object) # Append method name to base path. # pylint: disable=E1101 path = '/'.join((self.url_parsed.path, method_name, '')) try: # pylint: disable=E1101 url_unparsed = urlunparse \ ((self.url_parsed.scheme, self.url_parsed.netloc, path, '', '', '')) LOGGER.debug('%s: HTTP request (POST) to %s', self.classname(), url_unparsed) # Make connection and issue HTTP POST request. # pylint: disable=E1101 http_conn = self.http_class(self.url_parsed.netloc) http_conn.request('POST', path, request_encoded, self.header_dict) except: # Construction of HTTP/HTTPS object failed, or request failed. ##### FIXME: Improve handling of transport faults, but let ##### caller handle. # log.log_exception() raise # Get HTTP response. http_response = http_conn.getresponse() LOGGER.debug('%s: HTTP response from %s (%s %s)', self.classname(), url_unparsed, http_response.status, http_response.reason) try: self._validate_response(http_response) # Read response data and decode into Python object. response_encoded = http_response.read() client_response = ClientResponse(self.decode(response_encoded)) # If response object has a fault key, this indicates the server # method generated a fault. If doraise is true, we re-raise the # exception for the caller to handle in a try/except block. # Otherwise, fault is handled manually by the client using the # client_response.fault attribute. # pylint: disable=E0702 if client_response.is_fault() and self.doraise: raise client_response.fault # Unpickling error may be raised in ClientResponse contstructor. except pickle.UnpicklingError: # Unable to unpickle fault object from server. log.log_exception('unable to unpickle server fault') raise # Error validating or decoding response. except Exception: log.log_exception('error validating or decoding server response') raise return client_response