def _search_transaction( query: Optional[dict] = None, q: Optional[str] = None, get_all: bool = False, sort: Optional[str] = None, offset: Optional[int] = None, limit: Optional[int] = None, should_parse: bool = True, ) -> "ESSearch": """invoke queries on elastic search indexes built with #set. Return the full storage stored object. Args: query: {dict=None} Elastic search query. The search definition using the ES Query DSL. q: {string=None} Query in the Lucene query string syntax Returns: {"results": [], "total": total} storage objects matching search query """ hits_pages = elasticsearch.get_index_only(folder=transaction_dao.FOLDER, query=query, q=q, get_all=get_all, sort=sort, offset=offset, limit=limit) _log.info(f"pages: {hits_pages}") storage_objects = [] for hit in hits_pages["hits"]: status = hit["_source"].get("status") if status == "pending": _log.info("[SEARCH TRANSACTION] FOUND PENDING TRANSACTION") stubbed_response = { "txn_id": hit["_source"]["txn_id"], "status": "pending", "message": "the transaction is waiting to be included into a block", } storage_objects.append( stubbed_response if should_parse else json. dumps(stubbed_response, separators=(",", ":"))) else: storage_id = hit["_source"][ transaction_dao.S3_OBJECT_ID] # get the id storage_inner_id = hit["_source"][ "txn_id"] # get the transaction id to look for within the block storage_object = storage.select_transaction( storage_id, storage_inner_id ) # pull the object from storage, contained in a group file storage_objects.append(storage_object) # add to the result set if should_parse: storage_object["payload"] = json.loads( storage_object["payload"]) return {"results": storage_objects, "total": hits_pages["total"]}
def query_transactions_v1(params: Dict[str, Any], parse: bool = True) -> "RSearch": """invoke queries on redisearch indexes Args: params: Dictionary of redisearch query options parse: If true, parse the transaction payload before returning Returns: {"results": [], "total": total} storage objects matching search query """ if not params.get("transaction_type"): raise exceptions.ValidationException( "transaction_type must be supplied for transaction queries") try: query_result = redisearch.search( index=params["transaction_type"], query_str=params["q"], only_id=params.get("id_only"), verbatim=params.get("verbatim"), offset=params.get("offset"), limit=params.get("limit"), sort_by=params.get("sort_by"), sort_asc=params.get("sort_asc"), ) except redis.exceptions.ResponseError as e: error_str = str(e) # Detect if this is a syntax error; if so, throw it back as a 400 with the message if error_str.startswith("Syntax error"): raise exceptions.BadRequest(error_str) # If unknown index, user provided a bad transaction type elif error_str == "Unknown Index name": raise exceptions.BadRequest("Invalid transaction type") else: raise result: "RSearch" = {"total": query_result.total, "results": []} if params.get("id_only"): result["results"] = [x.id for x in query_result.docs] else: transactions = [] for doc in query_result.docs: block_id = doc.block_id transaction_id = doc.id retrieved_txn = storage.select_transaction(block_id, transaction_id) if parse: retrieved_txn["payload"] = json.loads(retrieved_txn["payload"]) transactions.append(retrieved_txn) result["results"] = transactions return result
def get_transaction_v1(transaction_id: str, parse: bool = True) -> Dict[str, Any]: """ get_transaction_by_id Searches for a transaction by a specific transaction ID """ doc = redisearch.get_document(redisearch.Indexes.transaction.value, f"txn-{transaction_id}") try: block_id = doc.block_id except AttributeError: raise exceptions.NotFound(f"Transaction {transaction_id} could not be found.") if block_id == "0": # Check for stubbed result return _get_transaction_stub(transaction_id) else: txn = storage.select_transaction(block_id, transaction_id) if parse: txn["payload"] = json.loads(txn["payload"]) return txn
def get_transaction_v1(transaction_id: str, parse: bool = True) -> Dict[str, Any]: """ get_transaction_by_id Searches for a transaction by a specific transaction ID """ if dc_redis.sismember_sync(queue.TEMPORARY_TX_KEY, transaction_id): return _get_transaction_stub(transaction_id) doc = redisearch.get_document(redisearch.Indexes.transaction.value, f"txn-{transaction_id}") try: block_id = doc.block_id except AttributeError: raise exceptions.NotFound( f"Transaction {transaction_id} could not be found.") txn = storage.select_transaction(block_id, transaction_id) if parse: txn["payload"] = json.loads(txn["payload"]) return txn
def test_select_transaction_calls_cache_put_with_params(self): storage.storage.select_transaction = MagicMock(return_value={}) storage.select_transaction("block", "txn") storage.redis.cache_put("block/txn", "{}", None)
def test_select_transaction_returns_correct_value_from_storage(self): storage.storage.select_transaction = MagicMock(return_value={}) self.assertEqual(storage.select_transaction("block", "txn"), {})
def test_select_transaction_returns_correct_value_from_cache(self): storage.storage.select_transaction = MagicMock(return_value={}) storage.redis.cache_get = MagicMock(return_value="{}") self.assertEqual(storage.select_transaction("block", "txn"), {})
def test_select_transaction_calls_cache_get_with_params(self): storage.storage.select_transaction = MagicMock(return_value={}) storage.redis.cache_get = MagicMock(return_value="{}") storage.select_transaction("block", "txn") storage.redis.cache_get.assert_called_once_with("block/txn")
def test_select_transaction_calls_storage_select_transaction_with_params( self): storage.storage.select_transaction = MagicMock(return_value={}) storage.select_transaction("block", "txn") storage.storage.select_transaction.assert_called_once_with( "test", "block", "txn")