Add metadata and squash migrations

This commit is contained in:
Gregory Schier
2024-02-18 08:35:31 -08:00
parent ed55eb2238
commit 555389b667
11 changed files with 108 additions and 44 deletions

View File

@@ -1,6 +1,6 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id, model, workspace_id, folder_id, created_at, updated_at, name, sort_priority,\n url, service, method, message, authentication_type,\n authentication AS \"authentication!: Json<HashMap<String, JsonValue>>\",\n proto_files AS \"proto_files!: sqlx::types::Json<Vec<String>>\"\n FROM grpc_requests\n WHERE workspace_id = ?\n ",
"query": "\n SELECT\n id, model, workspace_id, folder_id, created_at, updated_at, name, sort_priority,\n url, service, method, message, authentication_type,\n authentication AS \"authentication!: Json<HashMap<String, JsonValue>>\",\n proto_files AS \"proto_files!: sqlx::types::Json<Vec<String>>\",\n metadata AS \"metadata!: sqlx::types::Json<Vec<GrpcMetadataEntry>>\"\n FROM grpc_requests\n WHERE workspace_id = ?\n ",
"describe": {
"columns": [
{
@@ -77,6 +77,11 @@
"name": "proto_files!: sqlx::types::Json<Vec<String>>",
"ordinal": 14,
"type_info": "Text"
},
{
"name": "metadata!: sqlx::types::Json<Vec<GrpcMetadataEntry>>",
"ordinal": 15,
"type_info": "Text"
}
],
"parameters": {
@@ -97,8 +102,9 @@
false,
true,
false,
false,
false
]
},
"hash": "545d21ff21bd02468be86746325dc9f1b50f3fe53d7735194d91927b5d14a436"
"hash": "24a721700844cb0ea9c2585c4df796ec10188b559063a9093e432ae993154f31"
}

View File

@@ -0,0 +1,12 @@
{
"db_name": "SQLite",
"query": "\n INSERT INTO grpc_requests (\n id, name, workspace_id, folder_id, sort_priority, url, service, method, message,\n proto_files, authentication_type, authentication, metadata\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n name = excluded.name,\n folder_id = excluded.folder_id,\n sort_priority = excluded.sort_priority,\n url = excluded.url,\n service = excluded.service,\n method = excluded.method,\n message = excluded.message,\n proto_files = excluded.proto_files,\n authentication_type = excluded.authentication_type,\n authentication = excluded.authentication,\n metadata = excluded.metadata\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 13
},
"nullable": []
},
"hash": "38e8fd3b0959623322bf49cf6682a4ddeac667cf6e71b97bc7e122848ad1565f"
}

View File

@@ -1,6 +1,6 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id, model, workspace_id, folder_id, created_at, updated_at, name, sort_priority,\n url, service, method, message, authentication_type,\n authentication AS \"authentication!: Json<HashMap<String, JsonValue>>\",\n proto_files AS \"proto_files!: sqlx::types::Json<Vec<String>>\"\n FROM grpc_requests\n WHERE id = ?\n ",
"query": "\n SELECT\n id, model, workspace_id, folder_id, created_at, updated_at, name, sort_priority,\n url, service, method, message, authentication_type,\n authentication AS \"authentication!: Json<HashMap<String, JsonValue>>\",\n proto_files AS \"proto_files!: sqlx::types::Json<Vec<String>>\",\n metadata AS \"metadata!: sqlx::types::Json<Vec<GrpcMetadataEntry>>\"\n FROM grpc_requests\n WHERE id = ?\n ",
"describe": {
"columns": [
{
@@ -77,6 +77,11 @@
"name": "proto_files!: sqlx::types::Json<Vec<String>>",
"ordinal": 14,
"type_info": "Text"
},
{
"name": "metadata!: sqlx::types::Json<Vec<GrpcMetadataEntry>>",
"ordinal": 15,
"type_info": "Text"
}
],
"parameters": {
@@ -97,8 +102,9 @@
false,
true,
false,
false,
false
]
},
"hash": "0d9e685f878fc2a0e1803c6aaae3828deebd684fc9f78e9f8595a550f90749fe"
"hash": "697afa2c3072b7b01676be53d5857066724fc23c94cd279d074253d5581b6f2c"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n INSERT INTO grpc_requests (\n id, name, workspace_id, folder_id, sort_priority, url, service, method, message,\n proto_files, authentication_type, authentication\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n name = excluded.name,\n folder_id = excluded.folder_id,\n sort_priority = excluded.sort_priority,\n url = excluded.url,\n service = excluded.service,\n method = excluded.method,\n message = excluded.message,\n proto_files = excluded.proto_files,\n authentication_type = excluded.authentication_type,\n authentication = excluded.authentication\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 12
},
"nullable": []
},
"hash": "c554305252cb21e34aa1e3c1f204c6060c3d2a209689a879824dea4d26e5497e"
}

