@@ -14,7 +14,7 @@ use logger::RuntimeLevel;
14
14
use profile:: Profiler ;
15
15
use prom_remote_api:: { types:: RemoteStorageRef , web} ;
16
16
use query_engine:: executor:: Executor as QueryExecutor ;
17
- use router:: endpoint:: Endpoint ;
17
+ use router:: { endpoint:: Endpoint , Router , RouterRef } ;
18
18
use serde:: Serialize ;
19
19
use snafu:: { Backtrace , OptionExt , ResultExt , Snafu } ;
20
20
use table_engine:: { engine:: EngineRuntimes , table:: FlushRequest } ;
@@ -105,6 +105,9 @@ pub enum Error {
105
105
106
106
#[ snafu( display( "Server already started.\n Backtrace:\n {}" , backtrace) ) ]
107
107
AlreadyStarted { backtrace : Backtrace } ,
108
+
109
+ #[ snafu( display( "Missing router.\n Backtrace:\n {}" , backtrace) ) ]
110
+ MissingRouter { backtrace : Backtrace } ,
108
111
}
109
112
110
113
define_result ! ( Error ) ;
@@ -128,6 +131,7 @@ pub struct Service<Q> {
128
131
rx : Option < Receiver < ( ) > > ,
129
132
config : HttpConfig ,
130
133
config_content : String ,
134
+ router : Arc < dyn Router + Send + Sync > ,
131
135
}
132
136
133
137
impl < Q : QueryExecutor + ' static > Service < Q > {
@@ -178,6 +182,7 @@ impl<Q: QueryExecutor + 'static> Service<Q> {
178
182
. or ( self . sql ( ) )
179
183
. or ( self . influxdb_api ( ) )
180
184
. or ( self . prom_api ( ) )
185
+ . or ( self . route ( ) )
181
186
// admin APIs
182
187
. or ( self . admin_block ( ) )
183
188
// debug APIs
@@ -253,6 +258,30 @@ impl<Q: QueryExecutor + 'static> Service<Q> {
253
258
} )
254
259
}
255
260
261
+ // GET /route
262
+ fn route ( & self ) -> impl Filter < Extract = ( impl warp:: Reply , ) , Error = warp:: Rejection > + Clone {
263
+ warp:: path!( "route" / String )
264
+ . and ( warp:: get ( ) )
265
+ . and ( self . with_context ( ) )
266
+ . and ( self . with_instance ( ) )
267
+ . and_then ( |table : String , ctx, instance| async move {
268
+ let result = handlers:: route:: handle_route ( & ctx, instance, & table)
269
+ . await
270
+ . map_err ( |e| {
271
+ error ! (
272
+ "Http service Failed to find route of table:{}, err:{:?}" ,
273
+ table, e
274
+ ) ;
275
+ Box :: new ( e)
276
+ } )
277
+ . context ( HandleRequest ) ;
278
+ match result {
279
+ Ok ( res) => Ok ( reply:: json ( & res) ) ,
280
+ Err ( e) => Err ( reject:: custom ( e) ) ,
281
+ }
282
+ } )
283
+ }
284
+
256
285
/// for write api:
257
286
/// POST `/influxdb/v1/write`
258
287
///
@@ -446,6 +475,7 @@ impl<Q: QueryExecutor + 'static> Service<Q> {
446
475
//TODO(boyan) use read/write runtime by sql type.
447
476
let runtime = self . engine_runtimes . bg_runtime . clone ( ) ;
448
477
let timeout = self . config . timeout ;
478
+ let router = self . router . clone ( ) ;
449
479
450
480
header:: optional :: < String > ( consts:: CATALOG_HEADER )
451
481
. and ( header:: optional :: < String > ( consts:: SCHEMA_HEADER ) )
@@ -456,13 +486,15 @@ impl<Q: QueryExecutor + 'static> Service<Q> {
456
486
let default_catalog = default_catalog. clone ( ) ;
457
487
let runtime = runtime. clone ( ) ;
458
488
let schema = schema. unwrap_or_else ( || default_schema. clone ( ) ) ;
489
+ let router = router. clone ( ) ;
459
490
async move {
460
491
RequestContext :: builder ( )
461
492
. catalog ( catalog. unwrap_or ( default_catalog) )
462
493
. schema ( schema)
463
494
. runtime ( runtime)
464
495
. timeout ( timeout)
465
496
. enable_partition_table_access ( true )
497
+ . router ( router)
466
498
. build ( )
467
499
. context ( CreateContext )
468
500
. map_err ( reject:: custom)
@@ -506,6 +538,7 @@ pub struct Builder<Q> {
506
538
instance : Option < InstanceRef < Q > > ,
507
539
schema_config_provider : Option < SchemaConfigProviderRef > ,
508
540
config_content : Option < String > ,
541
+ router : Option < RouterRef > ,
509
542
}
510
543
511
544
impl < Q > Builder < Q > {
@@ -517,6 +550,7 @@ impl<Q> Builder<Q> {
517
550
instance : None ,
518
551
schema_config_provider : None ,
519
552
config_content : None ,
553
+ router : None ,
520
554
}
521
555
}
522
556
@@ -544,6 +578,11 @@ impl<Q> Builder<Q> {
544
578
self . config_content = Some ( content) ;
545
579
self
546
580
}
581
+
582
+ pub fn router ( mut self , router : RouterRef ) -> Self {
583
+ self . router = Some ( router) ;
584
+ self
585
+ }
547
586
}
548
587
549
588
impl < Q : QueryExecutor + ' static > Builder < Q > {
@@ -556,6 +595,7 @@ impl<Q: QueryExecutor + 'static> Builder<Q> {
556
595
let schema_config_provider = self
557
596
. schema_config_provider
558
597
. context ( MissingSchemaConfigProvider ) ?;
598
+ let router = self . router . context ( MissingRouter ) ?;
559
599
let prom_remote_storage = Arc :: new ( CeresDBStorage :: new (
560
600
instance. clone ( ) ,
561
601
schema_config_provider. clone ( ) ,
@@ -574,6 +614,7 @@ impl<Q: QueryExecutor + 'static> Builder<Q> {
574
614
rx : Some ( rx) ,
575
615
config : self . config . clone ( ) ,
576
616
config_content,
617
+ router,
577
618
} ;
578
619
579
620
Ok ( service)
@@ -610,6 +651,7 @@ fn error_to_status_code(err: &Error) -> StatusCode {
610
651
| Error :: JoinAsyncTask { .. }
611
652
| Error :: AlreadyStarted { .. }
612
653
| Error :: HandleUpdateLogLevel { .. } => StatusCode :: INTERNAL_SERVER_ERROR ,
654
+ Error :: MissingRouter { .. } => StatusCode :: INTERNAL_SERVER_ERROR ,
613
655
}
614
656
}
615
657
0 commit comments