ticket_abstractor_client 2.0.1 → 2.0.2
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 +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
|