Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTP APIs : SHOW QUERY, SHOW TRANSACTIONS, SHOW TRANSACTION #2007

Merged
merged 3 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions docs/references/http_api_reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2635,7 +2635,150 @@ A `500` HTTP status code indicates an error condition. The response includes a J

---

## Show transactions

**GET** `/instance/transactions`

Shows running transactions on database.

### Request

- Method: GET
- URL: `/instance/transactions`
- Headers: `accept: application/json`

#### Request example

```shell
curl --request GET \
--url http://localhost:23820/instance/transactions \
--header 'accept: application/json'
```

### Response

<Tabs
defaultValue="s200"
values={[
{label: 'Status code 200', value: 's200'},
{label: 'Status code 500', value: 's500'},
]}>
<TabItem value="s200">

The response includes a JSON object like the following:

```shell
{
"error_code":0,
"transactions": [
{
"transaction_id":"27275",
"transaction_text":""
},
{
"transaction_id":"27274",
"transaction_text":""
}
]
}
```

- `"error_code"`: `integer`
`0`: The operation succeeds.

</TabItem>
<TabItem value="s500">

A `500` HTTP status code indicates an error condition. The response includes a JSON object like the following:

```shell
{
"error_code": 2005,
"error_message": "Not support in maintenance mode"
}
```

- `"error_code"`: `integer`
A non-zero value indicates a specific error condition.
- `"error_message"`: `string`
When `error_code` is non-zero, `"error_message"` provides additional details about the error.

</TabItem>
</Tabs>

---

## Show transaction

**GET** `/instance/transactions/{trasaction_id}`

Shows running transactions on database by transaction_id.

### Request

- Method: GET
- URL: `/instance/transactions`
- Headers: `accept: application/json`

#### Request example

```shell
curl --request GET \
--url http://localhost:23820/instance/transactions/{transaction_id} \
--header 'accept: application/json'
```

#### Request parameters

- `transaction_id`: (*Path parameter*)
The id of the running transaction.

### Response

<Tabs
defaultValue="s200"
values={[
{label: 'Status code 200', value: 's200'},
{label: 'Status code 500', value: 's500'},
]}>
<TabItem value="s200">

The response includes a JSON object like the following:

```shell
{
"error_code":0,
"transaction": {
"transaction_id":"27275",
"transaction_text":""
}
}
```

- `"error_code"`: `integer`
`0`: The operation succeeds.

</TabItem>
<TabItem value="s500">

A `500` HTTP status code indicates an error condition. The response includes a JSON object like the following:

```shell
{
"error_code": 2005,
"error_message": "Not support in maintenance mode"
}
```

- `"error_code"`: `integer`
A non-zero value indicates a specific error condition.
- `"error_message"`: `string`
When `error_code` is non-zero, `"error_message"` provides additional details about the error.

</TabItem>
</Tabs>

---

## Admin set node role

Expand Down
113 changes: 113 additions & 0 deletions src/network/http_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3590,6 +3590,116 @@ class ShowFullCheckpointHandler final : public HttpRequestHandler {
}
};


class ShowQueryHandler final : public HttpRequestHandler {
public:
SharedPtr<OutgoingResponse> handle(const SharedPtr<IncomingRequest> &request) final {
auto infinity = Infinity::RemoteConnect();
DeferFn defer_fn([&]() { infinity->RemoteDisconnect(); });

nlohmann::json json_response;
nlohmann::json json_table;
HTTPStatus http_status;
String query_id = request->getPathVariable("query_id");
QueryResult result = infinity->Query(fmt::format("show query {}", query_id));

if (result.IsOk()) {
DataBlock *data_block = result.result_table_->GetDataBlockById(0).get();
auto column_cnt = result.result_table_->ColumnCount();
for (SizeT col = 0; col < column_cnt; ++col) {
const String &column_name = result.result_table_->GetColumnNameById(col);
Value value = data_block->GetValue(col, 0);
const String &column_value = value.ToString();
json_table[column_name] = column_value;
}
json_response["query"] = json_table;
json_response["error_code"] = 0;
http_status = HTTPStatus::CODE_200;
} else {
json_response["error_code"] = result.ErrorCode();
json_response["error_message"] = result.ErrorMsg();
http_status = HTTPStatus::CODE_500;
}

return ResponseFactory::createResponse(http_status, json_response.dump());
}
};

