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

[DE-6473] Add feature for trino-client helper rest api #95

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
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
29 changes: 28 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
SCRIPT_DIR := "./scripts"

BUILD_OUT_DIR := "bin/"
API_OUT := "bin/api"
API_MAIN_FILE := "cmd/trino_rest/main.go"

GOVERSION=$(shell go version)
UNAME_OS=$(shell go env GOOS)
UNAME_ARCH=$(shell go env GOARCH)

GO = go

PWD = $(shell pwd)

Expand Down Expand Up @@ -54,3 +61,23 @@ test-integration:
.PHONY: test-unit
test-unit:
go test

.PHONY: go-build-trino-rest-api ## Build trino rest api
go-build-trino-rest-api:
@CGO_ENABLED=0 GOOS=$(UNAME_OS) GOARCH=$(UNAME_ARCH) $(GO) build -v -o $(API_OUT) $(API_MAIN_FILE)

.PHONY: local_trino_rest_up
local_trino_rest_up:
$(SCRIPT_DIR)/trino_rest_docker.sh up

.PHONY: local_trino_rest_down
local_trino_rest_down:
$(SCRIPT_DIR)/trino_rest_docker.sh down

.PHONY: local_trino_rest_logs
local_trino_rest_logs:
$(SCRIPT_DIR)/trino_rest_docker.sh logs

.PHONY: local_trino_rest_clean
local_trino_rest_clean:
$(SCRIPT_DIR)/trino_rest_docker.sh clean
212 changes: 210 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ Rest of this section covers non-container based build environment.

