Class: GoodData::Rest::Client
- Includes:
- Mixin::Inspector
- Defined in:
- lib/gooddata/rest/client.rb
Overview
User's interface to GoodData Platform.
MUST provide way to use - DELETE, GET, POST, PUT SHOULD provide way to use - HEAD, Bulk GET ...
Constant Summary collapse
- DEFAULT_CONNECTION_IMPLEMENTATION =
Constants
GoodData::Rest::Connection
- DEFAULT_SLEEP_INTERVAL =
10
- DEFAULT_POLL_TIME_LIMIT =
5 hours
5 * 60 * 60
- @@instance =
Class variables
nil
Instance Attribute Summary collapse
-
#connection ⇒ Object
readonly
Decide if we need provide direct access to connection.
-
#factory ⇒ Object
readonly
TODO: Decide if we need provide direct access to factory.
-
#opts ⇒ Object
readonly
Returns the value of attribute opts.
Class Method Summary collapse
-
.connect(username, password = 'aaaa', opts = {}) ⇒ GoodData::Rest::Client
Globally available way to connect (and create client and set global instance).
- .connect_sso(sso) ⇒ Object
- .connection ⇒ Object (also: client)
- .disconnect ⇒ Object
-
.retryable(options = {}, &block) ⇒ Object
Retry block if exception thrown.
Instance Method Summary collapse
- #connect ⇒ Object
-
#create(klass, data = {}, opts = {}) ⇒ Object
Factory stuff.
- #create_datawarehouse(opts = {}) ⇒ Object
- #create_project(options = { title: 'Project' }) ⇒ Object
- #create_project_from_blueprint(blueprint, options = {}) ⇒ Object
-
#delete(uri, opts = {}) ⇒ Object
Rest.
- #disconnect ⇒ Object
- #domain(domain_name) ⇒ Object
-
#download(source_relative_path, target_file_path, options = {}) ⇒ Object
Downloads file from staging.
- #download_from_user_webdav(source_relative_path, target_file_path, options = { client: GoodData.client }) ⇒ Object
- #find(klass, opts = {}) ⇒ Object
- #generate_request_id ⇒ Object
-
#get(uri, opts = {}, &block) ⇒ Object
HTTP GET.
-
#initialize(opts) ⇒ Client
constructor
Constructor of client.
- #links ⇒ Object
-
#poll_on_code(link, options = {}) ⇒ Hash
Generalizaton of poller.
-
#poll_on_response(link, options = {}, &bl) ⇒ Hash
Generalizaton of poller.
-
#post(uri, data, opts = {}) ⇒ Object
HTTP POST.
- #processes(id = :all) ⇒ Object
- #project_is_accessible?(id) ⇒ Boolean
- #project_webdav_path(opts = { project: GoodData.project }) ⇒ Object
- #projects(id = :all, limit = nil, offset = nil) ⇒ Object
-
#put(uri, data, opts = {}) ⇒ Object
HTTP PUT.
-
#resource(res_name) ⇒ Object
Gets resource by name.
- #stats_off ⇒ Object
- #stats_on ⇒ Object
- #stats_on? ⇒ Boolean
-
#upload(file, options = {}) ⇒ Object
Uploads file to staging.
- #upload_to_user_webdav(file, options = {}) ⇒ Object
- #user(id = nil) ⇒ Object
- #user_webdav_path ⇒ Object
- #warehouses(id = :all) ⇒ Object
- #with_project(pid, &block) ⇒ Object
Methods included from Mixin::Inspector
Constructor Details
#initialize(opts) ⇒ Client
Constructor of client
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/gooddata/rest/client.rb', line 153 def initialize(opts) # TODO: Decide if we want to pass the options directly or not @opts = opts @connection_factory = @opts[:connection_factory] || DEFAULT_CONNECTION_IMPLEMENTATION # TODO: See previous TODO # Create connection @connection = opts[:connection] || @connection_factory.new(opts) # Connect connect # Create factory bound to previously created connection @factory = ObjectFactory.new(self) end |
Instance Attribute Details
#connection ⇒ Object (readonly)
Decide if we need provide direct access to connection
41 42 43 |
# File 'lib/gooddata/rest/client.rb', line 41 def connection @connection end |
#factory ⇒ Object (readonly)
TODO: Decide if we need provide direct access to factory
44 45 46 |
# File 'lib/gooddata/rest/client.rb', line 44 def factory @factory end |
#opts ⇒ Object (readonly)
Returns the value of attribute opts.
45 46 47 |
# File 'lib/gooddata/rest/client.rb', line 45 def opts @opts end |
Class Method Details
.connect(username, password = 'aaaa', opts = {}) ⇒ GoodData::Rest::Client
Globally available way to connect (and create client and set global instance)
HACK
To make transition from old implementation to new one following HACK IS TEMPORARILY ENGAGED!
- First call of #connect sets the GoodData::Rest::Client.instance (static, singleton instance)
- There are METHOD functions with same signature as their CLASS counterparts using singleton instance
Example
client = GoodData.connect('[email protected]', 's3cr3tp4sw0rd')
69 70 71 72 73 74 75 76 77 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 |
# File 'lib/gooddata/rest/client.rb', line 69 def connect(username, password = 'aaaa', opts = {}) execution_id = "" if username.is_a?(Hash) && username.key?(:execution_id) execution_id = username[:execution_id] username.delete(:execution_id) end if opts.key?(:execution_id) execution_id = opts[:execution_id] opts.delete(:execution_id) end if username.nil? && password.nil? username = ENV['GD_GEM_USER'] password = ENV['GD_GEM_PASSWORD'] end username = GoodData::Helpers.symbolize_keys(username) if username.is_a?(Hash) new_opts = opts.dup if username.is_a?(Hash) && username.key?(:sst_token) new_opts = new_opts.merge(username) elsif username.is_a? Hash new_opts = new_opts.merge(username) new_opts[:username] = username[:login] || username[:user] || username[:username] new_opts[:password] = username[:password] elsif username.nil? && password.nil? && opts.blank? new_opts = Helpers::AuthHelper.read_credentials else new_opts[:username] = username new_opts[:password] = password end new_opts = { verify_ssl: true, execution_id: execution_id }.merge(new_opts) if username.is_a?(Hash) && username[:cookies] new_opts[:sst_token] = username[:cookies]['GDCAuthSST'] new_opts[:cookies] = username[:cookies] end unless new_opts[:sst_token] fail ArgumentError, 'No username specified' if new_opts[:username].nil? fail ArgumentError, 'No password specified' if new_opts[:password].nil? end if username.is_a?(Hash) && username.key?(:server) new_opts[:server] = username[:server] end client = Client.new(new_opts) GoodData.logger.info("Connected to server with webdav path #{client.user_webdav_path}") # HACK: This line assigns class instance # if not done yet @@instance = client # rubocop:disable ClassVars end |
.connect_sso(sso) ⇒ Object
124 125 126 |
# File 'lib/gooddata/rest/client.rb', line 124 def connect_sso(sso) @@instance = Client.new(sso) # rubocop:disable ClassVars end |
.connection ⇒ Object Also known as: client
135 136 137 |
# File 'lib/gooddata/rest/client.rb', line 135 def connection @@instance end |
.disconnect ⇒ Object
128 129 130 131 132 133 |
# File 'lib/gooddata/rest/client.rb', line 128 def disconnect if @@instance # rubocop:disable Style/GuardClause @@instance.disconnect @@instance = nil # rubocop:disable ClassVars end end |
.retryable(options = {}, &block) ⇒ Object
Retry block if exception thrown
140 141 142 |
# File 'lib/gooddata/rest/client.rb', line 140 def retryable( = {}, &block) GoodData::Rest::Connection.retryable(, &block) end |
Instance Method Details
#connect ⇒ Object
203 204 205 206 207 208 |
# File 'lib/gooddata/rest/client.rb', line 203 def connect username = @opts[:username] password = @opts[:password] @connection.connect(username, password, @opts) end |
#create(klass, data = {}, opts = {}) ⇒ Object
Factory stuff
229 230 231 |
# File 'lib/gooddata/rest/client.rb', line 229 def create(klass, data = {}, opts = {}) @factory.create(klass, data, opts) end |
#create_datawarehouse(opts = {}) ⇒ Object
222 223 224 |
# File 'lib/gooddata/rest/client.rb', line 222 def create_datawarehouse(opts = {}) GoodData::DataWarehouse.create({ client: self }.merge(opts)) end |
#create_project(options = { title: 'Project' }) ⇒ Object
170 171 172 |
# File 'lib/gooddata/rest/client.rb', line 170 def create_project( = { title: 'Project' }) GoodData::Project.create({ client: self }.merge()) end |
#create_project_from_blueprint(blueprint, options = {}) ⇒ Object
174 175 176 |
# File 'lib/gooddata/rest/client.rb', line 174 def create_project_from_blueprint(blueprint, = {}) GoodData::Model::ProjectCreator.migrate(.merge(spec: blueprint, client: self)) end |
#delete(uri, opts = {}) ⇒ Object
Rest
HTTP DELETE
273 274 275 |
# File 'lib/gooddata/rest/client.rb', line 273 def delete(uri, opts = {}) @connection.delete uri, opts.merge(stats_on: stats_on?) end |
#disconnect ⇒ Object
210 211 212 213 214 215 216 |
# File 'lib/gooddata/rest/client.rb', line 210 def disconnect if stats_on? GoodData.logger.info("API call statistics to server #{@connection.server}") GoodData.logger.info(@connection.stats_table.to_s) end @connection.disconnect end |
#domain(domain_name) ⇒ Object
178 179 180 |
# File 'lib/gooddata/rest/client.rb', line 178 def domain(domain_name) GoodData::Domain[domain_name, :client => self] end |
#download(source_relative_path, target_file_path, options = {}) ⇒ Object
Downloads file from staging
390 391 392 |
# File 'lib/gooddata/rest/client.rb', line 390 def download(source_relative_path, target_file_path, = {}) @connection.download source_relative_path, target_file_path, end |
#download_from_user_webdav(source_relative_path, target_file_path, options = { client: GoodData.client }) ⇒ Object
394 395 396 397 |
# File 'lib/gooddata/rest/client.rb', line 394 def download_from_user_webdav(source_relative_path, target_file_path, = { client: GoodData.client }) download(source_relative_path, target_file_path, .merge(:directory => [:directory], :staging_url => user_webdav_path)) end |
#find(klass, opts = {}) ⇒ Object
233 234 235 |
# File 'lib/gooddata/rest/client.rb', line 233 def find(klass, opts = {}) @factory.find(klass, opts) end |
#generate_request_id ⇒ Object
263 264 265 |
# File 'lib/gooddata/rest/client.rb', line 263 def generate_request_id @connection.generate_request_id end |
#get(uri, opts = {}, &block) ⇒ Object
HTTP GET
280 281 282 |
# File 'lib/gooddata/rest/client.rb', line 280 def get(uri, opts = {}, & block) @connection.get uri, opts.merge(stats_on: stats_on?), & block end |
#links ⇒ Object
408 409 410 |
# File 'lib/gooddata/rest/client.rb', line 408 def links GoodData::Helpers.get_path(get('/gdc'), %w(about links)) end |
#poll_on_code(link, options = {}) ⇒ Hash
Generalizaton of poller. Since we have quite a variation of how async proceses are handled this is a helper that should help you with resources where the information about "Are we done" is the http code of response. By default we repeat as long as the code == 202. You can change the code if necessary. It expects the URI as an input where it can poll. It returns the value of last poll. In majority of cases these are the data that you need.
317 318 319 320 321 322 323 324 325 326 327 328 329 330 |
# File 'lib/gooddata/rest/client.rb', line 317 def poll_on_code(link, = {}) code = [:code] || 202 process = [:process] response = poll_on_response(link, .merge(:process => false)) do |resp| resp.code == code end if process == false response else get(link) end end |
#poll_on_response(link, options = {}, &bl) ⇒ Hash
Generalizaton of poller. Since we have quite a variation of how async proceses are handled this is a helper that should help you with resources where the information about "Are we done" is inside the response. It expects the URI as an input where it can poll and a block that should return either true (meaning sleep and repeat) or false (meaning we are done). It returns the value of last poll. In majority of cases these are the data that you need
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 |
# File 'lib/gooddata/rest/client.rb', line 341 def poll_on_response(link, = {}, &bl) time_limit = [:time_limit] || DEFAULT_POLL_TIME_LIMIT process = [:process] == false ? false : true # get the first status and start the timer response = get(link, process: process) poll_start = Time.now retry_time = GoodData::Rest::Connection::RETRY_TIME_INITIAL_VALUE while bl.call(response) limit_breached = time_limit && (Time.now - poll_start > time_limit) if limit_breached fail ExecutionLimitExceeded, "The time limit #{time_limit} secs for polling on #{link} is over" end sleep retry_time retry_time *= GoodData::Rest::Connection::RETRY_TIME_COEFFICIENT GoodData::Rest::Client.retryable(:tries => Helpers::GD_MAX_RETRY, :refresh_token => proc { connection.refresh_token }) do response = get(link, process: process) end end response end |
#post(uri, data, opts = {}) ⇒ Object
HTTP POST
373 374 375 |
# File 'lib/gooddata/rest/client.rb', line 373 def post(uri, data, opts = {}) @connection.post uri, data, opts.merge(stats_on: stats_on?) end |
#processes(id = :all) ⇒ Object
199 200 201 |
# File 'lib/gooddata/rest/client.rb', line 199 def processes(id = :all) GoodData::Process[id, client: self] end |
#project_is_accessible?(id) ⇒ Boolean
182 183 184 185 186 187 188 189 |
# File 'lib/gooddata/rest/client.rb', line 182 def project_is_accessible?(id) GoodData.logger.warn 'Beware! project_is_accessible is deprecated and should not be used.' begin # rubocop:disable RedundantBegin TODO: remove this after droping JRuby which does not support rescue without begin projects(id) rescue RestClient::NotFound false end end |
#project_webdav_path(opts = { project: GoodData.project }) ⇒ Object
284 285 286 287 288 289 290 291 292 293 294 295 296 |
# File 'lib/gooddata/rest/client.rb', line 284 def project_webdav_path(opts = { project: GoodData.project }) p = opts[:project] fail ArgumentError, 'No :project specified' if p.nil? project = GoodData::Project[p, opts] fail ArgumentError, 'Wrong :project specified' if project.nil? url = project.links['uploads'] fail 'Project WebDAV not supported in this Data Center' unless url GoodData.logger.warn 'Beware! Project webdav is deprecated and should not be used.' url end |
#projects(id = :all, limit = nil, offset = nil) ⇒ Object
191 192 193 194 195 196 197 |
# File 'lib/gooddata/rest/client.rb', line 191 def projects(id = :all, limit = nil, offset = nil) if limit.nil? GoodData::Project[id, client: self] else GoodData::Project.all({ client: self }, limit, offset) end end |
#put(uri, data, opts = {}) ⇒ Object
HTTP PUT
366 367 368 |
# File 'lib/gooddata/rest/client.rb', line 366 def put(uri, data, opts = {}) @connection.put uri, data, opts.merge(stats_on: stats_on?) end |
#resource(res_name) ⇒ Object
Gets resource by name
238 239 240 241 |
# File 'lib/gooddata/rest/client.rb', line 238 def resource(res_name) GoodData.logger.info("Getting resource '#{res_name}'") nil end |
#stats_off ⇒ Object
251 252 253 |
# File 'lib/gooddata/rest/client.rb', line 251 def stats_off @stats = false end |
#stats_on ⇒ Object
255 256 257 |
# File 'lib/gooddata/rest/client.rb', line 255 def stats_on @stats = true end |
#stats_on? ⇒ Boolean
259 260 261 |
# File 'lib/gooddata/rest/client.rb', line 259 def stats_on? @stats end |
#upload(file, options = {}) ⇒ Object
Uploads file to staging
381 382 383 |
# File 'lib/gooddata/rest/client.rb', line 381 def upload(file, = {}) @connection.upload file, end |
#upload_to_user_webdav(file, options = {}) ⇒ Object
399 400 401 402 |
# File 'lib/gooddata/rest/client.rb', line 399 def upload_to_user_webdav(file, = {}) upload(file, .merge(:directory => [:directory], :staging_url => user_webdav_path)) end |
#user(id = nil) ⇒ Object
243 244 245 246 247 248 249 |
# File 'lib/gooddata/rest/client.rb', line 243 def user(id = nil) if id create(GoodData::Profile, get(id)) else create(GoodData::Profile, @connection.user) end end |
#user_webdav_path ⇒ Object
298 299 300 301 302 303 304 305 306 |
# File 'lib/gooddata/rest/client.rb', line 298 def user_webdav_path uri = if opts[:webdav_server] opts[:webdav_server] else links.find { |i| i['category'] == 'uploads' }['link'] end res = uri.chomp('/') + '/' res[0] == '/' ? "#{connection.server}#{res}" : res end |
#warehouses(id = :all) ⇒ Object
218 219 220 |
# File 'lib/gooddata/rest/client.rb', line 218 def warehouses(id = :all) GoodData::DataWarehouse[id, client: self] end |
#with_project(pid, &block) ⇒ Object
404 405 406 |
# File 'lib/gooddata/rest/client.rb', line 404 def with_project(pid, &block) GoodData.with_project(pid, client: self, &block) end |