-
Notifications
You must be signed in to change notification settings - Fork 11
/
jira.rb
169 lines (138 loc) · 5.03 KB
/
jira.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
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
123
124
125
126
127
128
129
130
131
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
require "perfect_retry"
require "embulk/input/jira_input_plugin_utils"
require "embulk/input/jira_api"
module Embulk
module Input
class Jira < InputPlugin
PER_PAGE = 50
GUESS_RECORDS_COUNT = 10
PREVIEW_RECORDS_COUNT = 15
Plugin.register_input("jira", self)
def self.transaction(config, &control)
task = {
username: config.param(:username, :string),
password: config.param(:password, :string),
uri: config.param(:uri, :string),
jql: config.param(:jql, :string),
}
attributes = {}
columns = config.param(:columns, :array).map do |column|
name = column["name"]
type = column["type"].to_sym
attributes[name] = type
Column.new(nil, name, type, column["format"])
end
task[:attributes] = attributes
task[:retry_limit] = config.param(:retry_limit, :integer, default: 5)
task[:retry_initial_wait_sec] = config.param(:retry_initial_wait_sec, :integer, default: 1)
resume(task, columns, 1, &control)
end
def self.resume(task, columns, count, &control)
task_reports = yield(task, columns, count)
next_config_diff = {}
return next_config_diff
end
def self.guess(config)
username = config.param(:username, :string)
password = config.param(:password, :string)
uri = config.param(:uri, :string)
jql = config.param(:jql, :string)
jira = JiraApi::Client.setup do |jira_config|
# TODO: api_version should be 2 (the latest version)
# auth_type should be specified from config. (The future task)
jira_config.username = username
jira_config.password = password
jira_config.uri = uri
jira_config.api_version = "latest"
jira_config.auth_type = "basic"
end
retry_limit = config.param(:retry_limit, :integer, default: 5)
retry_initial_wait_sec = config.param(:retry_initial_wait_sec, :integer, default: 1)
retryer = retryer(retry_limit, retry_initial_wait_sec)
# Get credential before going to search issue
jira.check_user_credential(username)
# TODO: we use 0..10 issues to guess config?
records = retryer.with_retry do
jira.search_issues(jql, max_results: GUESS_RECORDS_COUNT).map do |issue|
issue.to_record
end
end
columns = JiraInputPluginUtils.guess_columns(records)
guessed_config = {
"columns" => columns,
}
return guessed_config
end
def init
@attributes = task[:attributes]
@jira = JiraApi::Client.setup do |config|
config.username = task[:username]
config.password = task[:password]
config.uri = task[:uri]
config.api_version = "latest"
config.auth_type = "basic"
end
@jql = task[:jql]
@retryer = self.class.retryer(task[:retry_limit], task[:retry_initial_wait_sec])
end
def run
return preview if preview?
@jira.check_user_credential(task[:username])
options = {}
total_count = @jira.total_count(@jql)
last_page = (total_count.to_f / PER_PAGE).ceil
0.step(total_count, PER_PAGE).with_index(1) do |start_at, page|
logger.debug "Fetching #{page} / #{last_page} page"
@retryer.with_retry do
@jira.search_issues(@jql, options.merge(start_at: start_at)).each do |issue|
values = @attributes.map do |(attribute_name, type)|
JiraInputPluginUtils.cast(issue[attribute_name], type)
end
page_builder.add(values)
end
end
end
page_builder.finish
task_report = {}
return task_report
end
def self.logger
Embulk.logger
end
def self.retryer(limit, initial_wait)
PerfectRetry.new do |config|
config.limit = limit
config.sleep = proc{|n| initial_wait + (2 ** n)}
config.dont_rescues = [Embulk::ConfigError, Embulk::DataError]
config.logger = Embulk.logger
config.log_level = nil
end
end
def logger
self.class.logger
end
private
def preview
@jira.check_user_credential(task[:username])
logger.debug "For preview mode, JIRA input plugin fetches records at most #{PREVIEW_RECORDS_COUNT}"
@jira.search_issues(@jql, max_results: PREVIEW_RECORDS_COUNT).each do |issue|
values = @attributes.map do |(attribute_name, type)|
JiraInputPluginUtils.cast(issue[attribute_name], type)
end
page_builder.add(values)
end
page_builder.finish
task_report = {}
return task_report
end
def preview?
begin
# http://www.embulk.org/docs/release/release-0.6.12.html
org.embulk.spi.Exec.isPreview()
rescue java.lang.NullPointerException => e
false
end
end
end
end
end