class ShowTransactionsHandler final : public HttpRequestHandler {
public:
SharedPtr<OutgoingResponse> handle(const SharedPtr<IncomingRequest> &request) final {
auto infinity = Infinity::RemoteConnect();
DeferFn defer_fn([&]() { infinity->RemoteDisconnect(); });

nlohmann::json json_response;
HTTPStatus http_status;
QueryResult result = infinity->Query("show transactions");

if (result.IsOk()) {
SizeT block_rows = result.result_table_->DataBlockCount();
for (SizeT block_id = 0; block_id < block_rows; ++block_id) {
DataBlock *data_block = result.result_table_->GetDataBlockById(block_id).get();
auto row_count = data_block->row_count();
auto column_cnt = result.result_table_->ColumnCount();
for (int row = 0; row < row_count; ++row) {
nlohmann::json json_table;
for (SizeT col = 0; col < column_cnt; ++col) {
const String &column_name = result.result_table_->GetColumnNameById(col);
Value value = data_block->GetValue(col, row);
const String &column_value = value.ToString();
json_table[column_name] = column_value;
}
json_response["transactions"].push_back(json_table);
}
}
json_response["error_code"] = 0;
http_status = HTTPStatus::CODE_200;
} else {
json_response["error_code"] = result.ErrorCode();
json_response["error_message"] = result.ErrorMsg();
http_status = HTTPStatus::CODE_500;
}

return ResponseFactory::createResponse(http_status, json_response.dump());
}
};

class ShowTransactionHandler final : public HttpRequestHandler {
public:
SharedPtr<OutgoingResponse> handle(const SharedPtr<IncomingRequest> &request) final {
auto infinity = Infinity::RemoteConnect();
DeferFn defer_fn([&]() { infinity->RemoteDisconnect(); });

nlohmann::json json_response;
nlohmann::json json_table;
HTTPStatus http_status;
String transaction_id = request->getPathVariable("transaction_id");
QueryResult result = infinity->Query(fmt::format("show transaction {}", transaction_id));

if (result.IsOk()) {
DataBlock *data_block = result.result_table_->GetDataBlockById(0).get();
auto column_cnt = result.result_table_->ColumnCount();
for (SizeT col = 0; col < column_cnt; ++col) {
const String &column_name = result.result_table_->GetColumnNameById(col);
Value value = data_block->GetValue(col, 0);
const String &column_value = value.ToString();
json_table[column_name] = column_value;
}
json_response["error_code"] = 0;
json_response["transaction"]= json_table;
http_status = HTTPStatus::CODE_200;
} else {
json_response["error_code"] = result.ErrorCode();
json_response["error_message"] = result.ErrorMsg();
http_status = HTTPStatus::CODE_500;
}

return ResponseFactory::createResponse(http_status, json_response.dump());
}
};



class AdminShowCurrentNodeHandler final : public HttpRequestHandler {
public:
SharedPtr<OutgoingResponse> handle(const SharedPtr<IncomingRequest> &request) final {
Expand Down Expand Up @@ -3926,6 +4036,9 @@ void HTTPServer::Start(const String &ip_address, u16 port) {
router->route("GET", "/instance/logs", MakeShared<ShowLogsHandler>());
router->route("GET", "/instance/delta_checkpoint", MakeShared<ShowDeltaCheckpointHandler>());
router->route("GET", "/instance/global_checkpoint", MakeShared<ShowFullCheckpointHandler>());
router->route("GET", "/instance/queries/{query_id}", MakeShared<ShowQueryHandler>());
router->route("GET", "/instance/transactions", MakeShared<ShowTransactionsHandler>());
router->route("GET", "/instance/transactions/{transaction_id}", MakeShared<ShowTransactionHandler>());

// variable
router->route("GET", "/variables/global", MakeShared<ShowGlobalVariablesHandler>());
Expand Down
Loading