frontend/instance/
log_handler.rs1use std::sync::Arc;
16
17use api::v1::RowInsertRequests;
18use async_trait::async_trait;
19use auth::{PermissionChecker, PermissionCheckerRef, PermissionReq};
20use client::Output;
21use common_error::ext::BoxedError;
22use datatypes::timestamp::TimestampNanosecond;
23use pipeline::pipeline_operator::PipelineOperator;
24use pipeline::{Pipeline, PipelineInfo, PipelineVersion};
25use servers::error::{
26 AuthSnafu, Error as ServerError, ExecuteGrpcRequestSnafu, PipelineSnafu, Result as ServerResult,
27};
28use servers::interceptor::{LogIngestInterceptor, LogIngestInterceptorRef};
29use servers::query_handler::PipelineHandler;
30use session::context::{QueryContext, QueryContextRef};
31use snafu::ResultExt;
32use table::Table;
33
34use crate::instance::Instance;
35
36impl Instance {
37 async fn prepare_log_insert(
38 &self,
39 log: RowInsertRequests,
40 ctx: QueryContextRef,
41 ) -> ServerResult<RowInsertRequests> {
42 self.plugins
43 .get::<PermissionCheckerRef>()
44 .as_ref()
45 .check_permission(ctx.current_user(), PermissionReq::LogWrite)
46 .context(AuthSnafu)?;
47
48 let log = self
49 .plugins
50 .get::<LogIngestInterceptorRef<ServerError>>()
51 .as_ref()
52 .pre_ingest(log, ctx.clone())?;
53
54 self.check_row_insert_permission(&log, &ctx, PermissionReq::LogWrite)
55 .context(AuthSnafu)?;
56
57 Ok(log)
58 }
59}
60
61#[async_trait]
62impl PipelineHandler for Instance {
63 async fn insert(&self, log: RowInsertRequests, ctx: QueryContextRef) -> ServerResult<Output> {
64 let log = self.prepare_log_insert(log, ctx.clone()).await?;
65 self.handle_log_inserts(log, Arc::new(ctx.fork())).await
66 }
67
68 async fn insert_all(
69 &self,
70 inputs: Vec<(QueryContextRef, RowInsertRequests)>,
71 ) -> ServerResult<Vec<ServerResult<Output>>> {
72 let mut prepared = Vec::with_capacity(inputs.len());
73 for (ctx, log) in inputs {
74 let log = self.prepare_log_insert(log, ctx.clone()).await?;
75 prepared.push((Arc::new(ctx.fork()), log));
78 }
79
80 let mut outputs = Vec::with_capacity(prepared.len());
81 for (ctx, log) in prepared {
82 outputs.push(self.handle_log_inserts(log, ctx).await);
83 }
84 Ok(outputs)
85 }
86
87 async fn get_pipeline(
88 &self,
89 name: &str,
90 version: PipelineVersion,
91 query_ctx: QueryContextRef,
92 ) -> ServerResult<Arc<Pipeline>> {
93 self.pipeline_operator
94 .get_pipeline(query_ctx, name, version)
95 .await
96 .context(PipelineSnafu)
97 }
98
99 async fn insert_pipeline(
100 &self,
101 name: &str,
102 content_type: &str,
103 pipeline: &str,
104 query_ctx: QueryContextRef,
105 ) -> ServerResult<PipelineInfo> {
106 self.pipeline_operator
107 .insert_pipeline(name, content_type, pipeline, query_ctx)
108 .await
109 .context(PipelineSnafu)
110 }
111
112 async fn delete_pipeline(
113 &self,
114 name: &str,
115 version: PipelineVersion,
116 ctx: QueryContextRef,
117 ) -> ServerResult<Option<()>> {
118 self.pipeline_operator
119 .delete_pipeline(name, version, ctx)
120 .await
121 .context(PipelineSnafu)
122 }
123
124 async fn get_table(
125 &self,
126 table: &str,
127 query_ctx: &QueryContext,
128 ) -> std::result::Result<Option<Arc<Table>>, catalog::error::Error> {
129 let catalog = query_ctx.current_catalog();
130 let schema = query_ctx.current_schema();
131 self.catalog_manager
132 .table(catalog, &schema, table, None)
133 .await
134 }
135
136 fn build_pipeline(&self, pipeline: &str) -> ServerResult<Pipeline> {
137 PipelineOperator::build_pipeline(pipeline).context(PipelineSnafu)
138 }
139
140 async fn get_pipeline_str(
141 &self,
142 name: &str,
143 version: PipelineVersion,
144 query_ctx: QueryContextRef,
145 ) -> ServerResult<(String, TimestampNanosecond)> {
146 self.pipeline_operator
147 .get_pipeline_str(name, version, query_ctx)
148 .await
149 .context(PipelineSnafu)
150 }
151}
152
153impl Instance {
154 pub async fn handle_log_inserts(
155 &self,
156 log: RowInsertRequests,
157 ctx: QueryContextRef,
158 ) -> ServerResult<Output> {
159 self.inserter
160 .handle_log_inserts(log, ctx, self.statement_executor.as_ref())
161 .await
162 .map_err(BoxedError::new)
163 .context(ExecuteGrpcRequestSnafu)
164 }
165
166 pub async fn handle_trace_inserts(
167 &self,
168 rows: RowInsertRequests,
169 ctx: QueryContextRef,
170 ) -> ServerResult<Output> {
171 self.inserter
172 .handle_trace_inserts(rows, ctx, self.statement_executor.as_ref())
173 .await
174 .map_err(BoxedError::new)
175 .context(ExecuteGrpcRequestSnafu)
176 }
177}