1. Install [Golang](https://go.dev)(It is recommended that the version matches exactly as defined in go.mod)

2. [Protobuf compiler](https://github.com/protocolbuffers/protobuf/releases)
2. [Protobuf compiler](https://github.com/protocolbuffers/protobuf/releases)

3. Install dependencies

Expand Down Expand Up @@ -178,7 +178,7 @@ go run ./cmd/gateway | jq
1. Extract https://github.com/swagger-api/swagger-ui/tree/<version>/dist -> third_party/swaggerui
2. Modify swagger-initializer.js to point to generated openApi spec

## TODO
## TODO

_rough notes_

Expand Down Expand Up @@ -208,3 +208,211 @@ Explore victoriaMetrics go client <https://github.com/VictoriaMetrics/metrics>


Handle routing errors properly instead of returning HTTP500 in all cases, eg: sql transaction request must return HTTP400 instead of HTTP500


# RZP-Trino REST Client

## Overview

This module exposes an API to interact with Trino. It retrieves data using the Trino Go client, processes it, and returns it in JSON format to the client.

### Features:
- **Trino Integration:** Connects to a Trino instance and executes SQL queries.
- **Data Processing:** Applies business logic to the data before sending it to the client.
- **JSON API:** Communicates with clients using JSON format.
- **Request/Response Limitation:** Throws an error if response data exceeds 5,000 records.
- **Configurable:** Uses TOML files for different environments (development, staging, production).

## Base URL

The base URL for the API is: `http://rzp-trino-rest:8000`

### `POST /v1/query`

**Description:**
Executes a SQL query against Trino.

**Request:**

```json
{
"sql": "string" // SQL query to be executed on trino
}
```

**Reponse:**

```json
{
"status": "string", // "Success/ Error"
"columns": [
{
"name": "string", // Column name
"type": "string" // Column type
}
],
"data": [
{
"col1": "val1"
},
{
"col1": "val2"
}
],
"error": {
"message": "string", // Error message (if any)
"errorCode": "integer",// Error code (if any)
}
}
```

**Reponse(Success example):**

```json
{
"status": "Success",
"columns": [
{
"name": "nationkey",
"type": "BIGINT"
},
{
"name": "name",
"type": "VARCHAR"
},
{
"name": "regionkey",
"type": "BIGINT"
},
{
"name": "comment",
"type": "VARCHAR"
}
],
"data": [
{
"comment": " haggle. carefully final deposits detect slyly agai",
"name": "ALGERIA",
"nationkey": 0,
"regionkey": 0
},
{
"comment": "al foxes promise slyly according to the regular accounts. bold requests alon",
"name": "ARGENTINA",
"nationkey": 1,
"regionkey": 1
},
{
"comment": "y alongside of the pending deposits. carefully special packages are about the ironic forges. slyly special ",
"name": "BRAZIL",
"nationkey": 2,
"regionkey": 1
},
{
"comment": "eas hang ironic, silent packages. slyly regular packages are furiously over the tithes. fluffily bold",
"name": "CANADA",
"nationkey": 3,
"regionkey": 1
},
{
"comment": "y above the carefully unusual theodolites. final dugouts are quickly across the furiously regular d",
"name": "EGYPT",
"nationkey": 4,
"regionkey": 4
},
{
"comment": "ven packages wake quickly. regu",
"name": "ETHIOPIA",
"nationkey": 5,
"regionkey": 0
},
{
"comment": "refully final requests. regular, ironi",
"name": "FRANCE",
"nationkey": 6,
"regionkey": 3
},
{
"comment": "l platelets. regular accounts x-ray: unusual, regular acco",
"name": "GERMANY",
"nationkey": 7,
"regionkey": 3
},
{
"comment": "ss excuses cajole slyly across the packages. deposits print aroun",
"name": "INDIA",
"nationkey": 8,
"regionkey": 2
},
{
"comment": " slyly express asymptotes. regular deposits haggle slyly. carefully ironic hockey players sleep blithely. carefull",
"name": "INDONESIA",
"nationkey": 9,
"regionkey": 2
}
]
}
```

**Reponse(error example):**

```json
{
"status": "Error",
"error": {
"message": "Unable to query trino: trino: query failed (200 OK): \"USER_ERROR: line 1:31: mismatched input '10'. Expecting: ',', '.', 'AS', 'CROSS', 'EXCEPT', 'FETCH', 'FOR', 'FULL', 'GROUP', 'HAVING', 'INNER', 'INTERSECT', 'JOIN', 'LEFT', 'LIMIT', 'MATCH_RECOGNIZE', 'NATURAL', 'OFFSET', 'ORDER', 'RIGHT', 'TABLESAMPLE', 'UNION', 'WHERE', 'WINDOW', <EOF>, <identifier>\"",
"errorCode": 500,
}
}
```
## Project Structure

```plaintext
trino-gateway/
├── build/
│ ├── docker/
│ ├── dev/
│ │ ├── trino_rest/
│ │ │ ├── Dockerfile.trino_rest
│ │ │ ├── trino_rest_entrypoint.sh
│ │ │ ├── docker_compose.yml
│ ├── prod/
│ │ ├── Dockerfile.razorpay_trino_rest
│ │ ├── trino_rest_entrypoint.sh
├── cmd/
│ ├── trino_rest/
│ │ ├── main.go
├── config/
│ ├── default.toml
│ ├── dev_docker.toml
│ ├── stage.toml
│ ├── prod.toml
├── internal/
│ ├── trino_rest/
│ │ ├── handler/
│ │ │ ├── handler.go
│ │ │ ├── handler_test.go
│ │ ├── process/
│ │ │ ├── processor.go
│ │ ├── routes/
│ │ │ ├── routes.go
│ │ ├── model/
│ │ │ ├── model.go
│ │ ├── utils/
│ │ │ ├── response.go
│ │ ├── services/trino/
│ │ │ ├── client.go
│ │ ├── trino_rest.go
├── go.mod
├── go.sum
├── Makefile
├── README.md
3 changes: 0 additions & 3 deletions build/docker/dev/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,3 @@ services:
MYSQL_DATABASE: trino-gateway
networks:
- default
# networks:
# trino:
# external: true
41 changes: 41 additions & 0 deletions build/docker/dev/trino_rest/Dockerfile.trino_rest
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Use a lightweight Go image
FROM golang:1.21.5-alpine AS builder

ENV CGO_ENABLED 0

RUN mkdir /src

WORKDIR /src

RUN apk add --update --no-cache --repository https://dl-4.alpinelinux.org/alpine/latest-stable/community/ make

ADD Makefile /src

COPY go.mod .
COPY go.sum .

RUN go mod download

COPY . /src/

RUN make go-build-api

# stage 2

FROM alpine:latest

COPY --from=builder /src/bin/api /app/
COPY --from=builder /src/config/ /app/config/
COPY build/docker/dev/trino_rest/trino-rest_entrypoint.sh /app/

ENV WORKDIR=/app
ENV DUMB_INIT_SETSID=0
WORKDIR /app

RUN apk add --update --no-cache dumb-init su-exec ca-certificates curl

EXPOSE 8000

RUN chmod +x trino-rest_entrypoint.sh

ENTRYPOINT ["./api"]
26 changes: 26 additions & 0 deletions build/docker/dev/trino_rest/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
services:
trino:
image: harbor.razorpay.com/razorpay/trino:356
container_name: trino_dev
ports:
- "8080:8080"
environment:
JAVA_TOOL_OPTIONS: "-Xmx4g"
networks:
- trino-rest-network
api:
build:
context: ../../
dockerfile: build/docker/dev/trino_rest/Dockerfile.trino_rest
ports:
- "8000:8000"
container_name: trino_rest_server
networks:
- trino-rest-network
environment:
- APP_ENV=dev_docker
depends_on:
- trino
networks:
trino-rest-network:
driver: bridge
28 changes: 28 additions & 0 deletions build/docker/dev/trino_rest/trino-rest_entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/dumb-init /bin/sh
set -euo pipefail

start_application()
{
su-exec appuser $WORKDIR/"$appName" &

# Get pid for app
APP_PID=$!

# wait returns immediately after signal is caught,
# hence double wait is required in shutdown_application
# refer : http://veithen.io/2014/11/16/sigterm-propagation.html
wait "$APP_PID"
}

shutdown_application()
{
kill -s SIGTERM "$APP_PID"
trap - SIGTERM SIGINT
wait "$APP_PID"
EXIT_STATUS=$?
return ${EXIT_STATUS}
}

appName="$1"
trap shutdown_application SIGTERM SIGINT
start_application
Loading