ticket_abstractor_client 2.0.1 → 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +48 -2
- data/lib/ticket_abstractor_client/base/attachment.rb +2 -1
- data/lib/ticket_abstractor_client/base/client.rb +38 -2
- data/lib/ticket_abstractor_client/base/comment.rb +2 -1
- data/lib/ticket_abstractor_client/base/ticket.rb +3 -1
- data/lib/ticket_abstractor_client/communication_data.rb +43 -0
- data/lib/ticket_abstractor_client/configuration.rb +7 -1
- data/lib/ticket_abstractor_client/jira/ticket.rb +3 -1
- data/lib/ticket_abstractor_client/service_now/attachment.rb +21 -19
- data/lib/ticket_abstractor_client/service_now/client.rb +10 -2
- data/lib/ticket_abstractor_client/service_now/comment.rb +22 -12
- data/lib/ticket_abstractor_client/service_now/params_builder.rb +11 -8
- data/lib/ticket_abstractor_client/service_now/ticket.rb +39 -7
- data/lib/ticket_abstractor_client/version.rb +1 -1
- data/lib/ticket_abstractor_client.rb +1 -0
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5e5d71cc98d22ffbab8164cbcd6d91d19360d516
|
4
|
+
data.tar.gz: ecb8e7f3ba91f51fc9eb47b7776a93d6b76b77b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf1de47f64d0c61c21791d8853e4853292788c364bdff38cd0d61badae1802b91b982ead7f5747cd8082a32aee3a3409a5fdc906603b0520541001bd8c47ddc0
|
7
|
+
data.tar.gz: 39abe1cee3c2a8c4e6aa120cbef44a6ca7d5ace53ce05dcec6866026005a94d9fac27541528c0a791a9b298eb07161ecc1607076f840ac7185d3314325603427
|
data/README.md
CHANGED
@@ -9,6 +9,8 @@ Client for accessing to a TicketAbstractor service.
|
|
9
9
|
* [Configuration](#configuration)
|
10
10
|
* [Usage](#usage)
|
11
11
|
* [Filtering fields](#fields_filters)
|
12
|
+
* [TODOs](#todos)
|
13
|
+
* [Contributing](#contributing)
|
12
14
|
|
13
15
|
---
|
14
16
|
|
@@ -20,7 +22,7 @@ Add this line to your application's Gemfile:
|
|
20
22
|
|
21
23
|
And then execute:
|
22
24
|
|
23
|
-
$ bundle
|
25
|
+
$ bundle install
|
24
26
|
|
25
27
|
Or install it yourself as:
|
26
28
|
|
@@ -77,6 +79,40 @@ this parameter defaults to false.
|
|
77
79
|
|
78
80
|
config.snow_display_value = TicketAbstractorClient::Configuration::SNOW_DISPLAY_VALUE_ALL
|
79
81
|
|
82
|
+
**Trace communications**
|
83
|
+
|
84
|
+
Allows you to see all request's and response's data for `Client`, `Ticket`, `Comment` or `Attachment`
|
85
|
+
|
86
|
+
# add to configuration file
|
87
|
+
config.trace_communications = true # false by default
|
88
|
+
|
89
|
+
# my_class.rb
|
90
|
+
class MyClass
|
91
|
+
include TicketAbstractorClient
|
92
|
+
|
93
|
+
def create_snow_ticket(ticket_params)
|
94
|
+
snow_ticket = ServiceNow::Ticket.new(ticket_params).sync!
|
95
|
+
|
96
|
+
snow_ticket.communications_stack do |communication_data|
|
97
|
+
# do something
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
`communications_stack` method returns an array of `CommunicationData` objects with following attributes:
|
103
|
+
|
104
|
+
- method
|
105
|
+
- path
|
106
|
+
- args
|
107
|
+
- response
|
108
|
+
- executed_at
|
109
|
+
- total_response_time
|
110
|
+
- ta_response_time
|
111
|
+
- ts_response_time
|
112
|
+
|
113
|
+
`args` and `response` attributes may contain **'Binary content'** text or
|
114
|
+
**'Base64 string representation of content'** text for attachments, text depends on ticketing system.
|
115
|
+
|
80
116
|
[[table of contents](#content)]
|
81
117
|
|
82
118
|
---
|
@@ -332,9 +368,11 @@ and implement a `filter_ticket` method, after that configure the gem to use your
|
|
332
368
|
end
|
333
369
|
|
334
370
|
def filter_ticket
|
335
|
-
@ticket.fields.each_with_object([]) |raw_field, filtered_fields|
|
371
|
+
@ticket.fields = @ticket.fields.each_with_object([]) do |raw_field, filtered_fields|
|
336
372
|
# do some filtering here
|
337
373
|
end
|
374
|
+
|
375
|
+
@ticket
|
338
376
|
end
|
339
377
|
end
|
340
378
|
|
@@ -352,6 +390,14 @@ JIRA is supported as well.
|
|
352
390
|
|
353
391
|
---
|
354
392
|
|
393
|
+
## <a name="todos"></a> TODOs
|
394
|
+
|
395
|
+
- [] Ability to retrieve `communications_stack` data for Jira objects (`Ticket`, `Comment` and `Attachment`)
|
396
|
+
|
397
|
+
[[table of contents](#content)]
|
398
|
+
|
399
|
+
---
|
400
|
+
|
355
401
|
## <a name="contributing"></a> Contributing
|
356
402
|
|
357
403
|
1. Fork it
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module TicketAbstractorClient
|
2
2
|
module Base
|
3
3
|
class Attachment
|
4
|
-
attr_reader :file_path, :data_hash, :external_created_at
|
4
|
+
attr_reader :file_path, :data_hash, :external_created_at, :communications_stack
|
5
5
|
|
6
6
|
# Carrierwave uses the same regexp
|
7
7
|
SANITIZE_REGEXP = /[^[:word:]\.\-\+]/
|
@@ -38,6 +38,7 @@ module TicketAbstractorClient
|
|
38
38
|
@file_path = opts[:file_path]
|
39
39
|
@external_created_at = opts[:external_created_at]
|
40
40
|
@data_hash = opts[:data_hash]
|
41
|
+
@communications_stack = opts[:communications_stack] || []
|
41
42
|
set_data_hash! if @data_hash.blank?
|
42
43
|
end
|
43
44
|
|
@@ -3,10 +3,16 @@ module TicketAbstractorClient
|
|
3
3
|
class Client
|
4
4
|
include ResponseHandler
|
5
5
|
|
6
|
+
TA_RESPONSE_TIME_HEADERS_LIST = %i(total_response_time ta_response_time ts_response_time).freeze
|
7
|
+
|
8
|
+
attr_reader :communications_stack, :trace_communications
|
9
|
+
|
6
10
|
def initialize
|
7
11
|
@base_url = TicketAbstractorClient.configuration.ticket_abstractor_url
|
8
12
|
@security_token = TicketAbstractorClient.configuration.security_token
|
9
13
|
@ssl_options = TicketAbstractorClient.configuration.ssl_options
|
14
|
+
@communications_stack = []
|
15
|
+
@trace_communications = TicketAbstractorClient.configuration.trace_communications
|
10
16
|
|
11
17
|
raise Errors::ConfigurationError, 'TicketAbstractor url is not given' if @base_url.blank?
|
12
18
|
raise Errors::ConfigurationError, 'SecurityToken is not given' if @security_token.blank?
|
@@ -18,7 +24,7 @@ module TicketAbstractorClient
|
|
18
24
|
params.merge! args: args.to_json, security_token: @security_token
|
19
25
|
with_response_handling do
|
20
26
|
rest_client_error_handling do
|
21
|
-
response =
|
27
|
+
response = make_request(path, 'get', params)
|
22
28
|
response.headers.key?(:file_request) ? { 'result' => response } : JSON.parse(response)
|
23
29
|
end
|
24
30
|
end
|
@@ -28,12 +34,42 @@ module TicketAbstractorClient
|
|
28
34
|
params.merge! args: args.to_json, security_token: @security_token
|
29
35
|
with_response_handling do
|
30
36
|
rest_client_error_handling do
|
31
|
-
response =
|
37
|
+
response = make_request(path, 'post', params)
|
32
38
|
JSON.parse response
|
33
39
|
end
|
34
40
|
end
|
35
41
|
end
|
36
42
|
|
43
|
+
def make_request(path, method, params)
|
44
|
+
request = build_request(path, method, params)
|
45
|
+
executed_at = Time.now
|
46
|
+
response = request.execute
|
47
|
+
|
48
|
+
@communications_stack << communication_data(request, response, executed_at) if self.trace_communications
|
49
|
+
|
50
|
+
response
|
51
|
+
end
|
52
|
+
|
53
|
+
def communication_data(request, response, executed_at)
|
54
|
+
CommunicationData.new.tap do |communication|
|
55
|
+
communication.executed_at = executed_at
|
56
|
+
|
57
|
+
communication.method = request.method
|
58
|
+
communication.path = request.uri.path
|
59
|
+
communication.args = request.args.dig(:payload, :args) || request.args.dig(:headers, :params, :args)
|
60
|
+
|
61
|
+
if response.headers.key?(:file_request)
|
62
|
+
communication.binary_response!
|
63
|
+
else
|
64
|
+
communication.response = response.body
|
65
|
+
end
|
66
|
+
|
67
|
+
TA_RESPONSE_TIME_HEADERS_LIST.each do |key|
|
68
|
+
communication.public_send("#{key}=", response.headers[key])
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
37
73
|
def build_request(path, method, params)
|
38
74
|
request_params = @ssl_options.merge(url: "#{@base_url}/v2/#{path}", method: method)
|
39
75
|
request_params[:headers] = { params: params } if method.inquiry.get?
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module TicketAbstractorClient
|
2
2
|
module Base
|
3
3
|
class Comment
|
4
|
-
attr_reader :author, :body, :data_hash, :external_created_at
|
4
|
+
attr_reader :author, :body, :data_hash, :external_created_at, :communications_stack
|
5
5
|
|
6
6
|
def self.fetch(*opts)
|
7
7
|
method_not_implemented __method__
|
@@ -13,6 +13,7 @@ module TicketAbstractorClient
|
|
13
13
|
@body = opts.fetch(:body, nil) || raise(Errors::CommentArgumentError, 'Body is not given')
|
14
14
|
@external_created_at = opts[:external_created_at]
|
15
15
|
@data_hash = opts[:data_hash]
|
16
|
+
@communications_stack = opts[:communications_stack] || []
|
16
17
|
set_data_hash! if @data_hash.blank?
|
17
18
|
end
|
18
19
|
|
@@ -2,7 +2,7 @@ module TicketAbstractorClient
|
|
2
2
|
module Base
|
3
3
|
class Ticket
|
4
4
|
attr_reader :attachments, :comments, :changes, :status
|
5
|
-
attr_accessor :ticket_id, :endpoint, :project, :fields
|
5
|
+
attr_accessor :ticket_id, :endpoint, :project, :fields, :communications_stack
|
6
6
|
|
7
7
|
def initialize(opts = {})
|
8
8
|
opts = opts.with_indifferent_access
|
@@ -10,6 +10,7 @@ module TicketAbstractorClient
|
|
10
10
|
@fields = opts.fetch(:fields, {}).with_indifferent_access
|
11
11
|
@endpoint = opts[:endpoint] || raise(Errors::TicketArgumentError, 'Endpoint is not given')
|
12
12
|
@project = opts[:project]
|
13
|
+
@communications_stack = opts[:communications_stack] || []
|
13
14
|
@attachments ||= []
|
14
15
|
@comments ||= []
|
15
16
|
initialize_changes!
|
@@ -73,6 +74,7 @@ module TicketAbstractorClient
|
|
73
74
|
|
74
75
|
def mark_changes!
|
75
76
|
return @changes[:create] = true if @ticket_id.blank?
|
77
|
+
|
76
78
|
@changes[:update] = true if @fields.present?
|
77
79
|
end
|
78
80
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module TicketAbstractorClient
|
2
|
+
class CommunicationData
|
3
|
+
attr_accessor :method, :path, :args, :response, :executed_at,
|
4
|
+
:total_response_time, :ta_response_time, :ts_response_time
|
5
|
+
|
6
|
+
BINARY_RESPONSE_TEXT = 'Binary content'.freeze
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@binary_response = false
|
10
|
+
end
|
11
|
+
|
12
|
+
def binary_response!
|
13
|
+
@binary_response = true
|
14
|
+
end
|
15
|
+
|
16
|
+
def binary_response?
|
17
|
+
@binary_response
|
18
|
+
end
|
19
|
+
|
20
|
+
def response
|
21
|
+
return BINARY_RESPONSE_TEXT if self.binary_response?
|
22
|
+
|
23
|
+
@response
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_h
|
27
|
+
{
|
28
|
+
method: self.method,
|
29
|
+
path: self.path,
|
30
|
+
args: self.args,
|
31
|
+
response: self.response,
|
32
|
+
executed_at: self.executed_at,
|
33
|
+
total_response_time: self.total_response_time,
|
34
|
+
ta_response_time: self.ta_response_time,
|
35
|
+
ts_response_time: self.ts_response_time
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_json
|
40
|
+
self.to_h.to_json
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module TicketAbstractorClient
|
2
2
|
class Configuration
|
3
3
|
attr_accessor :ticket_abstractor_url, :security_token, :snow_display_value, :jira_fields_meta,
|
4
|
-
:jira_meta_expiration_period, :ssl_options
|
4
|
+
:jira_meta_expiration_period, :ssl_options, :trace_communications
|
5
5
|
|
6
6
|
DEFAULT_JIRA_META_EXPIRATION_PERIOD = 604800 # 1 week
|
7
7
|
|
@@ -15,6 +15,8 @@ module TicketAbstractorClient
|
|
15
15
|
|
16
16
|
DEFAULT_SSL_OPTIONS = { verify_ssl: true }.freeze
|
17
17
|
|
18
|
+
DEFAULT_TRACE_COMMUNICATIONS = false
|
19
|
+
|
18
20
|
def jira_tickets_filter_class
|
19
21
|
@jira_tickets_filter_class.presence
|
20
22
|
end
|
@@ -33,6 +35,10 @@ module TicketAbstractorClient
|
|
33
35
|
@jira_meta_expiration_period ||= DEFAULT_JIRA_META_EXPIRATION_PERIOD
|
34
36
|
end
|
35
37
|
|
38
|
+
def trace_communications
|
39
|
+
@trace_communications ||= DEFAULT_TRACE_COMMUNICATIONS
|
40
|
+
end
|
41
|
+
|
36
42
|
def snow_display_value
|
37
43
|
@snow_display_value ||= DEFAULT_SNOW_DISPLAY_VALUE
|
38
44
|
end
|
@@ -64,7 +64,7 @@ module TicketAbstractorClient
|
|
64
64
|
def sync!
|
65
65
|
raise(Errors::TicketArgumentError, 'No changes to apply') unless self.any_changes?
|
66
66
|
|
67
|
-
return
|
67
|
+
return create_ticket if @changes[:create]
|
68
68
|
|
69
69
|
update_ticket if @changes[:update]
|
70
70
|
update_status if @changes[:new_status]
|
@@ -72,6 +72,8 @@ module TicketAbstractorClient
|
|
72
72
|
sync_attachments unless @changes[:new_attachments].zero?
|
73
73
|
self.reload!
|
74
74
|
self.reset_changes!
|
75
|
+
|
76
|
+
self
|
75
77
|
end
|
76
78
|
|
77
79
|
def updated_at
|
@@ -5,26 +5,24 @@ module TicketAbstractorClient
|
|
5
5
|
|
6
6
|
class << self
|
7
7
|
def fetch(ticket_id, endpoint, project)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
protected
|
8
|
+
client = Client.new(endpoint)
|
9
|
+
attachments_list = client.get_attachments(ticket_id: ticket_id)
|
10
|
+
return [[], client.communications_stack] if attachments_list.blank?
|
14
11
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
12
|
+
attachments =
|
13
|
+
attachments_list.map do |attachment|
|
14
|
+
attachment_data = client.get_attachment_file(sys_id: attachment['sys_id'])
|
15
|
+
filepath = save_content(attachment_data.body, attachment['file_name'])
|
16
|
+
new(
|
17
|
+
file_path: filepath,
|
18
|
+
ticket_id: ticket_id,
|
19
|
+
endpoint: endpoint,
|
20
|
+
project: project,
|
21
|
+
communications_stack: client.communications_stack
|
22
|
+
)
|
23
|
+
end
|
20
24
|
|
21
|
-
|
22
|
-
payload.each.with_index.with_object([]) do |(payload, index), files|
|
23
|
-
next if payload.blank?
|
24
|
-
file_name = files_names[index]
|
25
|
-
decoded_payload = Base64.decode64(payload)
|
26
|
-
files << save_content(decoded_payload, file_name)
|
27
|
-
end
|
25
|
+
[attachments, client.communications_stack]
|
28
26
|
end
|
29
27
|
end
|
30
28
|
|
@@ -34,7 +32,11 @@ module TicketAbstractorClient
|
|
34
32
|
end
|
35
33
|
|
36
34
|
def sync!
|
37
|
-
Client.new(@endpoint)
|
35
|
+
client = Client.new(@endpoint)
|
36
|
+
response = client.create_attachment(self)
|
37
|
+
@communications_stack = client.communications_stack
|
38
|
+
|
39
|
+
response
|
38
40
|
end
|
39
41
|
end
|
40
42
|
end
|
@@ -4,6 +4,7 @@ module TicketAbstractorClient
|
|
4
4
|
include ServiceNow::ParamsBuilder
|
5
5
|
|
6
6
|
SYS_ID_LENGTH = 32
|
7
|
+
TICKET_NOT_FOUND = 'Ticket not found or incorrect ID given'.freeze
|
7
8
|
|
8
9
|
def initialize(endpoint = 'default')
|
9
10
|
super()
|
@@ -15,6 +16,11 @@ module TicketAbstractorClient
|
|
15
16
|
end
|
16
17
|
|
17
18
|
def get_attachments(opts)
|
19
|
+
opts[:ticket_id] = get_ticket_sys_id(opts)
|
20
|
+
get(__method__, opts)
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_attachment_file(opts)
|
18
24
|
get(__method__, opts)
|
19
25
|
end
|
20
26
|
|
@@ -48,7 +54,9 @@ module TicketAbstractorClient
|
|
48
54
|
|
49
55
|
def create_attachment(attachment)
|
50
56
|
attachment.ticket_id = get_ticket_sys_id(ticket_id: attachment.ticket_id, table_name: attachment.project)
|
51
|
-
|
57
|
+
|
58
|
+
args, params = build_attachment_params(attachment)
|
59
|
+
post(__method__, args, params)
|
52
60
|
end
|
53
61
|
|
54
62
|
def create_comment(comment)
|
@@ -77,7 +85,7 @@ module TicketAbstractorClient
|
|
77
85
|
|
78
86
|
response = get(__method__, opts)
|
79
87
|
|
80
|
-
raise(Errors::NotFoundError,
|
88
|
+
raise(Errors::NotFoundError, TICKET_NOT_FOUND) if response.blank?
|
81
89
|
|
82
90
|
response[0]['sys_id']
|
83
91
|
end
|
@@ -4,17 +4,23 @@ module TicketAbstractorClient
|
|
4
4
|
attr_accessor :ticket_id, :endpoint, :project
|
5
5
|
|
6
6
|
def self.fetch(ticket_id, endpoint, project)
|
7
|
-
|
8
|
-
response.
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
7
|
+
client = Client.new(endpoint)
|
8
|
+
response = client.get_comments(ticket_id: ticket_id, project: project)
|
9
|
+
|
10
|
+
comments =
|
11
|
+
response.map do |raw_comment|
|
12
|
+
new({
|
13
|
+
author: raw_comment['sys_created_by'],
|
14
|
+
body: raw_comment['value'],
|
15
|
+
external_created_at: raw_comment['sys_created_on'],
|
16
|
+
ticket_id: ticket_id,
|
17
|
+
endpoint: endpoint,
|
18
|
+
project: project,
|
19
|
+
communications_stack: client.communications_stack
|
20
|
+
})
|
21
|
+
end
|
22
|
+
|
23
|
+
[comments, client.communications_stack]
|
18
24
|
end
|
19
25
|
|
20
26
|
def initialize(opts)
|
@@ -23,7 +29,11 @@ module TicketAbstractorClient
|
|
23
29
|
end
|
24
30
|
|
25
31
|
def sync!
|
26
|
-
Client.new(@endpoint)
|
32
|
+
client = Client.new(@endpoint)
|
33
|
+
response = client.create_comment(self)
|
34
|
+
@communications_stack = client.communications_stack
|
35
|
+
|
36
|
+
response
|
27
37
|
end
|
28
38
|
end
|
29
39
|
end
|
@@ -15,14 +15,17 @@ module TicketAbstractorClient
|
|
15
15
|
def build_attachment_params(attachment)
|
16
16
|
file_path = attachment.file_path
|
17
17
|
mime_type = MIME::Types.type_for(file_path).first.try(:to_s) || '*/*'
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
18
|
+
[
|
19
|
+
{
|
20
|
+
table_name: attachment.project,
|
21
|
+
table_sys_id: attachment.ticket_id,
|
22
|
+
file_name: File.basename(file_path),
|
23
|
+
content_type: mime_type
|
24
|
+
},
|
25
|
+
{
|
26
|
+
attachments: [File.new(file_path, 'rb')]
|
27
|
+
}
|
28
|
+
]
|
26
29
|
end
|
27
30
|
|
28
31
|
def build_comment_params(comment)
|
@@ -17,6 +17,7 @@ module TicketAbstractorClient
|
|
17
17
|
|
18
18
|
def initialize(opts = {})
|
19
19
|
super(opts)
|
20
|
+
|
20
21
|
@project = opts[:project] || raise(Errors::TicketArgumentError, 'Project is not given')
|
21
22
|
@sys_id = @fields['sys_id']
|
22
23
|
@status = @fields['state']
|
@@ -25,12 +26,14 @@ module TicketAbstractorClient
|
|
25
26
|
def add_attachment(attachment)
|
26
27
|
@attachments << Attachment.new(attachment.merge(ticket_id: @ticket_id, endpoint: @endpoint, project: @project))
|
27
28
|
@changes[:new_attachments] += 1
|
29
|
+
|
28
30
|
self
|
29
31
|
end
|
30
32
|
|
31
33
|
def add_comment(comment)
|
32
34
|
@comments << Comment.new(comment.merge(ticket_id: @ticket_id, endpoint: @endpoint, project: @project))
|
33
35
|
@changes[:new_comments] += 1
|
36
|
+
|
34
37
|
self
|
35
38
|
end
|
36
39
|
|
@@ -39,7 +42,10 @@ module TicketAbstractorClient
|
|
39
42
|
|
40
43
|
return [] if @ticket_id.blank? && @attachments.blank?
|
41
44
|
|
42
|
-
@attachments = Attachment.fetch(@ticket_id, @endpoint, @project)
|
45
|
+
@attachments, attachments_communications_stack = Attachment.fetch(@ticket_id, @endpoint, @project)
|
46
|
+
@communications_stack += attachments_communications_stack
|
47
|
+
|
48
|
+
@attachments
|
43
49
|
end
|
44
50
|
|
45
51
|
def comments
|
@@ -47,7 +53,10 @@ module TicketAbstractorClient
|
|
47
53
|
|
48
54
|
return [] if @ticket_id.blank? && @comments.blank?
|
49
55
|
|
50
|
-
@comments = Comment.fetch(@ticket_id, @endpoint, @project)
|
56
|
+
@comments, comments_communications_stack = Comment.fetch(@ticket_id, @endpoint, @project)
|
57
|
+
@communications_stack += comments_communications_stack
|
58
|
+
|
59
|
+
@comments
|
51
60
|
end
|
52
61
|
|
53
62
|
def to_hash
|
@@ -56,12 +65,16 @@ module TicketAbstractorClient
|
|
56
65
|
|
57
66
|
def sync!
|
58
67
|
raise(Errors::TicketArgumentError, 'No changes to apply') unless self.any_changes?
|
68
|
+
|
59
69
|
return create_ticket if @changes[:create]
|
70
|
+
|
60
71
|
update_ticket if @changes[:update]
|
61
72
|
update_status if @changes[:new_status]
|
62
73
|
sync_comments unless @changes[:new_comments].zero?
|
63
74
|
sync_attachments unless @changes[:new_attachments].zero?
|
64
75
|
reset_changes!
|
76
|
+
|
77
|
+
self
|
65
78
|
end
|
66
79
|
|
67
80
|
def updated_at
|
@@ -78,13 +91,15 @@ module TicketAbstractorClient
|
|
78
91
|
opts = opts.with_indifferent_access
|
79
92
|
endpoint = opts.delete(:endpoint)
|
80
93
|
method_map = { all: :get_all_tickets, by_id: :get_ticket_by_id, by_query: :get_tickets_by_query }
|
81
|
-
|
94
|
+
client = Client.new(endpoint)
|
95
|
+
client_response = client.public_send(method_map.fetch(selektor.to_sym), opts)
|
82
96
|
|
83
97
|
Array.wrap(client_response).map do |ticket_hash|
|
84
98
|
ticket_id = opts[:ticket_id] || ticket_hash['number']
|
85
99
|
ticket = new(ticket_id: ticket_id, fields: ticket_hash, endpoint: endpoint, project: opts[:project])
|
86
100
|
filtered_ticket = filter_ticket(ticket)
|
87
101
|
filtered_ticket.reset_changes!
|
102
|
+
filtered_ticket.communications_stack = client.communications_stack
|
88
103
|
filtered_ticket
|
89
104
|
end
|
90
105
|
end
|
@@ -98,13 +113,20 @@ module TicketAbstractorClient
|
|
98
113
|
end
|
99
114
|
|
100
115
|
def create_ticket
|
101
|
-
|
116
|
+
client = Client.new(@endpoint)
|
117
|
+
response = client.create_ticket(self)
|
118
|
+
@communications_stack += client.communications_stack
|
119
|
+
|
102
120
|
ticket = Ticket.fetch_by_id(ticket_id: response['number'], project: @project, endpoint: @endpoint)
|
121
|
+
|
103
122
|
@sys_id = ticket.sys_id
|
104
123
|
@fields = ticket.fields
|
105
124
|
@status = ticket.status
|
106
125
|
@ticket_id = ticket.ticket_id
|
126
|
+
@communications_stack += ticket.communications_stack
|
107
127
|
reset_changes!
|
128
|
+
|
129
|
+
self
|
108
130
|
end
|
109
131
|
|
110
132
|
def update_status
|
@@ -113,16 +135,26 @@ module TicketAbstractorClient
|
|
113
135
|
end
|
114
136
|
|
115
137
|
def update_ticket
|
116
|
-
|
138
|
+
client = Client.new(@endpoint)
|
139
|
+
response = client.update_ticket(self)
|
140
|
+
@communications_stack += client.communications_stack
|
117
141
|
@fields['sys_updated_on'] = response['sys_updated_on']
|
118
142
|
end
|
119
143
|
|
120
144
|
def sync_attachments
|
121
|
-
@
|
145
|
+
@communications_stack +=
|
146
|
+
@attachments.last(@changes[:new_attachments]).flat_map do |attachment|
|
147
|
+
attachment.sync!
|
148
|
+
attachment.communications_stack
|
149
|
+
end
|
122
150
|
end
|
123
151
|
|
124
152
|
def sync_comments
|
125
|
-
@
|
153
|
+
@communications_stack +=
|
154
|
+
@comments.last(@changes[:new_comments]).flat_map do |comment|
|
155
|
+
comment.sync!
|
156
|
+
comment.communications_stack
|
157
|
+
end
|
126
158
|
end
|
127
159
|
end
|
128
160
|
end
|
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.2
|
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-06-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -17,14 +17,14 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: 1.
|
20
|
+
version: 1.15.1
|
21
21
|
type: :development
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: 1.
|
27
|
+
version: 1.15.1
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: rake
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -99,6 +99,7 @@ files:
|
|
99
99
|
- lib/ticket_abstractor_client/base/ticket.rb
|
100
100
|
- lib/ticket_abstractor_client/base/tickets_filter.rb
|
101
101
|
- lib/ticket_abstractor_client/client_helper.rb
|
102
|
+
- lib/ticket_abstractor_client/communication_data.rb
|
102
103
|
- lib/ticket_abstractor_client/configuration.rb
|
103
104
|
- lib/ticket_abstractor_client/jira/attachment.rb
|
104
105
|
- lib/ticket_abstractor_client/jira/client.rb
|