View File

@@ -1,22 +1,26 @@
CREATE TABLE grpc_requests
(
id TEXT NOT NULL
id TEXT NOT NULL
PRIMARY KEY,
model TEXT DEFAULT 'grpc_request' NOT NULL,
workspace_id TEXT NOT NULL
model TEXT DEFAULT 'grpc_request' NOT NULL,
workspace_id TEXT NOT NULL
REFERENCES workspaces
ON DELETE CASCADE,
folder_id TEXT NULL
folder_id TEXT NULL
REFERENCES folders
ON DELETE CASCADE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
name TEXT NOT NULL,
sort_priority REAL NOT NULL,
url TEXT NOT NULL,
service TEXT NULL,
method TEXT NULL,
message TEXT NOT NULL
created_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
name TEXT NOT NULL,
sort_priority REAL NOT NULL,
url TEXT NOT NULL,
service TEXT NULL,
method TEXT NULL,
message TEXT NOT NULL,
proto_files TEXT DEFAULT '[]' NOT NULL,
authentication TEXT DEFAULT '{}' NOT NULL,
authentication_type TEXT NULL,
metadata TEXT DEFAULT '[]' NOT NULL
);
CREATE TABLE grpc_connections

View File

@@ -1 +0,0 @@
ALTER TABLE grpc_requests ADD COLUMN proto_files TEXT DEFAULT '[]' NOT NULL;

View File

@@ -1,2 +0,0 @@
ALTER TABLE grpc_requests ADD COLUMN authentication TEXT NOT NULL DEFAULT '{}';
ALTER TABLE grpc_requests ADD COLUMN authentication_type TEXT;

View File

