11require 'diego/bbs/bbs'
22require 'diego/errors'
33require 'diego/routes'
4- require 'net/http/persistent'
5- require 'uri'
64
75module Diego
86 class Client
7+ PROTOBUF_HEADER = { 'Content-Type' . freeze => 'application/x-protobuf' . freeze } . freeze
8+
99 def initialize ( url :, ca_cert_file :, client_cert_file :, client_key_file :,
1010 connect_timeout :, send_timeout :, receive_timeout :)
1111 ENV [ 'PB_IGNORE_DEPRECATIONS' ] ||= 'true'
12- @bbs_url = URI ( url )
13- @http_client = new_http_client (
12+ @client = build_client (
13+ url ,
1414 ca_cert_file ,
1515 client_cert_file ,
1616 client_key_file ,
@@ -20,121 +20,157 @@ def initialize(url:, ca_cert_file:, client_cert_file:, client_key_file:,
2020 end
2121
2222 def ping
23- req = post_request ( path : Routes ::PING )
24- response = request_with_error_handling ( req )
23+ response = with_request_error_handling do
24+ client . post ( Routes ::PING )
25+ end
2526
26- validate_status! ( response )
27+ validate_status! ( response : response , statuses : [ 200 ] )
2728 protobuf_decode! ( response . body , Bbs ::Models ::PingResponse )
2829 end
2930
3031 def upsert_domain ( domain :, ttl :)
31- req = post_request ( body : protobuf_encode! ( { domain : domain , ttl : ttl . to_i } , Bbs ::Models ::UpsertDomainRequest ) , path : Routes ::UPSERT_DOMAIN )
32- response = request_with_error_handling ( req )
32+ request = protobuf_encode! ( { domain : domain , ttl : ttl . to_i } , Bbs ::Models ::UpsertDomainRequest )
33+
34+ response = with_request_error_handling do
35+ client . post ( Routes ::UPSERT_DOMAIN , request , PROTOBUF_HEADER )
36+ end
3337
34- validate_status! ( response )
38+ validate_status! ( response : response , statuses : [ 200 ] )
3539 protobuf_decode! ( response . body , Bbs ::Models ::UpsertDomainResponse )
3640 end
3741
3842 def desire_task ( task_definition :, domain :, task_guid :)
39- req = post_request ( body : protobuf_encode! ( { task_definition : task_definition , domain : domain , task_guid : task_guid } , Bbs ::Models ::DesireTaskRequest ) ,
40- path : Routes ::DESIRE_TASK )
41- response = request_with_error_handling ( req )
43+ request = protobuf_encode! ( { task_definition : task_definition , domain : domain , task_guid : task_guid } , Bbs ::Models ::DesireTaskRequest )
4244
43- validate_status! ( response )
45+ response = with_request_error_handling do
46+ client . post ( Routes ::DESIRE_TASK , request , PROTOBUF_HEADER )
47+ end
48+
49+ validate_status! ( response : response , statuses : [ 200 ] )
4450 protobuf_decode! ( response . body , Bbs ::Models ::TaskLifecycleResponse )
4551 end
4652
4753 def task_by_guid ( task_guid )
48- req = post_request ( body : protobuf_encode! ( { task_guid : task_guid } , Bbs ::Models ::TaskByGuidRequest ) , path : Routes ::TASK_BY_GUID )
49- response = request_with_error_handling ( req )
54+ request = protobuf_encode! ( { task_guid : task_guid } , Bbs ::Models ::TaskByGuidRequest )
55+
56+ response = with_request_error_handling do
57+ client . post ( Routes ::TASK_BY_GUID , request , PROTOBUF_HEADER )
58+ end
5059
51- validate_status! ( response )
60+ validate_status! ( response : response , statuses : [ 200 ] )
5261 protobuf_decode! ( response . body , Bbs ::Models ::TaskResponse )
5362 end
5463
5564 def tasks ( domain : '' , cell_id : '' )
56- req = post_request ( body : protobuf_encode! ( { domain : domain , cell_id : cell_id } , Bbs ::Models ::TasksRequest ) , path : Routes ::LIST_TASKS )
57- response = request_with_error_handling ( req )
65+ request = protobuf_encode! ( { domain : domain , cell_id : cell_id } , Bbs ::Models ::TasksRequest )
5866
59- validate_status! ( response )
67+ response = with_request_error_handling do
68+ client . post ( Routes ::LIST_TASKS , request , PROTOBUF_HEADER )
69+ end
70+
71+ validate_status! ( response : response , statuses : [ 200 ] )
6072 protobuf_decode! ( response . body , Bbs ::Models ::TasksResponse )
6173 end
6274
6375 def cancel_task ( task_guid )
64- req = post_request ( body : protobuf_encode! ( { task_guid : task_guid } , Bbs ::Models ::TaskGuidRequest ) , path : Routes ::CANCEL_TASK )
65- response = request_with_error_handling ( req )
76+ request = protobuf_encode! ( { task_guid : task_guid } , Bbs ::Models ::TaskGuidRequest )
77+
78+ response = with_request_error_handling do
79+ client . post ( Routes ::CANCEL_TASK , request , PROTOBUF_HEADER )
80+ end
6681
67- validate_status! ( response )
82+ validate_status! ( response : response , statuses : [ 200 ] )
6883 protobuf_decode! ( response . body , Bbs ::Models ::TaskLifecycleResponse )
6984 end
7085
7186 def desire_lrp ( lrp )
72- req = post_request ( body : protobuf_encode! ( { desired_lrp : lrp } , Bbs ::Models ::DesireLRPRequest ) , path : Routes ::DESIRE_LRP )
73- response = request_with_error_handling ( req )
87+ request = protobuf_encode! ( { desired_lrp : lrp } , Bbs ::Models ::DesireLRPRequest )
7488
75- validate_status! ( response )
89+ response = with_request_error_handling do
90+ client . post ( Routes ::DESIRE_LRP , request , PROTOBUF_HEADER )
91+ end
92+
93+ validate_status! ( response : response , statuses : [ 200 ] )
7694 protobuf_decode! ( response . body , Bbs ::Models ::DesiredLRPLifecycleResponse )
7795 end
7896
7997 def desired_lrp_by_process_guid ( process_guid )
80- req = post_request ( body : protobuf_encode! ( { process_guid : process_guid } , Bbs ::Models ::DesiredLRPByProcessGuidRequest ) , path : Routes ::DESIRED_LRP_BY_PROCESS_GUID )
81- response = request_with_error_handling ( req )
98+ request = protobuf_encode! ( { process_guid : process_guid } , Bbs ::Models ::DesiredLRPByProcessGuidRequest )
99+
100+ response = with_request_error_handling do
101+ client . post ( Routes ::DESIRED_LRP_BY_PROCESS_GUID , request , PROTOBUF_HEADER )
102+ end
82103
83- validate_status! ( response )
104+ validate_status! ( response : response , statuses : [ 200 ] )
84105 protobuf_decode! ( response . body , Bbs ::Models ::DesiredLRPResponse )
85106 end
86107
87108 def update_desired_lrp ( process_guid , lrp_update )
88- req = post_request ( body : protobuf_encode! ( { process_guid : process_guid , update : lrp_update } , Bbs ::Models ::UpdateDesiredLRPRequest ) , path : Routes ::UPDATE_DESIRED_LRP )
89- response = request_with_error_handling ( req )
109+ request = protobuf_encode! ( { process_guid : process_guid , update : lrp_update } , Bbs ::Models ::UpdateDesiredLRPRequest )
90110
91- validate_status! ( response )
111+ response = with_request_error_handling do
112+ client . post ( Routes ::UPDATE_DESIRED_LRP , request , PROTOBUF_HEADER )
113+ end
114+
115+ validate_status! ( response : response , statuses : [ 200 ] )
92116 protobuf_decode! ( response . body , Bbs ::Models ::DesiredLRPLifecycleResponse )
93117 end
94118
95119 def remove_desired_lrp ( process_guid )
96- req = post_request ( body : protobuf_encode! ( { process_guid : process_guid } , Bbs ::Models ::RemoveDesiredLRPRequest ) , path : Routes ::REMOVE_DESIRED_LRP )
97- response = request_with_error_handling ( req )
120+ request = protobuf_encode! ( { process_guid : process_guid } , Bbs ::Models ::RemoveDesiredLRPRequest )
121+
122+ response = with_request_error_handling do
123+ client . post ( Routes ::REMOVE_DESIRED_LRP , request , PROTOBUF_HEADER )
124+ end
98125
99- validate_status! ( response )
126+ validate_status! ( response : response , statuses : [ 200 ] )
100127 protobuf_decode! ( response . body , Bbs ::Models ::DesiredLRPLifecycleResponse )
101128 end
102129
103130 def retire_actual_lrp ( actual_lrp_key )
104- req = post_request ( body : protobuf_encode! ( { actual_lrp_key : actual_lrp_key } , Bbs ::Models ::RetireActualLRPRequest ) , path : Routes ::RETIRE_ACTUAL_LRP )
105- response = request_with_error_handling ( req )
131+ request = protobuf_encode! ( { actual_lrp_key : actual_lrp_key } , Bbs ::Models ::RetireActualLRPRequest )
106132
107- validate_status! ( response )
133+ response = with_request_error_handling do
134+ client . post ( Routes ::RETIRE_ACTUAL_LRP , request , PROTOBUF_HEADER )
135+ end
136+
137+ validate_status! ( response : response , statuses : [ 200 ] )
108138 protobuf_decode! ( response . body , Bbs ::Models ::ActualLRPLifecycleResponse )
109139 end
110140
111141 def desired_lrp_scheduling_infos ( domain )
112- req = post_request ( body : protobuf_encode! ( { domain : domain } , Bbs ::Models ::DesiredLRPsRequest ) , path : Routes ::DESIRED_LRP_SCHEDULING_INFOS )
113- response = request_with_error_handling ( req )
142+ request = protobuf_encode! ( { domain : domain } , Bbs ::Models ::DesiredLRPsRequest )
143+
144+ response = with_request_error_handling do
145+ client . post ( Routes ::DESIRED_LRP_SCHEDULING_INFOS , request , PROTOBUF_HEADER )
146+ end
114147
115- validate_status! ( response )
148+ validate_status! ( response : response , statuses : [ 200 ] )
116149 protobuf_decode! ( response . body , Bbs ::Models ::DesiredLRPSchedulingInfosResponse )
117150 end
118151
119152 def actual_lrps_by_process_guid ( process_guid )
120- req = post_request ( body : protobuf_encode! ( { process_guid : process_guid } , Bbs ::Models ::ActualLRPsRequest ) , path : Routes ::ACTUAL_LRPS )
121- response = request_with_error_handling ( req )
153+ request = protobuf_encode! ( { process_guid : process_guid } , Bbs ::Models ::ActualLRPsRequest )
122154
123- validate_status! ( response )
155+ response = with_request_error_handling do
156+ client . post ( Routes ::ACTUAL_LRPS , request , PROTOBUF_HEADER )
157+ end
158+
159+ validate_status! ( response : response , statuses : [ 200 ] )
124160 protobuf_decode! ( response . body , Bbs ::Models ::ActualLRPsResponse )
125161 end
126162
127- def request_with_error_handling ( req )
128- attempt ||= 1
129- http_client . request ( bbs_url + req . path , req )
163+ def with_request_error_handling ( & blk )
164+ tries ||= 3
165+ yield
130166 rescue => e
131- retry unless ( attempt + = 1 ) > 3
167+ retry unless ( tries - = 1 ) . zero?
132168 raise RequestError . new ( e . message )
133169 end
134170
135171 private
136172
137- attr_reader :http_client , :bbs_url
173+ attr_reader :client
138174
139175 def protobuf_encode! ( hash , protobuf_message_class )
140176 # See below link to understand proto3 message encoding
@@ -144,15 +180,8 @@ def protobuf_encode!(hash, protobuf_message_class)
144180 raise EncodeError . new ( e . message )
145181 end
146182
147- def post_request ( body : nil , path :)
148- req = Net ::HTTP ::Post . new ( path )
149- req . body = body if body
150- req [ 'Content-Type' . freeze ] = 'application/x-protobuf' . freeze
151- req
152- end
153-
154- def validate_status! ( response )
155- raise ResponseError . new ( "failed with status: #{ response . code } , body: #{ response . body } " ) unless response . code == '200'
183+ def validate_status! ( response :, statuses :)
184+ raise ResponseError . new ( "failed with status: #{ response . status } , body: #{ response . body } " ) unless statuses . include? ( response . status )
156185 end
157186
158187 def protobuf_decode! ( message , protobuf_decoder )
@@ -161,16 +190,14 @@ def protobuf_decode!(message, protobuf_decoder)
161190 raise DecodeError . new ( e . message )
162191 end
163192
164- def new_http_client ( ca_cert_file , client_cert_file , client_key_file ,
165- connect_timeout , send_timeout , receive_timeout )
166- client = Net ::HTTP ::Persistent . new ( pool_size : WorkPool ::SIZE )
167- client . verify_mode = OpenSSL ::SSL ::VERIFY_PEER
168- client . private_key = OpenSSL ::PKey ::RSA . new ( File . read ( client_key_file ) )
169- client . certificate = OpenSSL ::X509 ::Certificate . new ( File . read ( client_cert_file ) )
170- client . ca_file = ca_cert_file
171- client . open_timeout = connect_timeout
172- client . read_timeout = receive_timeout
173- client . write_timeout = send_timeout
193+ def build_client ( url , ca_cert_file , client_cert_file , client_key_file ,
194+ connect_timeout , send_timeout , receive_timeout )
195+ client = HTTPClient . new ( base_url : url )
196+ client . connect_timeout = connect_timeout
197+ client . send_timeout = send_timeout
198+ client . receive_timeout = receive_timeout
199+ client . ssl_config . set_client_cert_file ( client_cert_file , client_key_file )
200+ client . ssl_config . set_trust_ca ( ca_cert_file )
174201 client
175202 end
176203 end
0 commit comments