Class: K3CloudWebapiSdk::Core::WebApiClient

Inherits:
Object
  • Object
show all
Defined in:
lib/k3cloud_webapi_sdk/core/webapi_client.rb

Overview

Web API Client class

Direct Known Subclasses

K3CloudApiSdk

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#configObject

Returns the value of attribute config.



33
34
35
# File 'lib/k3cloud_webapi_sdk/core/webapi_client.rb', line 33

def config
  @config
end

#connect_timeoutObject

Returns the value of attribute connect_timeout.



33
34
35
# File 'lib/k3cloud_webapi_sdk/core/webapi_client.rb', line 33

def connect_timeout
  @connect_timeout
end

#cookies_storeObject

Returns the value of attribute cookies_store.



33
34
35
# File 'lib/k3cloud_webapi_sdk/core/webapi_client.rb', line 33

def cookies_store
  @cookies_store
end

#identifyObject

Returns the value of attribute identify.



33
34
35
# File 'lib/k3cloud_webapi_sdk/core/webapi_client.rb', line 33

def identify
  @identify
end

#initializeWebApiClient

Returns the value of attribute initialize.



33
34
35
# File 'lib/k3cloud_webapi_sdk/core/webapi_client.rb', line 33

def initialize
  @initialize
end

#proxyObject

Returns the value of attribute proxy.



33
34
35
# File 'lib/k3cloud_webapi_sdk/core/webapi_client.rb', line 33

def proxy
  @proxy
end

#request_timeoutObject

Returns the value of attribute request_timeout.



33
34
35
# File 'lib/k3cloud_webapi_sdk/core/webapi_client.rb', line 33

def request_timeout
  @request_timeout
end

Instance Method Details

#build_header(service_url) ⇒ Object

Build request headers



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/k3cloud_webapi_sdk/core/webapi_client.rb', line 78

def build_header(service_url)
  path_url = service_url
  if service_url.start_with?('http')
    uri = URI.parse(service_url)
    path_url = uri.path
  end
  
  path_url = ERB::Util.url_encode(path_url).gsub('/', '%2F')
  time_stamp = Time.now.to_i.to_s
  nonce = Time.now.to_i.to_s
  client_id = ''
  client_sec = ''
  
  arr = @identify.app_id.split('_')
  if arr.length == 2
    client_id = arr[0]
    client_sec = Util::EncodeUtil.decode_app_secret(arr[1])
  end
  
  api_sign = 'POST\n' + path_url + '\n\nx-api-nonce:' + nonce + '\nx-api-timestamp:' + time_stamp + '\n'
  app_data = @identify.dcid + ',' + @identify.user_name + ',' + @identify.lcid.to_s + ',' + @identify.org_num.to_s
  
  dic_header = {
    Const::HeaderParam::X_Api_ClientID => client_id,
    Const::HeaderParam::X_Api_Auth_Version => '2.0',
    Const::HeaderParam::X_Api_Timestamp => time_stamp,
    Const::HeaderParam::X_Api_Nonce => nonce,
    Const::HeaderParam::X_Api_SignHeaders => 'x-api-timestamp,x-api-nonce',
    Const::HeaderParam::X_Api_Signature => Util::HmacUtil.hmac_sha256(api_sign, client_sec),
    Const::HeaderParam::X_KD_AppKey => @identify.app_id,
    Const::HeaderParam::X_KD_AppData => Util::Base64Util.encode(app_data.bytes),
    Const::HeaderParam::X_KD_Signature => Util::HmacUtil.hmac_sha256(@identify.app_id + app_data, @identify.app_secret)
  }
  
  if !@cookies_store.sid.empty?
    dic_header[Const::HeaderParam::KDService_SessionId] = @cookies_store.sid
  end
  
  if @cookies_store.cookies.length > 0
    cookie_str = 'Theme=standard'
    @cookies_store.cookies.each_value do |cookie|
      cookie_str += ';' + cookie.to_s
    end
    dic_header['Cookie'] = cookie_str
  end
  
  dic_header['Accept-Charset'] = 'utf-8'
  dic_header['User-Agent'] = 'Kingdee/Ruby WebApi SDK 8.2.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)'
  dic_header['Content-Type'] = 'application/json'
  
  dic_header
end

#execute(service_name, json_data = nil, invoke_type = Const::InvokeMethod::SYNC) ⇒ Object

Execute API call



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/k3cloud_webapi_sdk/core/webapi_client.rb', line 190

def execute(service_name, json_data = nil, invoke_type = Const::InvokeMethod::SYNC)
  if !@initialize
    raise '拒绝请求,请先正确初始化!'
  end
  
  if @config.nil?
    raise '请先初始化SDK配置信息!'
  end
  
  case invoke_type
  when Const::InvokeMethod::SYNC
    post_json(service_name, json_data, Const::InvokeMethod::SYNC)
  when Const::InvokeMethod::QUERY
    execute_by_query(service_name, json_data)
  else
    raise 'Not support for InvokeMode:' + invoke_type.to_s
  end
