def get_exactly_one_jsonpath_match(jsonpath, jsondata, custom_error_msg): jsonpath_expr = parser.parse(jsonpath) matches = jsonpath_expr.find(jsondata) if len(matches) != 1: raise exception.BadRequest( custom_error_msg.format(jsonpath, jsondata)) return matches[0].value
def invoke_service_rpc(self, service_id, method, kwargs=None, timeout=None, local=False, retry=None): """Invoke RPC method on a DSE Service. :param: service_id: The ID of the data service on which to invoke the call. :param: method: The method name to call. :param: kwargs: A dict of method arguments. :returns: The result of the method invocation. :raises: MessagingTimeout, RemoteError, MessageDeliveryFailure, NotFound """ target = self.service_rpc_target( service_id, server=(self.node_id if local else None)) LOG.trace("<%s> Preparing to invoking RPC '%s' on %s", self.node_id, method, target) client = messaging.RPCClient(self.transport, target, timeout=timeout, retry=retry) if not self.is_valid_service(service_id): try: # First ping the destination to fail fast if unresponsive LOG.trace( "<%s> Checking responsiveness before invoking RPC " "'%s' on %s", self.node_id, method, target) client.prepare(timeout=cfg.CONF.dse.ping_timeout).call( self.context, 'ping') except (messaging_exceptions.MessagingTimeout, messaging_exceptions.MessageDeliveryFailure): msg = "service '%s' could not be found" raise exception.RpcTargetNotFound(msg % service_id) if kwargs is None: kwargs = {} try: LOG.trace("<%s> Invoking RPC '%s' on %s", self.node_id, method, target) result = client.call(self.context, method, **kwargs) except dispatcher.NoSuchMethod: msg = "Method %s not supported for datasource %s" LOG.exception(msg, method, service_id) raise exception.BadRequest(msg % (method, service_id)) except (messaging_exceptions.MessagingTimeout, messaging_exceptions.MessageDeliveryFailure): msg = "Request to service '%s' timed out" raise exception.Unavailable(msg % service_id) LOG.trace("<%s> RPC call returned: %s", self.node_id, result) return result
def _webhook_update_table(self, table_name, key, data): key_string = json.dumps(key, sort_keys=True) PGSQL_MAX_INDEXABLE_SIZE = 2712 if len(key_string) > PGSQL_MAX_INDEXABLE_SIZE: raise exception.BadRequest( 'The supplied key ({}) exceeds the max indexable size ({}) in ' 'PostgreSQL.'.format(key_string, PGSQL_MAX_INDEXABLE_SIZE)) insert_statement = """INSERT INTO {}.{} VALUES(%s, %s);""" delete_tuple_statement = """ DELETE FROM {}.{} WHERE _key = %s;""" conn = None try: conn = psycopg2.connect(cfg.CONF.json_ingester.db_connection) conn.set_session(isolation_level=psycopg2.extensions. ISOLATION_LEVEL_READ_COMMITTED, readonly=False, autocommit=False) cur = conn.cursor() # delete the appropriate row from table cur.execute( sql.SQL(delete_tuple_statement).format( sql.Identifier(self.name), sql.Identifier(table_name)), (key_string, )) # insert new row into table cur.execute( sql.SQL(insert_statement).format(sql.Identifier(self.name), sql.Identifier(table_name)), (json.dumps(data), key_string)) conn.commit() cur.close() except (Exception, psycopg2.Error): LOG.exception("Error writing to DB") finally: if conn is not None: conn.close()
def add_item(self, item, params, id_=None, context=None): """Add item to model. :param: item: The item to add to the model :param: params: A dict-like object containing parameters from the request query string and body. :param: id\_: The ID of the item, or None if an ID should be generated :param: context: Key-values providing frame of reference of request :returns: Tuple of (ID, newly_created_item) :raises KeyError: ID already exists. :raises DataModelException: Addition cannot be performed. :raises BadRequest: library_policy parameter and request body both present """ # case 1: parameter gives library policy UUID if 'library_policy' in params: if item: raise exception.BadRequest( 'Policy creation request with `library_policy` parameter ' 'must not have non-empty body.') try: # Note(thread-safety): blocking call library_policy_object = self.invoke_rpc( base.LIBRARY_SERVICE_ID, 'get_policy', {'id_': params['library_policy']}) policy_metadata = self.invoke_rpc( base.ENGINE_SERVICE_ID, 'persistent_create_policy_with_rules', {'policy_rules_obj': library_policy_object}, timeout=self.dse_long_timeout) except exception.CongressException as e: raise webservice.DataModelException.create(e) return (policy_metadata['id'], policy_metadata) # case 2: item contains rules if 'rules' in item: try: library_service.validate_policy_item(item) # Note(thread-safety): blocking call policy_metadata = self.invoke_rpc( base.ENGINE_SERVICE_ID, 'persistent_create_policy_with_rules', {'policy_rules_obj': item}, timeout=self.dse_long_timeout) except exception.CongressException as e: raise webservice.DataModelException.create(e) return (policy_metadata['id'], policy_metadata) # case 3: item does not contain rules self._check_create_policy(id_, item) name = item['name'] try: # Note(thread-safety): blocking call policy_metadata = self.invoke_rpc( base.ENGINE_SERVICE_ID, 'persistent_create_policy', {'name': name, 'abbr': item.get('abbreviation'), 'kind': item.get('kind'), 'desc': item.get('description')}) except exception.CongressException as e: raise webservice.DataModelException.create(e) return (policy_metadata['id'], policy_metadata)