ticket_abstractor_client 1.29.0 → 2.0.0

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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +199 -159
  3. data/lib/ticket_abstractor_client.rb +11 -39
  4. data/lib/ticket_abstractor_client/base/attachment.rb +52 -0
  5. data/lib/ticket_abstractor_client/base/client.rb +54 -0
  6. data/lib/ticket_abstractor_client/base/comment.rb +35 -0
  7. data/lib/ticket_abstractor_client/base/errors.rb +25 -0
  8. data/lib/ticket_abstractor_client/base/fields_filter.rb +15 -0
  9. data/lib/ticket_abstractor_client/base/response_handler.rb +28 -0
  10. data/lib/ticket_abstractor_client/base/ticket.rb +79 -0
  11. data/lib/ticket_abstractor_client/client_helper.rb +29 -0
  12. data/lib/ticket_abstractor_client/configuration.rb +61 -0
  13. data/lib/ticket_abstractor_client/jira/attachment.rb +42 -0
  14. data/lib/ticket_abstractor_client/jira/client.rb +83 -0
  15. data/lib/ticket_abstractor_client/jira/comment.rb +35 -0
  16. data/lib/ticket_abstractor_client/jira/errors.rb +25 -0
  17. data/lib/ticket_abstractor_client/jira/fields_meta.rb +36 -0
  18. data/lib/ticket_abstractor_client/jira/params_builder.rb +96 -0
  19. data/lib/ticket_abstractor_client/jira/ticket.rb +131 -0
  20. data/lib/ticket_abstractor_client/service_now/attachment.rb +41 -0
  21. data/lib/ticket_abstractor_client/service_now/client.rb +78 -0
  22. data/lib/ticket_abstractor_client/service_now/comment.rb +30 -0
  23. data/lib/ticket_abstractor_client/service_now/errors.rb +25 -0
  24. data/lib/ticket_abstractor_client/service_now/params_builder.rb +56 -0
  25. data/lib/ticket_abstractor_client/service_now/ticket.rb +120 -0
  26. data/lib/ticket_abstractor_client/version.rb +1 -1
  27. metadata +52 -9
  28. data/lib/ticket_abstractor_client/brouha_client.rb +0 -33
  29. data/lib/ticket_abstractor_client/client.rb +0 -31
  30. data/lib/ticket_abstractor_client/i_logger_client.rb +0 -5
  31. data/lib/ticket_abstractor_client/itrc_client.rb +0 -33
  32. data/lib/ticket_abstractor_client/jira_client.rb +0 -128
  33. data/lib/ticket_abstractor_client/service_now_client.rb +0 -61
  34. data/lib/ticket_abstractor_client/sev_one_client.rb +0 -21
