ticket_abstractor_client 2.0.0 → 2.0.1
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 +4 -4
- data/README.md +74 -11
- data/lib/ticket_abstractor_client/base/attachment.rb +16 -4
- data/lib/ticket_abstractor_client/base/client.rb +3 -1
- data/lib/ticket_abstractor_client/base/comment.rb +10 -2
- data/lib/ticket_abstractor_client/base/ticket.rb +10 -9
- data/lib/ticket_abstractor_client/base/{fields_filter.rb → tickets_filter.rb} +4 -6
- data/lib/ticket_abstractor_client/client_helper.rb +1 -0
- data/lib/ticket_abstractor_client/configuration.rb +12 -12
- data/lib/ticket_abstractor_client/jira/ticket.rb +9 -9
- data/lib/ticket_abstractor_client/service_now/client.rb +23 -7
- data/lib/ticket_abstractor_client/service_now/comment.rb +2 -2
- data/lib/ticket_abstractor_client/service_now/params_builder.rb +6 -5
- data/lib/ticket_abstractor_client/service_now/ticket.rb +25 -16
- data/lib/ticket_abstractor_client/version.rb +1 -1
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 115d09ad3d18ed05d7d9bd31cd6bcf5f96f87a13
|
4
|
+
data.tar.gz: 4b9f066a917ec904c2ec00989cabf11c0b1d109d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 252d6de493963f80a6608c5288866a0e1490ba35e3582bc24d355992ffce225be53e34a4538a01251c120ce51e1e92a32ce2d4fe15bc2f2f793ffda54c5ba5e3
|
7
|
+
data.tar.gz: 948ace98118b77dd78f67aced69c995ddfa777a585c867fdad70c77af20b9fa2c8e7df56990cbddd537658e9506a56ab22662a567420509fe5cdf9a6e79f70f3
|
data/README.md
CHANGED
@@ -42,7 +42,7 @@ Since version 2.0.0, you operate with ticket as **PORO**.
|
|
42
42
|
|
43
43
|
**Base configuration options:**
|
44
44
|
|
45
|
-
TicketAbstractorClient.
|
45
|
+
TicketAbstractorClient.configure do |config|
|
46
46
|
config.ticket_abstractor_url = 'http://localhost:4567'
|
47
47
|
config.security_token = 'security_token_1'
|
48
48
|
end
|
@@ -75,7 +75,7 @@ this parameter defaults to false.
|
|
75
75
|
* `SNOW_DISPLAY_VALUE_ALL` returns both actual and display values.
|
76
76
|
|
77
77
|
|
78
|
-
|
78
|
+
config.snow_display_value = TicketAbstractorClient::Configuration::SNOW_DISPLAY_VALUE_ALL
|
79
79
|
|
80
80
|
[[table of contents](#content)]
|
81
81
|
|
@@ -165,6 +165,33 @@ Update ticket's status:
|
|
165
165
|
ticket.status = 'IN_PROGRESS'
|
166
166
|
ticket.sync!
|
167
167
|
|
168
|
+
Add comment:
|
169
|
+
|
170
|
+
include TicketAbstractorClient
|
171
|
+
...
|
172
|
+
|
173
|
+
ticket = Jira::Ticket.new(ticket_id: 'ISSUE-111', endpoint: 'tp')
|
174
|
+
ticket.add_comment(body: 'New comment body')
|
175
|
+
ticket.sync!
|
176
|
+
|
177
|
+
# or
|
178
|
+
|
179
|
+
Jira::Comment.new(ticket_id: 'ISSUE-111', endpoint: 'tp', body: 'New comment body').sync!
|
180
|
+
|
181
|
+
Add attachment:
|
182
|
+
|
183
|
+
include TicketAbstractorClient
|
184
|
+
...
|
185
|
+
|
186
|
+
ticket = Jira::Ticket.new(ticket_id: 'ISSUE-111', endpoint: 'tp')
|
187
|
+
ticket.add_attachment(file_attachment: '/path/to/file')
|
188
|
+
ticket.sync!
|
189
|
+
|
190
|
+
# or
|
191
|
+
|
192
|
+
Jira::Attachment.new(ticket_id: 'ISSUE-111', endpoint: 'tp', file_attachment: '/path/to/file').sync!
|
193
|
+
|
194
|
+
|
168
195
|
### <a name="snow"></a>ServiceNow
|
169
196
|
|
170
197
|
Get ticket by id:
|
@@ -178,7 +205,7 @@ Get ticket by id:
|
|
178
205
|
|
179
206
|
Get tickets by query:
|
180
207
|
|
181
|
-
ticket_opts = {
|
208
|
+
ticket_opts = { sysparm_query: 'numberIN(INC001,INC002,INC010)', endpoint: :test, project: 'incident' }
|
182
209
|
TicketAbstractorClient::ServiceNow::Ticket.fetch_tickets_by_query(ticket_opts)
|
183
210
|
|
184
211
|
Get ticket's comments:
|
@@ -244,11 +271,47 @@ Update ticket:
|
|
244
271
|
|
245
272
|
Update ticket's status:
|
246
273
|
|
247
|
-
ticket_opts = { ticket_id: 'INC011', endpoint: '
|
274
|
+
ticket_opts = { ticket_id: 'INC011', endpoint: 'test', project: :incident }
|
248
275
|
ticket = TicketAbstractorClient::ServiceNow::Ticket.new(ticket_opts)
|
249
276
|
ticket.status = 'IN_PROGRESS'
|
250
277
|
ticket.sync!
|
251
278
|
|
279
|
+
Add comment:
|
280
|
+
|
281
|
+
include TicketAbstractorClient
|
282
|
+
...
|
283
|
+
|
284
|
+
ticket = ServiceNow::Ticket.new(ticket_id: 'INC011', endpoint: 'test', project: :incident)
|
285
|
+
ticket.add_comment(body: 'New comment body')
|
286
|
+
ticket.sync!
|
287
|
+
|
288
|
+
# or
|
289
|
+
|
290
|
+
ServiceNow::Comment.new(
|
291
|
+
ticket_id: 'INC011',
|
292
|
+
endpoint: 'test',
|
293
|
+
project: :incident,
|
294
|
+
body: 'New comment body'
|
295
|
+
).sync!
|
296
|
+
|
297
|
+
Add attachment:
|
298
|
+
|
299
|
+
include TicketAbstractorClient
|
300
|
+
...
|
301
|
+
|
302
|
+
ticket = ServiceNow::Ticket.new(ticket_id: 'INC011', endpoint: 'test', project: :incident)
|
303
|
+
ticket.add_attachment(file_attachment: '/path/to/file')
|
304
|
+
ticket.sync!
|
305
|
+
|
306
|
+
# or
|
307
|
+
|
308
|
+
ServiceNow::Attachment.new(
|
309
|
+
ticket_id: 'INC011',
|
310
|
+
endpoint: 'test',
|
311
|
+
project: :incident,
|
312
|
+
file_attachment: '/path/to/file'
|
313
|
+
).sync!
|
314
|
+
|
252
315
|
|
253
316
|
[[table of contents](#content)]
|
254
317
|
|
@@ -258,18 +321,18 @@ Update ticket's status:
|
|
258
321
|
|
259
322
|
There is a situation when you need to convert some values, like datetimes, or skip any other values and so on,
|
260
323
|
before you start working with fetched ticket.
|
261
|
-
All you have to do is create a class that is inherited from `TicketAbstractorClient::Base::
|
262
|
-
and implement a `
|
324
|
+
All you have to do is create a class that is inherited from `TicketAbstractorClient::Base::TicketsFilter`
|
325
|
+
and implement a `filter_ticket` method, after that configure the gem to use your class.
|
263
326
|
|
264
327
|
**ServiceNow example:**
|
265
328
|
|
266
|
-
class MyServiceNowTicketsFilter < TicketAbstractorClient::Base::
|
267
|
-
def initialize(
|
268
|
-
super(
|
329
|
+
class MyServiceNowTicketsFilter < TicketAbstractorClient::Base::TicketsFilter
|
330
|
+
def initialize(raw_ticket)
|
331
|
+
super(raw_ticket)
|
269
332
|
end
|
270
333
|
|
271
|
-
def
|
272
|
-
|
334
|
+
def filter_ticket
|
335
|
+
@ticket.fields.each_with_object([]) |raw_field, filtered_fields|
|
273
336
|
# do some filtering here
|
274
337
|
end
|
275
338
|
end
|
@@ -3,6 +3,9 @@ module TicketAbstractorClient
|
|
3
3
|
class Attachment
|
4
4
|
attr_reader :file_path, :data_hash, :external_created_at
|
5
5
|
|
6
|
+
# Carrierwave uses the same regexp
|
7
|
+
SANITIZE_REGEXP = /[^[:word:]\.\-\+]/
|
8
|
+
|
6
9
|
class << self
|
7
10
|
def fetch
|
8
11
|
method_not_implemented __method__
|
@@ -23,16 +26,17 @@ module TicketAbstractorClient
|
|
23
26
|
end
|
24
27
|
|
25
28
|
def set_original_name(filepath, original_name)
|
29
|
+
sanitized_name = original_name.gsub(SANITIZE_REGEXP, "_")
|
26
30
|
tmp_basename = File.basename(filepath)
|
27
31
|
tmp_path = filepath.gsub(tmp_basename, '')
|
28
|
-
FileUtils.mv
|
29
|
-
File.join(tmp_path,
|
32
|
+
FileUtils.mv(filepath, File.join(tmp_path, sanitized_name))
|
33
|
+
File.join(tmp_path, sanitized_name)
|
30
34
|
end
|
31
35
|
end
|
32
36
|
|
33
37
|
def initialize(opts)
|
34
38
|
@file_path = opts[:file_path]
|
35
|
-
@external_created_at = opts[:external_created_at]
|
39
|
+
@external_created_at = opts[:external_created_at]
|
36
40
|
@data_hash = opts[:data_hash]
|
37
41
|
set_data_hash! if @data_hash.blank?
|
38
42
|
end
|
@@ -44,9 +48,17 @@ module TicketAbstractorClient
|
|
44
48
|
def set_data_hash!
|
45
49
|
return if self.file_path.blank?
|
46
50
|
file = File.new(self.file_path, 'rb')
|
47
|
-
@data_hash = Digest::
|
51
|
+
@data_hash = Digest::SHA512.hexdigest(file.read)
|
48
52
|
file.close
|
49
53
|
end
|
54
|
+
|
55
|
+
def to_hash
|
56
|
+
{ file_path: @file_path, external_created_at: @external_created_at, data_hash: @data_hash }
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_json
|
60
|
+
self.to_hash.to_json
|
61
|
+
end
|
50
62
|
end
|
51
63
|
end
|
52
64
|
end
|
@@ -47,7 +47,9 @@ module TicketAbstractorClient
|
|
47
47
|
rescue Errno::ECONNREFUSED => exception
|
48
48
|
raise Errors::UnexpectedError, exception.message
|
49
49
|
rescue RestClient::Exception => exception
|
50
|
-
|
50
|
+
response_body = exception.response.body rescue exception.message
|
51
|
+
error_message = JSON.parse(response_body)['error'] rescue response_body
|
52
|
+
raise Errors::UnexpectedError, error_message
|
51
53
|
end
|
52
54
|
end
|
53
55
|
end
|
@@ -11,20 +11,28 @@ module TicketAbstractorClient
|
|
11
11
|
opts = opts.with_indifferent_access
|
12
12
|
@author = opts[:author]
|
13
13
|
@body = opts.fetch(:body, nil) || raise(Errors::CommentArgumentError, 'Body is not given')
|
14
|
-
@external_created_at = opts[:external_created_at]
|
14
|
+
@external_created_at = opts[:external_created_at]
|
15
15
|
@data_hash = opts[:data_hash]
|
16
16
|
set_data_hash! if @data_hash.blank?
|
17
17
|
end
|
18
18
|
|
19
19
|
def set_data_hash!
|
20
20
|
content = "#{@external_created_at}:#{@author}:#{@body}"
|
21
|
-
@data_hash = Digest::
|
21
|
+
@data_hash = Digest::SHA512.hexdigest(content)
|
22
22
|
end
|
23
23
|
|
24
24
|
def sync!
|
25
25
|
self.class.method_not_implemented __method__
|
26
26
|
end
|
27
27
|
|
28
|
+
def to_hash
|
29
|
+
{ author: @author, body: @body, external_created_at: @external_created_at, data_hash: @data_hash }
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_json
|
33
|
+
self.to_hash.to_json
|
34
|
+
end
|
35
|
+
|
28
36
|
protected
|
29
37
|
|
30
38
|
def self.method_not_implemented(method_name)
|
@@ -1,9 +1,8 @@
|
|
1
1
|
module TicketAbstractorClient
|
2
2
|
module Base
|
3
3
|
class Ticket
|
4
|
-
|
5
|
-
|
6
|
-
attr_accessor :ticket_id, :endpoint, :project
|
4
|
+
attr_reader :attachments, :comments, :changes, :status
|
5
|
+
attr_accessor :ticket_id, :endpoint, :project, :fields
|
7
6
|
|
8
7
|
def initialize(opts = {})
|
9
8
|
opts = opts.with_indifferent_access
|
@@ -11,6 +10,8 @@ module TicketAbstractorClient
|
|
11
10
|
@fields = opts.fetch(:fields, {}).with_indifferent_access
|
12
11
|
@endpoint = opts[:endpoint] || raise(Errors::TicketArgumentError, 'Endpoint is not given')
|
13
12
|
@project = opts[:project]
|
13
|
+
@attachments ||= []
|
14
|
+
@comments ||= []
|
14
15
|
initialize_changes!
|
15
16
|
mark_changes!
|
16
17
|
end
|
@@ -43,12 +44,12 @@ module TicketAbstractorClient
|
|
43
44
|
|
44
45
|
def to_hash
|
45
46
|
{
|
46
|
-
ticket_id:
|
47
|
-
status:
|
48
|
-
|
49
|
-
fields:
|
50
|
-
comments:
|
51
|
-
attachments:
|
47
|
+
ticket_id: self.ticket_id,
|
48
|
+
status: self.status,
|
49
|
+
updated_at: self.updated_at,
|
50
|
+
fields: self.fields,
|
51
|
+
comments: self.comments.map(&:to_hash),
|
52
|
+
attachments: self.attachments.map(&:to_hash)
|
52
53
|
}
|
53
54
|
end
|
54
55
|
|
@@ -1,13 +1,11 @@
|
|
1
1
|
module TicketAbstractorClient
|
2
2
|
module Base
|
3
|
-
class
|
4
|
-
|
5
|
-
|
6
|
-
def initialize(raw_fields)
|
7
|
-
@raw_fields = raw_fields
|
3
|
+
class TicketsFilter
|
4
|
+
def initialize(raw_ticket)
|
5
|
+
@ticket = raw_ticket
|
8
6
|
end
|
9
7
|
|
10
|
-
def
|
8
|
+
def filter_ticket
|
11
9
|
raise Errors::NotImplementedError, "#{self}##{__method__} is not implemented"
|
12
10
|
end
|
13
11
|
end
|
@@ -15,14 +15,14 @@ module TicketAbstractorClient
|
|
15
15
|
|
16
16
|
DEFAULT_SSL_OPTIONS = { verify_ssl: true }.freeze
|
17
17
|
|
18
|
-
def
|
19
|
-
@
|
18
|
+
def jira_tickets_filter_class
|
19
|
+
@jira_tickets_filter_class.presence
|
20
20
|
end
|
21
21
|
|
22
|
-
def
|
23
|
-
raise_configuration_error(
|
22
|
+
def jira_tickets_filter_class=(filter_class)
|
23
|
+
raise_configuration_error(filter_class) unless filter_class < Base::TicketsFilter
|
24
24
|
|
25
|
-
@
|
25
|
+
@jira_tickets_filter_class = filter_class
|
26
26
|
end
|
27
27
|
|
28
28
|
def jira_fields_meta
|
@@ -37,14 +37,14 @@ module TicketAbstractorClient
|
|
37
37
|
@snow_display_value ||= DEFAULT_SNOW_DISPLAY_VALUE
|
38
38
|
end
|
39
39
|
|
40
|
-
def
|
41
|
-
@
|
40
|
+
def snow_tickets_filter_class
|
41
|
+
@snow_tickets_filter_class.presence
|
42
42
|
end
|
43
43
|
|
44
|
-
def
|
45
|
-
raise_configuration_error(
|
44
|
+
def snow_tickets_filter_class=(filter_class)
|
45
|
+
raise_configuration_error(filter_class) unless filter_class < Base::TicketsFilter
|
46
46
|
|
47
|
-
@
|
47
|
+
@snow_tickets_filter_class = filter_class
|
48
48
|
end
|
49
49
|
|
50
50
|
def ssl_options
|
@@ -53,8 +53,8 @@ module TicketAbstractorClient
|
|
53
53
|
|
54
54
|
private
|
55
55
|
|
56
|
-
def raise_configuration_error(
|
57
|
-
message = "Filter class '#{
|
56
|
+
def raise_configuration_error(filter_class)
|
57
|
+
message = "Filter class '#{filter_class.to_s}' isn't a subclass of Base::TicketsFilter"
|
58
58
|
raise Base::Errors::ConfigurationError, message
|
59
59
|
end
|
60
60
|
end
|
@@ -88,20 +88,20 @@ module TicketAbstractorClient
|
|
88
88
|
raw_tickets = raw_tickets['issues'] if raw_tickets.key?('issues')
|
89
89
|
|
90
90
|
Array.wrap(raw_tickets).map do |raw_ticket|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
91
|
+
ticket = new(ticket_id: raw_ticket['key'], endpoint: endpoint, fields: raw_ticket['fields'])
|
92
|
+
filtered_ticket = filter_ticket(ticket)
|
93
|
+
filtered_ticket.reset_changes!
|
94
|
+
filtered_ticket
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
|
-
def self.
|
99
|
-
fields.extract!('attachment', 'comment')
|
100
|
-
|
98
|
+
def self.filter_ticket(raw_ticket)
|
99
|
+
raw_ticket.fields.extract!('attachment', 'comment')
|
100
|
+
tickets_filter_class = TicketAbstractorClient.configuration.jira_tickets_filter_class
|
101
101
|
|
102
|
-
return
|
102
|
+
return raw_ticket if tickets_filter_class.blank?
|
103
103
|
|
104
|
-
|
104
|
+
tickets_filter_class.new(raw_ticket).filter_ticket
|
105
105
|
end
|
106
106
|
|
107
107
|
def create_ticket
|
@@ -19,19 +19,30 @@ module TicketAbstractorClient
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def get_comments(opts)
|
22
|
-
opts[:
|
23
|
-
opts[:
|
22
|
+
opts[:table_name] = opts[:project]
|
23
|
+
opts[:sys_id] = get_ticket_sys_id(opts)
|
24
|
+
opts[:display_value] = TicketAbstractorClient.configuration.snow_display_value if opts[:display_value].nil?
|
24
25
|
get(__method__, opts)
|
25
26
|
end
|
26
27
|
|
28
|
+
def endpoints
|
29
|
+
get(__method__)
|
30
|
+
end
|
31
|
+
|
27
32
|
def get_ticket_by_id(opts)
|
28
|
-
opts[:
|
29
|
-
opts[:
|
33
|
+
opts[:table_name] = opts[:project]
|
34
|
+
opts[:sys_id] = get_ticket_sys_id(opts)
|
35
|
+
opts[:display_value] = TicketAbstractorClient.configuration.snow_display_value if opts[:display_value].nil?
|
30
36
|
get(__method__, opts)
|
31
37
|
end
|
32
38
|
|
33
39
|
def get_tickets_by_query(opts)
|
34
|
-
opts[:
|
40
|
+
opts[:table_name] = opts[:project]
|
41
|
+
opts[:display_value] = TicketAbstractorClient.configuration.snow_display_value if opts[:display_value].nil?
|
42
|
+
get(__method__, opts)
|
43
|
+
end
|
44
|
+
|
45
|
+
def get_users(opts)
|
35
46
|
get(__method__, opts)
|
36
47
|
end
|
37
48
|
|
@@ -50,11 +61,12 @@ module TicketAbstractorClient
|
|
50
61
|
end
|
51
62
|
|
52
63
|
def update_ticket(ticket)
|
53
|
-
ticket.
|
64
|
+
ticket.sys_id = get_ticket_sys_id(ticket_id: ticket.ticket_id, table_name: ticket.project)
|
54
65
|
post(__method__, build_ticket_params(ticket))
|
55
66
|
end
|
56
67
|
|
57
68
|
def update_ticket_status(ticket)
|
69
|
+
ticket.sys_id = get_ticket_sys_id(ticket_id: ticket.ticket.id, table_name: ticket.project)
|
58
70
|
post(:update_ticket, build_status_params(ticket))
|
59
71
|
end
|
60
72
|
|
@@ -63,7 +75,11 @@ module TicketAbstractorClient
|
|
63
75
|
def get_ticket_sys_id(opts)
|
64
76
|
return opts[:ticket_id] if opts[:ticket_id].length == SYS_ID_LENGTH
|
65
77
|
|
66
|
-
get(__method__, opts)
|
78
|
+
response = get(__method__, opts)
|
79
|
+
|
80
|
+
raise(Errors::NotFoundError, 'Ticket not found or incorrect ID given') if response.blank?
|
81
|
+
|
82
|
+
response[0]['sys_id']
|
67
83
|
end
|
68
84
|
|
69
85
|
def get(path, args = {}, params = {})
|
@@ -4,10 +4,10 @@ module TicketAbstractorClient
|
|
4
4
|
attr_accessor :ticket_id, :endpoint, :project
|
5
5
|
|
6
6
|
def self.fetch(ticket_id, endpoint, project)
|
7
|
-
response = Client.new(endpoint).get_comments(ticket_id: ticket_id,
|
7
|
+
response = Client.new(endpoint).get_comments(ticket_id: ticket_id, project: project)
|
8
8
|
response.map do |raw_comment|
|
9
9
|
new({
|
10
|
-
author: raw_comment['
|
10
|
+
author: raw_comment['sys_created_by'],
|
11
11
|
body: raw_comment['value'],
|
12
12
|
external_created_at: raw_comment['sys_created_on'],
|
13
13
|
ticket_id: ticket_id,
|
@@ -3,11 +3,12 @@ module TicketAbstractorClient
|
|
3
3
|
module ParamsBuilder
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
|
-
def
|
6
|
+
def build_all_tickets_params(opts)
|
7
|
+
opts[:table_name] = opts[:project]
|
7
8
|
opts[:sysparm_query] = build_sysparm_query(opts)
|
8
9
|
opts[:sysparm_fields] = Array.wrap(opts.delete(:fields))
|
9
10
|
opts.except!(:service_desk, :states)
|
10
|
-
opts[:display_value]
|
11
|
+
opts[:display_value] = TicketAbstractorClient.configuration.snow_display_value if opts[:display_value].nil?
|
11
12
|
opts
|
12
13
|
end
|
13
14
|
|
@@ -27,19 +28,19 @@ module TicketAbstractorClient
|
|
27
28
|
def build_comment_params(comment)
|
28
29
|
{
|
29
30
|
comment_params: { comments: comment.body },
|
30
|
-
|
31
|
+
sys_id: comment.ticket_id,
|
31
32
|
table_name: comment.project,
|
32
33
|
display_value: TicketAbstractorClient.configuration.snow_display_value
|
33
34
|
}
|
34
35
|
end
|
35
36
|
|
36
37
|
def build_status_params(ticket)
|
37
|
-
{ ticket_params: { state: ticket.status },
|
38
|
+
{ ticket_params: { state: ticket.status }, sys_id: ticket.sys_id, table_name: ticket.project }
|
38
39
|
end
|
39
40
|
|
40
41
|
def build_ticket_params(ticket)
|
41
42
|
opts = { ticket_params: ticket.fields, table_name: ticket.project }
|
42
|
-
opts.merge!(
|
43
|
+
opts.merge!(sys_id: ticket.sys_id) if ticket.sys_id.present?
|
43
44
|
opts
|
44
45
|
end
|
45
46
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module TicketAbstractorClient
|
2
2
|
module ServiceNow
|
3
3
|
class Ticket < Base::Ticket
|
4
|
+
attr_accessor :sys_id
|
4
5
|
|
5
6
|
def self.fetch_by_id(opts)
|
6
7
|
fetch(:by_id, opts).first
|
@@ -17,17 +18,18 @@ module TicketAbstractorClient
|
|
17
18
|
def initialize(opts = {})
|
18
19
|
super(opts)
|
19
20
|
@project = opts[:project] || raise(Errors::TicketArgumentError, 'Project is not given')
|
20
|
-
@
|
21
|
+
@sys_id = @fields['sys_id']
|
22
|
+
@status = @fields['state']
|
21
23
|
end
|
22
24
|
|
23
25
|
def add_attachment(attachment)
|
24
|
-
@attachments << Attachment.new(attachment.merge
|
26
|
+
@attachments << Attachment.new(attachment.merge(ticket_id: @ticket_id, endpoint: @endpoint, project: @project))
|
25
27
|
@changes[:new_attachments] += 1
|
26
28
|
self
|
27
29
|
end
|
28
30
|
|
29
31
|
def add_comment(comment)
|
30
|
-
@comments << Comment.new(comment.merge
|
32
|
+
@comments << Comment.new(comment.merge(ticket_id: @ticket_id, endpoint: @endpoint, project: @project))
|
31
33
|
@changes[:new_comments] += 1
|
32
34
|
self
|
33
35
|
end
|
@@ -37,7 +39,7 @@ module TicketAbstractorClient
|
|
37
39
|
|
38
40
|
return [] if @ticket_id.blank? && @attachments.blank?
|
39
41
|
|
40
|
-
@attachments = Attachment.fetch(@ticket_id, @endpoint)
|
42
|
+
@attachments = Attachment.fetch(@ticket_id, @endpoint, @project)
|
41
43
|
end
|
42
44
|
|
43
45
|
def comments
|
@@ -45,11 +47,15 @@ module TicketAbstractorClient
|
|
45
47
|
|
46
48
|
return [] if @ticket_id.blank? && @comments.blank?
|
47
49
|
|
48
|
-
@comments = Comment.fetch(@ticket_id, @endpoint)
|
50
|
+
@comments = Comment.fetch(@ticket_id, @endpoint, @project)
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_hash
|
54
|
+
{ sys_id: @sys_id }.merge(super())
|
49
55
|
end
|
50
56
|
|
51
57
|
def sync!
|
52
|
-
raise
|
58
|
+
raise(Errors::TicketArgumentError, 'No changes to apply') unless self.any_changes?
|
53
59
|
return create_ticket if @changes[:create]
|
54
60
|
update_ticket if @changes[:update]
|
55
61
|
update_status if @changes[:new_status]
|
@@ -74,27 +80,30 @@ module TicketAbstractorClient
|
|
74
80
|
method_map = { all: :get_all_tickets, by_id: :get_ticket_by_id, by_query: :get_tickets_by_query }
|
75
81
|
client_response = Client.new(endpoint).public_send(method_map.fetch(selektor.to_sym), opts)
|
76
82
|
|
77
|
-
Array.wrap(client_response).map do |
|
78
|
-
|
79
|
-
ticket = new(ticket_id:
|
80
|
-
ticket
|
81
|
-
|
83
|
+
Array.wrap(client_response).map do |ticket_hash|
|
84
|
+
ticket_id = opts[:ticket_id] || ticket_hash['number']
|
85
|
+
ticket = new(ticket_id: ticket_id, fields: ticket_hash, endpoint: endpoint, project: opts[:project])
|
86
|
+
filtered_ticket = filter_ticket(ticket)
|
87
|
+
filtered_ticket.reset_changes!
|
88
|
+
filtered_ticket
|
82
89
|
end
|
83
90
|
end
|
84
91
|
|
85
|
-
def self.
|
86
|
-
|
92
|
+
def self.filter_ticket(raw_ticket)
|
93
|
+
tickets_filter_class = TicketAbstractorClient.configuration.snow_tickets_filter_class
|
87
94
|
|
88
|
-
return
|
95
|
+
return raw_ticket if tickets_filter_class.blank?
|
89
96
|
|
90
|
-
|
97
|
+
tickets_filter_class.new(raw_ticket).filter_ticket
|
91
98
|
end
|
92
99
|
|
93
100
|
def create_ticket
|
94
101
|
response = Client.new(@endpoint).create_ticket(self)
|
95
|
-
ticket = Ticket.fetch_by_id(ticket_id: response['number'],
|
102
|
+
ticket = Ticket.fetch_by_id(ticket_id: response['number'], project: @project, endpoint: @endpoint)
|
103
|
+
@sys_id = ticket.sys_id
|
96
104
|
@fields = ticket.fields
|
97
105
|
@status = ticket.status
|
106
|
+
@ticket_id = ticket.ticket_id
|
98
107
|
reset_changes!
|
99
108
|
end
|
100
109
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ticket_abstractor_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roman Samoilov
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-03-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -43,42 +43,42 @@ dependencies:
|
|
43
43
|
name: rest-client
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- - "
|
46
|
+
- - ">="
|
47
47
|
- !ruby/object:Gem::Version
|
48
48
|
version: 2.0.0
|
49
49
|
type: :runtime
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
|
-
- - "
|
53
|
+
- - ">="
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: 2.0.0
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: activesupport
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
|
-
- - "
|
60
|
+
- - ">="
|
61
61
|
- !ruby/object:Gem::Version
|
62
62
|
version: 4.2.7
|
63
63
|
type: :runtime
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
|
-
- - "
|
67
|
+
- - ">="
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: 4.2.7
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: mime-types
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
73
73
|
requirements:
|
74
|
-
- - "
|
74
|
+
- - ">="
|
75
75
|
- !ruby/object:Gem::Version
|
76
76
|
version: 1.25.1
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
|
-
- - "
|
81
|
+
- - ">="
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: 1.25.1
|
84
84
|
description: Get access to Jira and Brouha ticketing systems through the single service
|
@@ -95,9 +95,9 @@ files:
|
|
95
95
|
- lib/ticket_abstractor_client/base/client.rb
|
96
96
|
- lib/ticket_abstractor_client/base/comment.rb
|
97
97
|
- lib/ticket_abstractor_client/base/errors.rb
|
98
|
-
- lib/ticket_abstractor_client/base/fields_filter.rb
|
99
98
|
- lib/ticket_abstractor_client/base/response_handler.rb
|
100
99
|
- lib/ticket_abstractor_client/base/ticket.rb
|
100
|
+
- lib/ticket_abstractor_client/base/tickets_filter.rb
|
101
101
|
- lib/ticket_abstractor_client/client_helper.rb
|
102
102
|
- lib/ticket_abstractor_client/configuration.rb
|
103
103
|
- lib/ticket_abstractor_client/jira/attachment.rb
|