11use crate :: error;
22use crate :: subscription:: Subscription ;
3+ use crate :: topic:: Topic ;
34use futures:: prelude:: * ;
45use goauth:: auth:: JwtClaims ;
56use goauth:: scopes:: Scope ;
7+ use hyper:: client:: HttpConnector ;
8+ use hyper_tls:: HttpsConnector ;
69use smpl_jwt:: Jwt ;
710use std:: sync:: { Arc , RwLock } ;
811use std:: time:: { Duration , Instant } ;
912use tokio:: timer:: Interval ;
1013
14+ type HyperClient = Arc < hyper:: Client < HttpsConnector < HttpConnector > , hyper:: Body > > ;
15+
1116pub struct State {
1217 token : Option < goauth:: auth:: Token > ,
1318 credentials_path : String ,
1419 project : Option < String > ,
20+ hyper_client : HyperClient ,
1521}
1622
1723impl State {
@@ -28,53 +34,53 @@ impl State {
2834 }
2935}
3036
31- pub trait Client
32- where
33- Self : std:: marker:: Sized ,
34- {
35- fn create ( credentials_path : String ) -> Result < Self , error:: Error > ;
36- fn subscribe ( & self , name : String ) -> Subscription ;
37- fn set_project ( & mut self , project : String ) ;
38- fn project ( & self ) -> String ;
39-
40- fn spawn_token_renew ( & self ) ;
41- fn refresh_token ( & mut self ) -> Result < ( ) , error:: Error > ;
42- fn get_token ( & mut self ) -> Result < goauth:: auth:: Token , goauth:: error:: GOErr > ;
43- }
44-
45- pub type BaseClient = Arc < RwLock < State > > ;
37+ pub struct Client ( Arc < RwLock < State > > ) ;
4638
47- impl Client for BaseClient {
48- fn subscribe ( & self , name : String ) -> Subscription {
49- Subscription {
50- client : self . clone ( ) ,
51- canonical_name : format ! ( "projects/{}/subscriptions/{}" , self . project( ) , name) ,
52- name,
53- }
39+ impl Clone for Client {
40+ fn clone ( & self ) -> Self {
41+ Client ( self . 0 . clone ( ) )
5442 }
43+ }
5544
56- fn create ( credentials_path : String ) -> Result < Self , error:: Error > {
57- let mut client = Arc :: new ( RwLock :: new ( State {
45+ impl Client {
46+ pub fn new ( credentials_path : String ) -> Result < Self , error:: Error > {
47+ let mut client = Client ( Arc :: new ( RwLock :: new ( State {
5848 token : None ,
5949 credentials_path,
6050 project : None ,
61- } ) ) ;
51+ hyper_client : setup_hyper ( ) ,
52+ } ) ) ) ;
6253
6354 match client. refresh_token ( ) {
6455 Ok ( _) => Ok ( client) ,
6556 Err ( e) => Err ( e) ,
6657 }
6758 }
6859
69- fn set_project ( & mut self , project : String ) {
70- self . write ( ) . unwrap ( ) . project = Some ( project) ;
60+ pub fn subscribe ( & self , name : String ) -> Subscription {
61+ Subscription {
62+ client : Some ( self . clone ( ) ) ,
63+ name : format ! ( "projects/{}/subscriptions/{}" , self . project( ) , name) ,
64+ topic : None ,
65+ }
7166 }
7267
73- fn project ( & self ) -> String {
74- self . read ( ) . unwrap ( ) . project ( ) . to_string ( )
68+ pub fn set_project ( & mut self , project : String ) {
69+ self . 0 . write ( ) . unwrap ( ) . project = Some ( project ) ;
7570 }
7671
77- fn spawn_token_renew ( & self ) {
72+ pub fn project ( & self ) -> String {
73+ self . 0 . read ( ) . unwrap ( ) . project ( ) . to_string ( )
74+ }
75+
76+ pub fn topic ( & self , name : String ) -> Topic {
77+ Topic {
78+ client : Some ( Client ( self . 0 . clone ( ) ) ) ,
79+ name : format ! ( "projects/{}/topics/{}" , self . project( ) , name) ,
80+ }
81+ }
82+
83+ pub fn spawn_token_renew ( & self ) {
7884 let mut client = self . clone ( ) ;
7985 let renew_token_task = Interval :: new ( Instant :: now ( ) , Duration :: from_secs ( 15 * 60 ) )
8086 . for_each ( move |_instant| {
@@ -89,10 +95,10 @@ impl Client for BaseClient {
8995 tokio:: spawn ( renew_token_task) ;
9096 }
9197
92- fn refresh_token ( & mut self ) -> Result < ( ) , error:: Error > {
98+ pub fn refresh_token ( & mut self ) -> Result < ( ) , error:: Error > {
9399 match self . get_token ( ) {
94100 Ok ( token) => {
95- self . write ( ) . unwrap ( ) . token = Some ( token) ;
101+ self . 0 . write ( ) . unwrap ( ) . token = Some ( token) ;
96102 Ok ( ( ) )
97103 }
98104 Err ( e) => Err ( error:: Error :: from ( e) ) ,
@@ -101,7 +107,7 @@ impl Client for BaseClient {
101107
102108 fn get_token ( & mut self ) -> Result < goauth:: auth:: Token , goauth:: error:: GOErr > {
103109 let credentials =
104- goauth:: credentials:: Credentials :: from_file ( & self . read ( ) . unwrap ( ) . credentials_path )
110+ goauth:: credentials:: Credentials :: from_file ( & self . 0 . read ( ) . unwrap ( ) . credentials_path )
105111 . unwrap ( ) ;
106112
107113 self . set_project ( credentials. project ( ) ) ;
@@ -116,4 +122,41 @@ impl Client for BaseClient {
116122 let jwt = Jwt :: new ( claims, credentials. rsa_key ( ) . unwrap ( ) , None ) ;
117123 goauth:: get_token_with_creds ( & jwt, & credentials)
118124 }
125+
126+ pub ( crate ) fn request < T : Into < hyper:: Body > > (
127+ & self ,
128+ method : hyper:: Method ,
129+ data : T ,
130+ ) -> hyper:: Request < hyper:: Body >
131+ where
132+ hyper:: Body : std:: convert:: From < T > ,
133+ {
134+ let mut req = hyper:: Request :: new ( hyper:: Body :: from ( data) ) ;
135+ * req. method_mut ( ) = method;
136+ req. headers_mut ( ) . insert (
137+ hyper:: header:: CONTENT_TYPE ,
138+ hyper:: header:: HeaderValue :: from_static ( "application/json" ) ,
139+ ) ;
140+ let readable = self . 0 . read ( ) . unwrap ( ) ;
141+ req. headers_mut ( ) . insert (
142+ hyper:: header:: AUTHORIZATION ,
143+ hyper:: header:: HeaderValue :: from_str ( & format ! (
144+ "{} {}" ,
145+ readable. token_type( ) ,
146+ readable. access_token( )
147+ ) )
148+ . unwrap ( ) ,
149+ ) ;
150+ req
151+ }
152+
153+ pub fn hyper_client ( & self ) -> HyperClient {
154+ self . 0 . read ( ) . unwrap ( ) . hyper_client . clone ( )
155+ }
156+ }
157+
158+ fn setup_hyper ( ) -> HyperClient {
159+ // 4 is number of blocking DNS threads
160+ let https = HttpsConnector :: new ( 4 ) . unwrap ( ) ;
161+ Arc :: new ( hyper:: Client :: builder ( ) . build :: < _ , hyper:: Body > ( https) )
119162}
0 commit comments