@@ -0,0 +1,41 @@
1
+ module TicketAbstractorClient
2
+ module ServiceNow
3
+ class Attachment < Base::Attachment
4
+ attr_accessor :ticket_id, :endpoint, :project
5
+
6
+ class << self
7
+ def fetch(ticket_id, endpoint, project)
8
+ download_files(ticket_id, endpoint).map do |filepath|
9
+ new(file_path: filepath, ticket_id: ticket_id, endpoint: endpoint, project: project)
10
+ end
11
+ end
12
+
13
+ protected
14
+
15
+ def download_files(ticket_id, endpoint)
16
+ response = Client.new(endpoint).get_attachments(ticket_id: ticket_id)
17
+ return [] if response.blank?
18
+ decode_and_save(Array.wrap(response['payload']), Array.wrap(response['file_name']))
19
+ end
20
+
21
+ def decode_and_save(payload, files_names)
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
28
+ end
29
+ end
30
+
31
+ def initialize(opts)
32
+ super(opts)
33
+ @ticket_id, @endpoint, @project = opts.values_at(:ticket_id, :endpoint, :project)
34
+ end
35
+
36
+ def sync!
37
+ Client.new(@endpoint).create_attachment(self)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,78 @@
1
+ module TicketAbstractorClient
2
+ module ServiceNow
3
+ class Client < Base::Client
4
+ include ServiceNow::ParamsBuilder
5
+
6
+ SYS_ID_LENGTH = 32
7
+
8
+ def initialize(endpoint = 'default')
9
+ super()
10
+ @service_now_endpoint = endpoint
11
+ end
12
+
13
+ def get_all_tickets(opts)
14
+ get_tickets_by_query(build_all_tickets_params(opts))
15
+ end
16
+
17
+ def get_attachments(opts)
18
+ get(__method__, opts)
19
+ end
20
+
21
+ def get_comments(opts)
22
+ opts[:ticket_id] = get_ticket_sys_id(opts)
23
+ opts[:display_value] ||= TicketAbstractorClient.configuration.snow_display_value
24
+ get(__method__, opts)
25
+ end
26
+
27
+ def get_ticket_by_id(opts)
28
+ opts[:ticket_id] = get_ticket_sys_id(opts)
29
+ opts[:display_value] ||= TicketAbstractorClient.configuration.snow_display_value
30
+ get(__method__, opts)
31
+ end
32
+
33
+ def get_tickets_by_query(opts)
34
+ opts[:display_value] ||= TicketAbstractorClient.configuration.snow_display_value
35
+ get(__method__, opts)
36
+ end
37
+
38
+ def create_attachment(attachment)
39
+ attachment.ticket_id = get_ticket_sys_id(ticket_id: attachment.ticket_id, table_name: attachment.project)
40
+ post(__method__, build_attachment_params(attachment))
41
+ end
42
+
43
+ def create_comment(comment)
44
+ comment.ticket_id = get_ticket_sys_id(ticket_id: comment.ticket_id, table_name: comment.project)
45
+ post(__method__, build_comment_params(comment))
46
+ end
47
+
48
+ def create_ticket(ticket)
49
+ post(__method__, build_ticket_params(ticket))
50
+ end
51
+
52
+ def update_ticket(ticket)
53
+ ticket.ticket_id = get_ticket_sys_id(ticket_id: ticket.ticket_id, table_name: ticket.project)
54
+ post(__method__, build_ticket_params(ticket))
55
+ end
56
+
57
+ def update_ticket_status(ticket)
58
+ post(:update_ticket, build_status_params(ticket))
59
+ end
60
+
61
+ protected
62
+
63
+ def get_ticket_sys_id(opts)
64
+ return opts[:ticket_id] if opts[:ticket_id].length == SYS_ID_LENGTH
65
+
66
+ get(__method__, opts)[0]['sys_id']
67
+ end
68
+
69
+ def get(path, args = {}, params = {})
70
+ super("service_now/#{path}", args, params.merge(service_now_endpoint: @service_now_endpoint))
71
+ end
72
+
73
+ def post(path, args = {}, params = {})
74
+ super("service_now/#{path}", args, params.merge(service_now_endpoint: @service_now_endpoint))
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,30 @@
1
+ module TicketAbstractorClient
2
+ module ServiceNow
3
+ class Comment < Base::Comment
4
+ attr_accessor :ticket_id, :endpoint, :project
5
+
6
+ def self.fetch(ticket_id, endpoint, project)
7
+ response = Client.new(endpoint).get_comments(ticket_id: ticket_id, table_name: project)
8
+ response.map do |raw_comment|
9
+ new({
10
+ author: raw_comment['sys_created_by_name'],
11
+ body: raw_comment['value'],
12
+ external_created_at: raw_comment['sys_created_on'],
13
+ ticket_id: ticket_id,
14
+ endpoint: endpoint,
15
+ project: project
16
+ })
17
+ end
18
+ end
19
+
20
+ def initialize(opts)
21
+ super(opts)
22
+ @ticket_id, @endpoint, @project = opts.values_at(:ticket_id, :endpoint, :project)
23
+ end
24
+
25
+ def sync!
26
+ Client.new(@endpoint).create_comment(self)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,25 @@
1
+ module TicketAbstractorClient
2
+ module ServiceNow
3
+ module Errors
4
+ class BaseError < Base::Errors::BaseError; end
5
+ class NotImplementedError < BaseError; end
6
+ class ConfigurationError < Base::Errors::ConfigurationError; end
7
+ class UnexpectedError < Base::Errors::UnexpectedError; end
8
+
9
+ class AttachmentArgumentError < Base::Errors::AttachmentArgumentError; end
10
+ class CommentArgumentError < Base::Errors::CommentArgumentError; end
11
+ class ClientArgumentError < Base::Errors::ClientArgumentError; end
12
+ class TicketArgumentError < Base::Errors::TicketArgumentError; end
13
+
14
+ class AttachmentError < Base::Errors::AttachmentError; end
15
+ class CommentError < Base::Errors::CommentError; end
16
+ class TicketError < Base::Errors::TicketError; end
17
+
18
+ class ConnectionError < Base::Errors::ConnectionError; end
19
+ class NotFoundError < Base::Errors::NotFoundError; end
20
+ class ParseError < Base::Errors::ParseError; end
21
+ class RequsetFormatError < Base::Errors::RequsetFormatError; end
22
+ class AccessError < Base::Errors::AccessError; end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,56 @@
1
+ module TicketAbstractorClient
2
+ module ServiceNow
3
+ module ParamsBuilder
4
+ extend ActiveSupport::Concern
5
+
6
+ def biuld_all_tickets_params(opts)
7
+ opts[:sysparm_query] = build_sysparm_query(opts)
8
+ opts[:sysparm_fields] = Array.wrap(opts.delete(:fields))
9
+ opts.except!(:service_desk, :states)
10
+ opts[:display_value] ||= TicketAbstractorClient.configuration.snow_display_value
11
+ opts
12
+ end
13
+
14
+ def build_attachment_params(attachment)
15
+ file_path = attachment.file_path
16
+ mime_type = MIME::Types.type_for(file_path).first.try(:to_s) || '*/*'
17
+ file = File.open(file_path, 'rb')
18
+ {
19
+ agent: 'AttachmentCreator',
20
+ topic: 'AttachmentCreator',
21
+ name: "#{File.basename(file_path)}:#{mime_type}",
22
+ source: "#{attachment.project}:#{attachment.ticket_id}",
23
+ payload: Base64.encode64(file.read)
24
+ }
25
+ end
26
+
27
+ def build_comment_params(comment)
28
+ {
29
+ comment_params: { comments: comment.body },
30
+ ticket_id: comment.ticket_id,
31
+ table_name: comment.project,
32
+ display_value: TicketAbstractorClient.configuration.snow_display_value
33
+ }
34
+ end
35
+
36
+ def build_status_params(ticket)
37
+ { ticket_params: { state: ticket.status }, ticket_id: ticket.ticket_id, table_name: ticket.project }
38
+ end
39
+
40
+ def build_ticket_params(ticket)
41
+ opts = { ticket_params: ticket.fields, table_name: ticket.project }
42
+ opts.merge!(ticket_id: ticket.ticket_id) if ticket.ticket_id.present?
43
+ opts
44
+ end
45
+
46
+ def build_sysparm_query(opts)
47
+ sysparm_query = {
48
+ 'u_support_fieldLIKE' => opts[:service_desk],
49
+ 'u_input_source=' => 'OIV',
50
+ '' => opts.fetch(:states, '').split(',').map { |st| "state=#{st}" }.join('^OR')
51
+ }
52
+ sysparm_query.select { |_, v| v.present? }.map { |k, v| [k, v].join }.join('^')
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,120 @@
1
+ module TicketAbstractorClient
2
+ module ServiceNow
3
+ class Ticket < Base::Ticket
4
+
5
+ def self.fetch_by_id(opts)
6
+ fetch(:by_id, opts).first
7
+ end
8
+
9
+ def self.fetch_all_tickets(opts)
10
+ fetch(:all, opts)
11
+ end
12
+
13
+ def self.fetch_tickets_by_query(opts)
14
+ fetch(:by_query, opts)
15
+ end
16
+
17
+ def initialize(opts = {})
18
+ super(opts)
19
+ @project = opts[:project] || raise(Errors::TicketArgumentError, 'Project is not given')
20
+ @status = @fields.delete('state')
21
+ end
22
+
23
+ def add_attachment(attachment)
24
+ @attachments << Attachment.new(attachment.merge!(ticket_id: @ticket_id, endpoint: @endpoint))
25
+ @changes[:new_attachments] += 1
26
+ self
27
+ end
28
+
29
+ def add_comment(comment)
30
+ @comments << Comment.new(comment.merge!(ticket_id: @ticket_id, endpoint: @endpoint))
31
+ @changes[:new_comments] += 1
32
+ self
33
+ end
34
+
35
+ def attachments
36
+ return @attachments if @attachments.present?
37
+
38
+ return [] if @ticket_id.blank? && @attachments.blank?
39
+
40
+ @attachments = Attachment.fetch(@ticket_id, @endpoint)
41
+ end
42
+
43
+ def comments
44
+ return @comments if @comments.present?
45
+
46
+ return [] if @ticket_id.blank? && @comments.blank?
47
+
48
+ @comments = Comment.fetch(@ticket_id, @endpoint)
49
+ end
50
+
51
+ def sync!
52
+ raise TicketArgumentError, 'No changes to apply' unless self.any_changes?
53
+ return create_ticket if @changes[:create]
54
+ update_ticket if @changes[:update]
55
+ update_status if @changes[:new_status]
56
+ sync_comments unless @changes[:new_comments].zero?
57
+ sync_attachments unless @changes[:new_attachments].zero?
58
+ reset_changes!
59
+ end
60
+
61
+ def updated_at
62
+ @fields['sys_updated_on']
63
+ end
64
+
65
+ private
66
+
67
+ # selektor -- all, by_id, by_query
68
+ # Ticket.fetch(:all, opts)
69
+ # Ticket.fetch(:by_id, opts)
70
+ # Ticket.fetch(:by_query, opts)
71
+ def self.fetch(selektor, opts)
72
+ opts = opts.with_indifferent_access
73
+ endpoint = opts.delete(:endpoint)
74
+ method_map = { all: :get_all_tickets, by_id: :get_ticket_by_id, by_query: :get_tickets_by_query }
75
+ client_response = Client.new(endpoint).public_send(method_map.fetch(selektor.to_sym), opts)
76
+
77
+ Array.wrap(client_response).map do |hash|
78
+ fields = filter_fields(hash)
79
+ ticket = new(ticket_id: opts[:ticket_id], fields: fields, endpoint: endpoint, project: opts[:table_name])
80
+ ticket.reset_changes!
81
+ ticket
82
+ end
83
+ end
84
+
85
+ def self.filter_fields(fields)
86
+ filter_fields_klass = TicketAbstractorClient.configuration.snow_fields_filter_class
87
+
88
+ return fields if filter_fields_klass.blank?
89
+
90
+ filter_fields_klass.new(fields).filter_fields
91
+ end
92
+
93
+ def create_ticket
94
+ response = Client.new(@endpoint).create_ticket(self)
95
+ ticket = Ticket.fetch_by_id(ticket_id: response['number'], table_name: @project, endpoint: @endpoint)
96
+ @fields = ticket.fields
97
+ @status = ticket.status
98
+ reset_changes!
99
+ end
100
+
101
+ def update_status
102
+ @fields['state'] = @status
103
+ update_ticket
104
+ end
105
+
106
+ def update_ticket
107
+ response = Client.new(@endpoint).update_ticket(self)
108
+ @fields['sys_updated_on'] = response['sys_updated_on']
109
+ end
110
+
111
+ def sync_attachments
112
+ @attachments.last(@changes[:new_attachments]).map(&:sync!)
113
+ end
114
+
115
+ def sync_comments
116
+ @comments.last(@changes[:new_comments]).map(&:sync!)
117
+ end
118
+ end
119
+ end
120
+ end
@@ -1,3 +1,3 @@
1
1
  module TicketAbstractorClient
