Class: GoodData::BlobStorageClient

Inherits:
Object
  • Object
show all
Defined in:
lib/gooddata/cloud_resources/blobstorage/blobstorage_client.rb

Constant Summary collapse

SAS_URL_PATTERN =
%r{(^https?:\/\/[^\/]*)\/.*\?(.*)}
INVALID_BLOB_GENERAL_MESSAGE =
"The connection string is not valid."
INVALID_BLOB_SIG_WELL_FORMED_MESSAGE =
"The signature format is not valid."
INVALID_BLOB_CONTAINER_MESSAGE =
"ContainerNotFound"
INVALID_BLOB_CONTAINER_FORMED_MESSAGE =
"The container with the specified name is not found."
INVALID_BLOB_EXPIRED_ORIGINAL_MESSAGE =
"Signature not valid in the specified time frame"
INVALID_BLOB_EXPIRED_MESSAGE =
"The signature expired."
INVALID_BLOB_INVALID_CONNECTION_STRING_MESSAGE =
"The connection string is not valid."
INVALID_BLOB_PATH_MESSAGE =
"BlobNotFound"
INVALID_BLOB_INVALID_PATH_MESSAGE =
"The path to the data is not found."

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ BlobStorageClient

Returns a new instance of BlobStorageClient.



27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/gooddata/cloud_resources/blobstorage/blobstorage_client.rb', line 27

def initialize(options = {})
  raise("Data Source needs a client to Blob Storage to be able to get blob file but 'blobStorage_client' is empty.") unless options['blobStorage_client']

  if options['blobStorage_client']['connectionString'] && options['blobStorage_client']['container']
    @connection_string = options['blobStorage_client']['connectionString']
    @container = options['blobStorage_client']['container']
    @path = options['blobStorage_client']['path']
    @use_sas = false
    build_sas(@connection_string)
  else
    raise('Missing connection info for Blob Storage client')
  end
end

Instance Attribute Details

#use_sasObject (readonly)

Returns the value of attribute use_sas.



25
26
27
# File 'lib/gooddata/cloud_resources/blobstorage/blobstorage_client.rb', line 25

def use_sas
  @use_sas
end

Instance Method Details

#build_sas(url) ⇒ Object



69
70
71
72
73
74
75
76
# File 'lib/gooddata/cloud_resources/blobstorage/blobstorage_client.rb', line 69

def build_sas(url)
  matches = url.scan(SAS_URL_PATTERN)
  return unless matches && matches[0]

  @use_sas = true
  @host = matches[0][0]
  @sas_token = matches[0][1]
end

#connectObject



60
61
62
63
64
65
66
67
# File 'lib/gooddata/cloud_resources/blobstorage/blobstorage_client.rb', line 60

def connect
  GoodData.logger.info "Setting up connection to Blob Storage"
  if use_sas
    @client = Azure::Storage::Blob::BlobService.create(:storage_blob_host => @host, :storage_sas_token => @sas_token)
  else
    @client = Azure::Storage::Blob::BlobService.create_from_connection_string(@connection_string)
  end
end

#get_blob_name(path, file) ⇒ Object



92
93
94
95
96
# File 'lib/gooddata/cloud_resources/blobstorage/blobstorage_client.rb', line 92

def get_blob_name(path, file)
  return file unless path

  path.rindex('/') == path.length - 1 ? "#{path}#{file}" : "#{path}/#{file}"
end

#raise_error(e) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/gooddata/cloud_resources/blobstorage/blobstorage_client.rb', line 78

def raise_error(e)
  if e.message && e.message.include?(INVALID_BLOB_EXPIRED_ORIGINAL_MESSAGE)
    raise INVALID_BLOB_EXPIRED_MESSAGE
  elsif e.message && e.message.include?(INVALID_BLOB_SIG_WELL_FORMED_MESSAGE)
    raise INVALID_BLOB_SIG_WELL_FORMED_MESSAGE
  elsif e.message && e.message.include?(INVALID_BLOB_CONTAINER_MESSAGE)
    raise INVALID_BLOB_CONTAINER_FORMED_MESSAGE
  elsif e.message && e.message.include?(INVALID_BLOB_PATH_MESSAGE)
    raise INVALID_BLOB_INVALID_PATH_MESSAGE
  else
    raise INVALID_BLOB_GENERAL_MESSAGE
  end
end

#realize_blob(file, _params) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/gooddata/cloud_resources/blobstorage/blobstorage_client.rb', line 41

def realize_blob(file, _params)
  GoodData.gd_logger.info("Realizing download from Blob Storage. Container #{@container}.")
  filename = ''
  begin
    connect
    filename = "#{SecureRandom.urlsafe_base64(6)}_#{Time.now.to_i}.csv"
    blob_name = get_blob_name(@path, file)

    measure = Benchmark.measure do
      _blob, content = @client.get_blob(@container, blob_name)
      File.open(filename, "wb") { |f| f.write(content) }
    end
  rescue  => e
    raise_error(e)
  end
  GoodData.gd_logger.info("Done downloading file type=blobStorage status=finished duration=#{measure.real}")
  filename
end