@@ -16,7 +16,7 @@ use std::process::exit;
use std::str::FromStr;
use ::http::uri::InvalidUri;
use ::http::Uri;
use ::http::{HeaderValue, Uri};
use base64::Engine;
use fern::colors::ColoredLevelConfig;
use log::{debug, error, info, warn};
@@ -275,6 +275,23 @@ async fn cmd_grpc_go(
};
let event_handler = w.listen_global(format!("grpc_client_msg_{}", conn.id).as_str(), cb);
let mut metadata = HashMap::new();
// Add rest of metadata
for h in req.clone().metadata.0 {
if h.name.is_empty() && h.value.is_empty() {
continue;
}
if !h.enabled {
continue;
}
let name = render::render(&h.name, &workspace, environment.as_ref());
let value = render::render(&h.value, &workspace, environment.as_ref());
metadata.insert(name, value);
}
if let Some(b) = &req.authentication_type {
let req = req.clone();
let environment_ref = environment.as_ref();
@@ -304,6 +321,7 @@ async fn cmd_grpc_go(
metadata.insert("Authorization".to_string(), format!("Bearer {token}"));
}
}
println!("METADATA: {:?}", metadata);
let grpc_listen = {

View File

@@ -189,6 +189,15 @@ impl HttpResponse {
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(default, rename_all = "camelCase")]
pub struct GrpcMetadataEntry {
#[serde(default = "default_true")]
pub enabled: bool,
pub name: String,
pub value: String,
}
#[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize, Default)]
#[serde(default, rename_all = "camelCase")]
pub struct GrpcRequest {
@@ -207,6 +216,7 @@ pub struct GrpcRequest {
pub proto_files: Json<Vec<String>>,
pub authentication_type: Option<String>,
pub authentication: Json<HashMap<String, JsonValue>>,
pub metadata: Json<Vec<GrpcMetadataEntry>>,
}
#[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize, Default)]
@@ -504,9 +514,9 @@ pub async fn upsert_grpc_request(
r#"
INSERT INTO grpc_requests (
id, name, workspace_id, folder_id, sort_priority, url, service, method, message,
proto_files, authentication_type, authentication
proto_files, authentication_type, authentication, metadata
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT (id) DO UPDATE SET
updated_at = CURRENT_TIMESTAMP,
name = excluded.name,
@@ -518,7 +528,8 @@ pub async fn upsert_grpc_request(
message = excluded.message,
proto_files = excluded.proto_files,
authentication_type = excluded.authentication_type,
authentication = excluded.authentication
authentication = excluded.authentication,
metadata = excluded.metadata
"#,
id,
trimmed_name,
@@ -532,6 +543,7 @@ pub async fn upsert_grpc_request(
request.proto_files,
request.authentication_type,
request.authentication,
request.metadata,
)
.execute(&db)
.await?;
@@ -554,7 +566,8 @@ pub async fn get_grpc_request(
id, model, workspace_id, folder_id, created_at, updated_at, name, sort_priority,
url, service, method, message, authentication_type,
authentication AS "authentication!: Json<HashMap<String, JsonValue>>",
proto_files AS "proto_files!: sqlx::types::Json<Vec<String>>"
proto_files AS "proto_files!: sqlx::types::Json<Vec<String>>",
metadata AS "metadata!: sqlx::types::Json<Vec<GrpcMetadataEntry>>"
FROM grpc_requests
WHERE id = ?
"#,
@@ -576,7 +589,8 @@ pub async fn list_grpc_requests(
id, model, workspace_id, folder_id, created_at, updated_at, name, sort_priority,
url, service, method, message, authentication_type,
authentication AS "authentication!: Json<HashMap<String, JsonValue>>",
proto_files AS "proto_files!: sqlx::types::Json<Vec<String>>"
proto_files AS "proto_files!: sqlx::types::Json<Vec<String>>",
metadata AS "metadata!: sqlx::types::Json<Vec<GrpcMetadataEntry>>"
FROM grpc_requests
WHERE workspace_id = ?
"#,
@@ -1032,8 +1046,6 @@ pub async fn upsert_http_request(
"" => generate_id(Some("rq")),
_ => r.id.to_string(),
};
let headers_json = Json(r.headers);
let auth_json = Json(r.authentication);
let trimmed_name = r.name.trim();
let db = get_db(mgr).await;
@@ -1068,9 +1080,9 @@ pub async fn upsert_http_request(
r.method,
r.body,
r.body_type,
auth_json,
r.authentication,
r.authentication_type,
headers_json,
r.headers,
r.sort_priority,
)
.execute(&db)
@@ -1291,7 +1303,6 @@ pub async fn update_response(
mgr: &impl Manager<Wry>,
response: &HttpResponse,
) -> Result<HttpResponse, sqlx::Error> {
let headers_json = Json(&response.headers);
let db = get_db(mgr).await;
sqlx::query!(
r#"
@@ -1308,7 +1319,7 @@ pub async fn update_response(
response.content_length,
response.body_path,
response.error,
headers_json,
response.headers,
response.version,
response.remote_addr,
response.id,

View File

@@ -7,13 +7,14 @@ import type { ReflectResponseService } from '../hooks/useGrpc';
import { useGrpcConnections } from '../hooks/useGrpcConnections';
import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey';
import { useUpdateGrpcRequest } from '../hooks/useUpdateGrpcRequest';
import type { GrpcRequest } from '../lib/models';
import type { GrpcMetadataEntry, GrpcRequest } from '../lib/models';
import { AUTH_TYPE_BASIC, AUTH_TYPE_BEARER, AUTH_TYPE_NONE } from '../lib/models';
import { BasicAuth } from './BasicAuth';
import { BearerAuth } from './BearerAuth';
import { Button } from './core/Button';
import { Icon } from './core/Icon';
import { IconButton } from './core/IconButton';
import { PairEditor } from './core/PairEditor';
import { RadioDropdown } from './core/RadioDropdown';
import { HStack, VStack } from './core/Stacks';
import type { TabItem } from './core/Tabs/Tabs';
@@ -155,6 +156,11 @@ export function GrpcConnectionSetupPane({
[activeRequest.authentication, activeRequest.authenticationType, updateRequest],
);
const handleMetadataChange = useCallback(
(metadata: GrpcMetadataEntry[]) => updateRequest.mutate({ metadata }),
[updateRequest],
);
return (
<VStack style={style}>
<div
@@ -281,6 +287,15 @@ export function GrpcConnectionSetupPane({
<EmptyStateText>No Authentication {activeRequest.authenticationType}</EmptyStateText>
)}
</TabContent>
<TabContent value="metadata">
<PairEditor
valueAutocompleteVariables
nameAutocompleteVariables
pairs={activeRequest.metadata}
onChange={handleMetadataChange}
forceUpdateKey={forceUpdateKey}
/>
</TabContent>
</Tabs>
</VStack>
);

View File

@@ -104,6 +104,12 @@ export interface HttpUrlParameter {
enabled?: boolean;
}
export interface GrpcMetadataEntry {
name: string;
value: string;
enabled?: boolean;
}
export interface GrpcRequest extends BaseModel {
readonly workspaceId: string;
readonly model: 'grpc_request';
@@ -117,6 +123,7 @@ export interface GrpcRequest extends BaseModel {
protoFiles: string[];
authentication: Record<string, string | number | boolean | null | undefined>;
authenticationType: string | null;
metadata: GrpcMetadataEntry[];
}
export interface GrpcMessage extends BaseModel {