1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: Apache-2.0
5 require 'google/api_client'
6 # Monkeypatch google-api-client gem to avoid sending newline characters
7 # on headers to make ruby-2.3.7+ happy.
8 # See: https://dev.arvados.org/issues/13920
9 Google::APIClient::ENV::OS_VERSION.strip!
14 class Google::APIClient
15 def discovery_document(api, version)
17 discovery_uri = self.discovery_uri(api, version)
18 discovery_uri_hash = Digest::MD5.hexdigest(discovery_uri)
19 discovery_cache_path =
20 File.expand_path("~/.cache/arvados/discovery-#{discovery_uri_hash}.json")
21 @discovery_documents[discovery_uri_hash] ||=
22 disk_cached_discovery_document(discovery_cache_path) or
23 fetched_discovery_document(discovery_uri, discovery_cache_path)
28 def disk_cached_discovery_document(cache_path)
30 if (Time.now - File.mtime(cache_path)) < 86400
31 open(cache_path) do |cache_file|
32 return JSON.load(cache_file)
35 rescue IOError, SystemCallError, JSON::JSONError
36 # Error reading the cache. Act like it doesn't exist.
41 def write_cached_discovery_document(cache_path, body)
42 cache_dir = File.dirname(cache_path)
45 FileUtils.makedirs(cache_dir)
46 cache_file = Tempfile.new("discovery", cache_dir)
47 cache_file.write(body)
49 File.rename(cache_file.path, cache_path)
50 rescue IOError, SystemCallError
51 # Failure to write the cache is non-fatal. Do nothing.
53 cache_file.close! unless cache_file.nil?
57 def fetched_discovery_document(uri, cache_path)
58 response = self.execute!(:http_method => :get,
60 :authenticated => false)
61 write_cached_discovery_document(cache_path, response.body)
62 JSON.load(response.body)