2
- VERSION = '1.29.0'
2
+ VERSION = '2.0.0'
3
3
  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: 1.29.0
4
+ version: 2.0.0
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-02-10 00:00:00.000000000 Z
12
+ date: 2017-02-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -53,6 +53,34 @@ dependencies:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
55
  version: 2.0.0
56
+ - !ruby/object:Gem::Dependency
57
+ name: activesupport
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: 4.2.7
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: 4.2.7
70
+ - !ruby/object:Gem::Dependency
71
+ name: mime-types
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: 1.25.1
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: 1.25.1
56
84
  description: Get access to Jira and Brouha ticketing systems through the single service
57
85
  email:
58
86
  - rsamoilov@productengine.com
@@ -63,13 +91,28 @@ extra_rdoc_files: []
63
91
  files:
64
92
  - README.md
65
93
  - lib/ticket_abstractor_client.rb
66
- - lib/ticket_abstractor_client/brouha_client.rb
67
- - lib/ticket_abstractor_client/client.rb
68
- - lib/ticket_abstractor_client/i_logger_client.rb
69
- - lib/ticket_abstractor_client/itrc_client.rb
70
- - lib/ticket_abstractor_client/jira_client.rb
71
- - lib/ticket_abstractor_client/service_now_client.rb
72
- - lib/ticket_abstractor_client/sev_one_client.rb
94
+ - lib/ticket_abstractor_client/base/attachment.rb
95
+ - lib/ticket_abstractor_client/base/client.rb
96
+ - lib/ticket_abstractor_client/base/comment.rb
97
+ - lib/ticket_abstractor_client/base/errors.rb
98
+ - lib/ticket_abstractor_client/base/fields_filter.rb
99
+ - lib/ticket_abstractor_client/base/response_handler.rb
100
+ - lib/ticket_abstractor_client/base/ticket.rb
101
+ - lib/ticket_abstractor_client/client_helper.rb
102
+ - lib/ticket_abstractor_client/configuration.rb
103
+ - lib/ticket_abstractor_client/jira/attachment.rb
104
+ - lib/ticket_abstractor_client/jira/client.rb
105
+ - lib/ticket_abstractor_client/jira/comment.rb
106
+ - lib/ticket_abstractor_client/jira/errors.rb
107
+ - lib/ticket_abstractor_client/jira/fields_meta.rb
108
+ - lib/ticket_abstractor_client/jira/params_builder.rb
109
+ - lib/ticket_abstractor_client/jira/ticket.rb
110
+ - lib/ticket_abstractor_client/service_now/attachment.rb
111
+ - lib/ticket_abstractor_client/service_now/client.rb
112
+ - lib/ticket_abstractor_client/service_now/comment.rb
113
+ - lib/ticket_abstractor_client/service_now/errors.rb
114
+ - lib/ticket_abstractor_client/service_now/params_builder.rb
115
+ - lib/ticket_abstractor_client/service_now/ticket.rb
73
116
  - lib/ticket_abstractor_client/version.rb
74
117
  homepage: https://github.comcast.com/opsint/ticket-abstractor-client
75
118
  licenses: