zuora_api 1.3.2 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c55ec215788feb32e23a15d1b184106afede1d1d
4
- data.tar.gz: e0735b673b4d2809d9382fadb6072e8c37d89351
3
+ metadata.gz: d92c60b9da5b74041b862fdd2af9194efaf4d9fd
4
+ data.tar.gz: 56465882c0f981d112eaa407ddff336a2ac9b2f8
5
5
  SHA512:
6
- metadata.gz: 02fba7b0de2e9ff2e58bbc247726e6c3b60ce5a483a99d0a0c9aebb36b2e741c33370a1f59bd5e6a33224753a8e990533b45a2812bfe220077789a51a0e62c93
7
- data.tar.gz: e893da8fd4cf5f9fb04934f2d8181058b94107adee328bee74e8372f694685c888d8b14e09b0751dc3ed1a5e9fcb5fe5c58d988d4ec60cb0e839deda9facc7cf
6
+ metadata.gz: aba52fda66bbb00072045a19d1ec30d534c7544e50395afef39c48a0ea1fb146a3939a14bf2bf97dc258542b7a84df008965a35e68e82470f18fd1aeb68ec995
7
+ data.tar.gz: 99bb1f0be83771d07212c1d7dfd25a3dcd517c01f9b1a06fc5d962415e1ae2be834bd2bdba1d8c8a06e07069e141046243ede52d735c1cbce6670770daaef4f2
data/README.md CHANGED
@@ -101,7 +101,47 @@ response = zuora_client.describe_call()
101
101
  ```
102
102
 
103
103
  ### Journal Run
104
-
105
104
  ```ruby
106
105
  zuora_client.createJournalRun(call)
107
106
  ```
107
+
108
+ ## Insights API
109
+
110
+ In order to make API calls a Zuora Login object must be created by running:
111
+
112
+ ```ruby
113
+ insightsapi = InsightsAPI::Login.new(api_token: "api token", url: "Nw1.api.insights.zuora.com/api/")
114
+ ```
115
+
116
+ Note that the login will default to the insights production url.
117
+
118
+ ```ruby
119
+ Date format: "YYYY-MM-DDT00:00:00Z"
120
+ ```
121
+
122
+ ### Uploading Data into Insights
123
+ ```ruby
124
+ insightsapi.upload_into_insights(dataSourceName, recordType, batchDate, filePath)
125
+ ```
126
+ dataSourceName: What system the data is coming from.
127
+ recordType: The type of records ie: "EVENTS, ATTRIBUTES, and METRICS"
128
+ batachDate: The date the data applies to.
129
+
130
+ ### Describing Insights Data
131
+ ```ruby
132
+ insightsapi.describe(type: "ACCOUNT/USER", object: "ATTRIBUTES/EVENTS/SEGMENTS/METRICS")
133
+ ```
134
+ Returns json payload describing attributes, events, metrics for each Account or User.
135
+
136
+ ### Downloading Data from Insights
137
+ ```ruby
138
+ insightsapi.data_export_insights(objecttype, segmentuuid, startDate: nil, endDate: nil, tries: 30)
139
+ ```
140
+ ```ruby
141
+ insightsapi.data_export_insights_file(objecttype, segmentuuid, startDate: nil, endDate: nil, tries: 30)
142
+ ```
143
+ Both do the same thing except one returns a url(data_export_insights) to download the file yourself and the other returns an actual Ruby temporary file(data_export_insights_file).
144
+
145
+ objectype: "ACCOUNT/USER"
146
+
147
+ segmentuuid: A single or array of string or int of a segment uuid(s) that you get from the describe call. The csv holds a column with a bool that represents if that User or Account belongs to that segment.
@@ -0,0 +1,213 @@
1
+ require "httparty"
2
+ require "zip"
3
+ module InsightsAPI
4
+ class Login
5
+ attr_accessor :api_token, :url
6
+
7
+ def initialize(api_token: nil, url: "Nw1.api.insights.zuora.com/api/", **keyword_args)
8
+ @api_token = api_token
9
+ @url = url
10
+ end
11
+
12
+ def insight_getstatus(uuid)
13
+ response = HTTParty.get(
14
+ "https://#{@url}/export/status/#{uuid}",
15
+ :basic_auth => { :username => @api_token })
16
+ if response.code == 200
17
+ parsed = JSON.parse(response.body)
18
+ return parsed
19
+ #error handing here
20
+ end
21
+ end
22
+
23
+ def data_export_insights_file(objecttype, segmentuuid, startDate: nil, endDate: nil, tries: 30)
24
+ status = data_export_insights(objecttype, segmentuuid, startDate, endDate, tries: 30)
25
+ if status['status']== "COMPLETE"
26
+ signedUrl = status['signedUrl']
27
+ return get_file(file_name: "insights-#{startDate}-#{endDate}.csv", url: signedUrl, headers: {}, count: 3, file_type: "zip")
28
+ else
29
+ return status
30
+ end
31
+ end
32
+
33
+ def data_export_insights(objecttype, segmentuuid, startDate: nil, endDate: nil, tries: 30)
34
+ status = insights_fetch_all(objecttype, segmentuuid, startDate, endDate)
35
+ if status['uuid'] == nil
36
+ return "Failed: #{status["response"]}"
37
+ else
38
+ fileid = status['uuid']
39
+ end
40
+ for retries in 1..tries
41
+ status = insight_getstatus(fileid)
42
+ if status['status']== "COMPLETE"
43
+ signedUrl = status['signedUrl']
44
+ return status
45
+ elsif status['status'] == "FAILED"
46
+ return status
47
+ else
48
+ sleep(60)
49
+ retries+=1
50
+ end
51
+ if retries > tries - 1
52
+ return "Timeout"
53
+ end
54
+ end
55
+ return signedUrl
56
+ end
57
+
58
+ def insights_fetch_all(objecttype, segmentuuid, startDate, endDate)
59
+ if segmentuuid.is_a? Array
60
+ segmentsForAPI = segmentuuid.join('","')
61
+ elsif segmentuuid.is_a? String
62
+ segmentsForAPI = segmentuuid
63
+ elsif segmentuuid.is_a? Integer
64
+ segmentsForAPI = segmentuuid.to_s
65
+ else
66
+ raise "Error fetching Insights data: Segmentuuid must be either an array of uuids or an single uuid in string or interger format."
67
+ end
68
+
69
+ response = HTTParty.post(
70
+ "https://#{@url}/export/type/#{objecttype}",
71
+ :basic_auth => { :username => @api_token },
72
+ :headers => {'Content-Type'=> "Application/json"},
73
+ :body =>
74
+ '
75
+ {
76
+ "endDate": "' + (dateFormat(date: endDate)).to_s + '",
77
+ "startDate":"' + (dateFormat(date: startDate)).to_s + '",
78
+ "segments": [
79
+ "'+segmentsForAPI+'"
80
+ ]
81
+ }
82
+ ')
83
+ if response.code == 200
84
+ parsed = JSON.parse(response.body)
85
+ return parsed
86
+ else
87
+ return {"uuid"=> nil, "status"=>"Error", "signedUrl"=>"signedUrl", "response" => response.body}
88
+ end
89
+ end
90
+
91
+ def dateFormat(date: nil)
92
+ date ||= DateTime.now
93
+ return (date.to_date).to_s
94
+ end
95
+
96
+ def upload_into_insights(dataSourceName, recordType, batchDate, filePath)
97
+ begin
98
+ response = HTTParty.post(
99
+ "https://#{@url}/files/upload",
100
+ :basic_auth => { :username => @api_token }, :body => {
101
+ :dataSource => dataSourceName, :recordType => recordType,
102
+ :batchDate => dateFormat(date: batchDate) + "T00:00:00Z"})
103
+ parsed = JSON.parse(response.body)
104
+ signedUrl = parsed['signedUrl']
105
+ if !File.extname(filePath) == ".gz"
106
+ zipPath = gzip_file(filePath)
107
+ else
108
+ zipPath = filePath
109
+ end
110
+
111
+ gzippedFile = File.open(zipPath)
112
+ post = HTTParty.put(signedUrl,
113
+ :body => gzippedFile.read)
114
+ if post.code == 200
115
+ return {"status"=>"COMPLETE", "signedUrl"=>"signedUrl", "response" => post.code}
116
+ else
117
+ return {"status"=>"Error", "signedUrl"=>"signedUrl", "response" => post.code}
118
+ end
119
+ rescue Exception => e
120
+ Rails.logger.debug "[ZuoraGem]: While uploading to insights Error: #{e}"
121
+ raise e
122
+ end
123
+ end
124
+
125
+ def describe(type: "ACCOUNT", object: "attributes")
126
+ url = "https://#{@url}/export/#{object}/#{type}"
127
+ uri = URI.parse(url)
128
+ http = Net::HTTP.new(uri.host, uri.port)
129
+ http.use_ssl = true
130
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
131
+ begin
132
+ request = Net::HTTP::Get.new(uri.request_uri)
133
+
134
+ request.basic_auth(@api_token, "")
135
+
136
+ if request.code == '200'
137
+ return http.request(request)
138
+ else
139
+ return "Failed"
140
+ end
141
+ rescue Exception => e
142
+ Rails.logger.debug "[ZuoraGem]: While describing Zoura Insights objects: #{e}"
143
+ return "Failed"
144
+ end
145
+ end
146
+
147
+ def get_file(file_name: nil, url: nil, basic: {:username => nil, :password => nil}, headers: {}, count: 3, file_type: "zip")
148
+ tries ||= 2
149
+ temp_file = nil
150
+ uri = URI(url)
151
+ Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
152
+ request = Net::HTTP::Get.new(uri)
153
+ headers.each do |k,v|
154
+ request["#{k}"] = v
155
+ end
156
+ request.basic_auth(basic[:username], basic[:password]) if (!basic[:username].blank? && !basic[:password].blank?)
157
+ http.request request do |response|
158
+ case response
159
+ when Net::HTTPNotFound
160
+ Rails.logger.fatal("[ZuoraGem]: 404 - Not Found")
161
+ raise response
162
+
163
+ when Net::HTTPUnauthorized
164
+ raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(zuora_client.current_error) if count <= 0
165
+ Rails.logger.fatal("[ZuoraGem]: Retry")
166
+ zuora_client.new_session
167
+ return get_file(:url => url, :count => count - 1, :headers => headers)
168
+
169
+ when Net::HTTPClientError
170
+ Rails.logger.debug("[ZuoraGem]: #{response}")
171
+ raise response
172
+
173
+ when Net::HTTPOK
174
+ Tempfile.open([file_name.rpartition('.').first, ".#{file_name.rpartition('.').last}"], "#{Rails.root}/tmp") do |tmp_file|
175
+ temp_file ||= tmp_file
176
+ tmp_file.binmode if (response.to_hash["content-type"].include?("application/zip") || response.to_hash["content-type"] == "application/zip")
177
+ response.read_body do |chunk|
178
+ tmp_file.write chunk.force_encoding("UTF-8")
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
184
+
185
+ rescue => ex
186
+ if !(tries -= 1).zero?
187
+ sleep 3
188
+ retry
189
+ else
190
+ raise ex
191
+ end
192
+ else
193
+ return temp_file
194
+ end
195
+
196
+ def gzip_file(filePath)
197
+ Zlib::GzipWriter.open(filePath + ".gz") do |gzip|
198
+ open(filePath, "rb") do |f|
199
+ f.each_chunk() {|chunk| gzip.write chunk }
200
+ end
201
+ gzip.close
202
+ end
203
+ return filePath+ ".gz"
204
+ end
205
+
206
+ end
207
+ end
208
+
209
+ class File
210
+ def each_chunk(chunk_size=2**16)
211
+ yield read(chunk_size) until eof?
212
+ end
213
+ end
@@ -2,6 +2,7 @@ require 'rails'
2
2
 
3
3
  require "zuora_api/login"
4
4
  require 'zuora_api/exceptions'
5
+ require "insights_api/login"
5
6
  module ZuoraAPI
6
7
  # Your code goes here...
7
8
  end
@@ -366,7 +366,7 @@ module ZuoraAPI
366
366
  end
367
367
 
368
368
  def get_catalog
369
- products, response = [{}, {'nextPage' => self.rest_endpoint('catalog/products?pageSize=40') }]
369
+ products, catalog_map, response = [{}, {}, {'nextPage' => self.rest_endpoint('catalog/products?pageSize=40') }]
370
370
  while !response["nextPage"].blank?
371
371
  url = self.rest_endpoint(response["nextPage"].split('/v1/').last)
372
372
  Rails.logger.debug("Fetch Catalog URL #{url}")
@@ -375,12 +375,18 @@ module ZuoraAPI
375
375
  raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Error Getting Catalog: #{output_json}")
376
376
  end
377
377
  output_json["products"].each do |product|
378
+ catalog_map[product["id"]] = {"productId" => product["id"]}
378
379
  rateplans = {}
380
+
379
381
  product["productRatePlans"].each do |rateplan|
382
+ catalog_map[rateplan["id"]] = {"productId" => product["id"], "productRatePlanId" => rateplan["id"]}
380
383
  charges = {}
384
+
381
385
  rateplan["productRatePlanCharges"].each do |charge|
386
+ catalog_map[charge["id"]] = {"productId" => product["id"], "productRatePlanId" => rateplan["id"], "productRatePlanChargeId" => charge["id"], }
382
387
  charges[charge["id"]] = charge.merge({"productId" => product["id"], "productName" => product["name"], "productRatePlanId" => rateplan["id"], "productRatePlanName" => rateplan["name"] })
383
388
  end
389
+
384
390
  rateplan["productRatePlanCharges"] = charges
385
391
  rateplans[rateplan["id"]] = rateplan.merge({"productId" => product["id"], "productName" => product["name"]})
386
392
  end
@@ -388,7 +394,7 @@ module ZuoraAPI
388
394
  products[product['id']] = product
389
395
  end
390
396
  end
391
- return products
397
+ return products, catalog_map
392
398
  end
393
399
 
394
400
  def get_file(file_name: nil, url: nil, headers: {}, count: 3, file_type: "zip")
@@ -1,3 +1,3 @@
1
1
  module ZuoraAPI
2
- VERSION = "1.3.2"
2
+ VERSION = "1.3.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zuora_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.2
4
+ version: 1.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zuora Strategic Solutions Group
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-05-11 00:00:00.000000000 Z
11
+ date: 2017-05-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -131,6 +131,7 @@ files:
131
131
  - Rakefile
132
132
  - bin/console
133
133
  - bin/setup
134
+ - lib/insights_api/login.rb
134
135
  - lib/zuora_api.rb
135
136
  - lib/zuora_api/exceptions.rb
136
137
  - lib/zuora_api/login.rb