end

#execute_by_query(service_name, json_data = nil) ⇒ Object

Execute by query method



210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/k3cloud_webapi_sdk/core/webapi_client.rb', line 210

def execute_by_query(service_name, json_data = nil)
  response_content = post_json(service_name, json_data, Const::InvokeMethod::QUERY)
  json_result = JSON.parse(response_content)
  
  if json_result['Status'] == Const::QueryState::Complete
    return json_result['Result'].to_json
  else
    return query_task_result(
      service_name, 
      { 'TaskId' => json_result['TaskId'], 'Cancelled' => false }, 
      5
    )
  end
end

Fill cookies and headers



175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/k3cloud_webapi_sdk/core/webapi_client.rb', line 175

def fill_cookie_and_header(cookies, headers)
  @cookies_store.set_sid(cookies[Const::HeaderParam::KDService_SessionId])
  
  if headers[Const::HeaderParam::Cookie_Set]
    @cookies_store.cookies.clear
    headers[Const::HeaderParam::Cookie_Set].split(',').each do |item|
      ck = Model::Cookie.parse(item)
      if ck
        @cookies_store.cookies[ck.name] = ck
      end
    end
  end
end

#init(server_url, timeout, sdk_initialize) ⇒ Object

Initialize the client



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/k3cloud_webapi_sdk/core/webapi_client.rb', line 46

def init(server_url, timeout, sdk_initialize)
  @initialize = sdk_initialize
  
  if @config.nil?
    raise 'Configuration file unload, you need initial config firstly!'
  end
  
  if server_url.empty?
    # Cancel default old gateway, require url input by Ann 2025-01-15
    raise 'ServerUrl is required'
  end
  
  @identify = Model::Identity.new(
    server_url, 
    @config.dcid, 
    @config.user_name, 
    @config.app_id, 
    @config.app_secret, 
    @config.org_num, 
    @config.lcid, 
    ''
  )
  
  @connect_timeout = @config.connect_timeout if @config.connect_timeout > 0
  @request_timeout = @config.request_timeout if @config.request_timeout > 0
  @request_timeout = timeout if timeout > 0
  @proxy = @config.proxy if !@config.proxy.empty?
  
  self
end

#post_json(service_name, json_data = {}, invoke_type = Const::InvokeMethod::SYNC) ⇒ Object

Post JSON data



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/k3cloud_webapi_sdk/core/webapi_client.rb', line 132

def post_json(service_name, json_data = {}, invoke_type = Const::InvokeMethod::SYNC)
  json_data ||= {}
  
  req_url = if @identify.server_url.end_with?('/')
              @identify.server_url + service_name + '.common.kdsvc'
            else
              @identify.server_url + '/' + service_name + '.common.kdsvc'
            end
  
  proxies = nil
  if !@proxy.empty?
    proxies = { URI.parse(@proxy).scheme => @proxy }
  end
  
  if invoke_type == Const::InvokeMethod::QUERY
    json_data[Const::QueryMode::BeginMethod_Header] = Const::QueryMode::BeginMethod_Method
    json_data[Const::QueryMode::QueryMethod_Header] = Const::QueryMode::QueryMethod_Method
  end
  
  headers = build_header(req_url)
  
  begin
    response = RestClient.post(
      req_url,
      json_data.to_json,
      headers: headers,
      timeout: [@connect_timeout, @request_timeout],
      verify_ssl: false,
      proxy: @proxy.empty? ? nil : @proxy
    )
    
    if response.code == 200 || response.code == 206
      fill_cookie_and_header(response.cookies, response.headers)
      return Core.valid_result(response.body)
    else
      raise "HTTP Error #{response.code}: #{response.body}"
    end
  rescue RestClient::Exception => e
    raise "Request failed: #{e.message}"
  end
end

#query_task_result(service_name, param, retry_count) ⇒ Object

Query task result



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/k3cloud_webapi_sdk/core/webapi_client.rb', line 226

def query_task_result(service_name, param, retry_count)
  sleep(1)
  
  dot_index = service_name.rindex('.')
  query_service = if dot_index
                   service_name[0, dot_index] + '.' + Const::QueryMode::QueryMethod_Method
                 else
                   service_name + '.' + Const::QueryMode::QueryMethod_Method
                 end
  
  begin
    response_content = post_json(query_service, { 'queryInfo' => param.to_json }, Const::InvokeMethod::SYNC)
    json_result = JSON.parse(response_content)
    
    if json_result['Status'] == Const::QueryState::Complete
      json_result['Result'].to_json
    else
      query_task_result(service_name, param, 5)
    end
  rescue => err
    if retry_count > 0
      query_task_result(service_name, param, retry_count - 1)
    else
      raise err
    end
  end
end