tehportal 0.1.0 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +4 -87
- data/app/controllers/remedy_controller.rb +6 -2
- data/lib/tehportal/operation.rb +19 -2
- data/lib/tehportal/remedy_client.rb +45 -13
- data/lib/tehportal/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 89c7023c36b3c4aaf5d169c02278e63f57ebbe08
|
4
|
+
data.tar.gz: b671e3f9bd9a34c230f865e78560bb2598179d15
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce27c58dc530915a96c0c2a99bf57d52cf4c22c562e658b62eb5e8ef1fb826f60d625e1b5de22bf333e28d4082c3fc42f2683b32a556ad8f4a5ae3bda9ded389
|
7
|
+
data.tar.gz: f698526fb5feefedd5d9c1925b5a768f9eecb841ffa9c7aabb14e0f351933939b6e1f44e2d3c5e46fcddbea23ecbaff8ea3777c0d828a75ef5644308b79571f3
|
data/README.md
CHANGED
@@ -3,30 +3,6 @@
|
|
3
3
|
## Описание
|
4
4
|
Данный gem это ядро для работы с remedy и возможно с другими системами.
|
5
5
|
|
6
|
-
## Модели
|
7
|
-
Все сервиси группируем - инциденты, изменения, проблемы, задачи и тд. Для каждой группы делаем модель с базовым классом - **Tehportal::Model**.
|
8
|
-
В модели делаем описание всех сервисов в виде хэша:
|
9
|
-
|
10
|
-
@@services = {
|
11
|
-
show: 'ATC:HPD:AKEOS-Portal-Get-Incident-WorkInfo',
|
12
|
-
list: 'ATC:INC:AKEOS-List',
|
13
|
-
create: 'ATC:INC:AKEOS-Create',
|
14
|
-
update: 'ATC:INC:AKEOS-Modify'
|
15
|
-
}
|
16
|
-
|
17
|
-
Где ключ данного хэша будет соответствовать action-методу в соответствующем контроллере.
|
18
|
-
Также в базовом классе моделе реализован запрос к серверу(сейчас через method_missing, после рефакторинга с помощью class_eval).
|
19
|
-
Модели называем во множественном числе(например: Tehportal::Incidents), чтобы соответствовало названию контроллера.
|
20
|
-
|
21
|
-
**ВАЖНО:** Т.к. в remedy важен порядок передаваемых ему полей в моделе реализован механизм, который расставляем параметры в нжном порядке. Нужно просто передать параметры.
|
22
|
-
|
23
|
-
### 1.Инциденты
|
24
|
-
Модель: **Tehportal::Incidents**
|
25
|
-
### 2.Изменения
|
26
|
-
### 3.Проблемы
|
27
|
-
Модель: **Tehportal::Problems**
|
28
|
-
### 4.Релизы
|
29
|
-
|
30
6
|
## Контроллеры/API
|
31
7
|
Все контроллеры для работы с remedy наследуются от **RemedyBaseController**. Перед запуском любого action-метода срабатывает хук который отпределяет
|
32
8
|
с какой моделью работать данному контроллеру.
|
@@ -36,69 +12,6 @@
|
|
36
12
|
Базовый url: _/tp/remedy_
|
37
13
|
|
38
14
|
Параметры который пойдут на вход Remedy передаются в массиве data (пример: data[ID]=23&data[Description]=New_Message)
|
39
|
-
Для action может быть несколько операций, они передаются параметром operation(пример: operation=INCGetList-InWork)
|
40
|
-
|
41
|
-
### 1.Инциденты
|
42
|
-
#### Список инцидентов
|
43
|
-
|
44
|
-
*URL:* GET /incidents/
|
45
|
-
|
46
|
-
|Операция|Описание|Параметры|
|
47
|
-
|--------|--------|---------|
|
48
|
-
| _INCGetList-InWork_ | Назначенные на меня со статусом "открытые" |startRecord - offset для списка<br /> maxLimit - limit для списка<br />Login - логин пользователя|
|
49
|
-
| _INCGetList-SLABreached-My_ | Назначенные на меня со статусом "нарушенные" |startRecord - offset для списка<br /> maxLimit - limit для списка<br />Login - логин пользователя|
|
50
|
-
| _INCGetList-Pending-My_ | Назначенные на меня со статусом "в ожидании" |startRecord - offset для списка<br /> maxLimit - limit для списка<br />Login - логин пользователя|
|
51
|
-
| _INC_Created_By_Me_InWork_ | Созданные мной |startRecord - offset для списка<br /> maxLimit - limit для списка<br />Login - логин пользователя|
|
52
|
-
| _INCGetList-SLABreached-OnMyGroup_ | Назначенные на группу со статусом "просроченные"|startRecord - offset для списка<br /> maxLimit - limit для списка<br />Group - Название группы|
|
53
|
-
| _INCGetList-InWork-OnMyGroup_ | Назначенные на группу со статусом "открытые"|startRecord - offset для списка<br /> maxLimit - limit для списка<br />Group - Название группы|
|
54
|
-
| _NCGetList-Pending-OnMyGroup_ | Назначенные на группу со статусом "в ожидании" |startRecord - offset для списка<br /> maxLimit - limit для списка<br />Group - Название группы|
|
55
|
-
|
56
|
-
##### *URL:* GET /incidents/:id - Просмотр инцидента
|
57
|
-
##### *URL:* GET /incidents/:id/associations - Просмотр инцидента: свзяи
|
58
|
-
##### *URL:* GET /incidents/:id/tasks - Просмотр инцидента: задачи
|
59
|
-
##### *URL:* GET /incidents/:id/times - Просмотр инцидента: затраченное время
|
60
|
-
|
61
|
-
### 2.Задачи
|
62
|
-
#### Список задач
|
63
|
-
|
64
|
-
*URL:* GET /tasks/
|
65
|
-
|
66
|
-
|Операция|Описание|Параметры|
|
67
|
-
|--------|--------|---------|
|
68
|
-
| _TSK_My_InWork_ | Назначенные на меня со статусом "открытые" |startRecord - offset для списка<br /> maxLimit - limit для списка<br />Login - логин пользователя|
|
69
|
-
| _TSK_Created_By_Me_InWork_ | Созданные мной |startRecord - offset для списка<br /> maxLimit - limit для списка<br />Login - логин пользователя|
|
70
|
-
| _TSK_OnMyGroup_InWork_ | Назначенные на группу со статусом "открытые"|startRecord - offset для списка<br /> maxLimit - limit для списка<br />Group - Название группы|
|
71
|
-
|
72
|
-
##### *URL:* GET /incidents/:id - Просмотр задачи
|
73
|
-
##### *URL:* GET /tasks/:id/comments - Просмотр задачи: комментарии
|
74
|
-
##### *URL:* GET /tasks/:id/times - Просмотр задачи: затраченное время
|
75
|
-
|
76
|
-
|
77
|
-
### 3.Изменения
|
78
|
-
### 4.Проблемы
|
79
|
-
Контроллер: **ProblemsController**
|
80
|
-
Методы:
|
81
|
-
|
82
|
-
* list
|
83
|
-
|
84
|
-
команда:
|
85
|
-
`GET /tp/remedy/problems?operation=[операция]`
|
86
|
-
|
87
|
-
операции:
|
88
|
-
|
89
|
-
- InWorkMy
|
90
|
-
- InWorkGroup
|
91
|
-
- InWorkAllGroups
|
92
|
-
|
93
|
-
* show
|
94
|
-
команда:
|
95
|
-
`GET /tp/remedy/problems/[id]`
|
96
|
-
|
97
|
-
* create
|
98
|
-
команда:
|
99
|
-
`POST /tp/remedy/problems`
|
100
|
-
|
101
|
-
### 5.Релизы
|
102
15
|
|
103
16
|
# Установка
|
104
17
|
|
@@ -109,9 +22,13 @@
|
|
109
22
|
1. В приложении необходимо создать инициализатор gem'а:
|
110
23
|
|
111
24
|
`Tehportal.configure do |config|
|
25
|
+
|
112
26
|
config.url = 'http://example.com'
|
27
|
+
|
113
28
|
config.server = 'example-server'
|
29
|
+
|
114
30
|
config.endpoint = 'http://example.com/services/ARService'
|
31
|
+
|
115
32
|
end`
|
116
33
|
|
117
34
|
1. Роутинг:
|
@@ -50,8 +50,12 @@ class RemedyController < Tehportal.config.parent_controller.constantize
|
|
50
50
|
private
|
51
51
|
|
52
52
|
def render_remedy_json(data)
|
53
|
-
|
54
|
-
|
53
|
+
if data.is_a? Array
|
54
|
+
render json: data
|
55
|
+
else
|
56
|
+
prepared = data.except!('@xmlns:ns0', '@xmlns:xsd', '@xmlns:xsi')
|
57
|
+
render json: (prepared.blank? && data.length != 3) ? {} : prepared
|
58
|
+
end
|
55
59
|
end
|
56
60
|
|
57
61
|
end
|
data/lib/tehportal/operation.rb
CHANGED
@@ -20,10 +20,27 @@ module Operation
|
|
20
20
|
|
21
21
|
# Добавляем синглтон метод к классу модели
|
22
22
|
define_singleton_method(name) do |*args|
|
23
|
+
args[0] ||= {}
|
23
24
|
client = args[0].delete(:client) || Tehportal.client
|
24
25
|
message = options[:defaults].merge(args[0])
|
25
|
-
|
26
|
-
|
26
|
+
|
27
|
+
unless options[:cache] and result = Rails.cache.fetch([:tehportal, service, operation, message])
|
28
|
+
result = client.request(service, operation, message)
|
29
|
+
if options[:cache] and !result.include?(:errorMessage)
|
30
|
+
Rails.cache.write([:tehportal, service, operation, message], result, expires_in: options[:cache])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
if options[:as] == :list
|
35
|
+
if result.include?(:errorMessage)
|
36
|
+
if result[:errorMessage] =~ /^ERROR \(302\)/
|
37
|
+
result = []
|
38
|
+
end
|
39
|
+
else
|
40
|
+
result = Array.wrap(result['getListValues'] || [result])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
result
|
27
44
|
end
|
28
45
|
end
|
29
46
|
end
|
@@ -1,10 +1,12 @@
|
|
1
1
|
module Tehportal
|
2
2
|
class RemedyClient
|
3
|
-
|
3
|
+
attr_reader :config
|
4
4
|
|
5
|
-
def initialize(login = nil, password = nil)
|
5
|
+
def initialize(login = nil, password = nil, **config_override)
|
6
6
|
@login, @password = login, password
|
7
7
|
@definitions = Rails.cache.read('tp.remedy.definitions') || {}
|
8
|
+
@config = Tehportal.config
|
9
|
+
config_override.each {|k, v| @config.send "#{k}=", v}
|
8
10
|
end
|
9
11
|
|
10
12
|
# Выполнение запроса к сервису
|
@@ -15,6 +17,7 @@ module Tehportal
|
|
15
17
|
# e.g.: {"Status" => "Pending"}
|
16
18
|
def request(service, method, body = {})
|
17
19
|
message = {}
|
20
|
+
body = body.with_indifferent_access
|
18
21
|
operation_map = operation_map(service, method)
|
19
22
|
|
20
23
|
operation_map[:input].each do |key|
|
@@ -32,7 +35,7 @@ module Tehportal
|
|
32
35
|
log: true,
|
33
36
|
logger: Rails.logger,
|
34
37
|
log_level: :debug,
|
35
|
-
filters: [:password])
|
38
|
+
filters: [:password, *[1,2,3].map {|i| :"z2AF_Work_Log0#{i}_attachmentData"}, *[1,2,3].map {|i| :"WLG_Attach#{i}_File"}])
|
36
39
|
|
37
40
|
response = client.call(method, message: message, soap_action: "urn:#{service}/#{method}", advanced_typecasting: false)
|
38
41
|
|
@@ -67,6 +70,41 @@ module Tehportal
|
|
67
70
|
|
68
71
|
@definitions[service]
|
69
72
|
end
|
73
|
+
|
74
|
+
# Хелперы для #operations_map и, в частности, для дебага не очень прямых сервисов
|
75
|
+
def operation_fields(op_name, elements: nil, types: nil)
|
76
|
+
unless elements and types
|
77
|
+
unless op_name['/']
|
78
|
+
raise ArgumentError, 'Нужно передать либо полное имя сервиса, e.g. ATC:FoundationCatalogs/SupportGroups, либо :elements и :types'
|
79
|
+
end
|
80
|
+
service, op_name = op_name.split '/'
|
81
|
+
elements, types = elements_and_types(service)
|
82
|
+
end
|
83
|
+
type_name = elements.find {|e| e['@name'] == op_name}['@type'].sub(/^[^:]+:/, '')
|
84
|
+
type_input = types.find {|t| t['@name'] == type_name}['sequence'] || {}
|
85
|
+
Array.wrap(type_input['element'])
|
86
|
+
end
|
87
|
+
|
88
|
+
def definition_schema(defs)
|
89
|
+
schema = defs['types'].blank? ? {} : defs['types']['schema']
|
90
|
+
if schema.is_a? Array # для Ремеди Росреестра; у сибирского всегда только 1 schema
|
91
|
+
main_schema = schema[0]
|
92
|
+
schema.sum(&:keys).uniq.each {|k|
|
93
|
+
unless k['@']
|
94
|
+
main_schema[k] = schema.sum {|i| Array.wrap(i[k])}
|
95
|
+
end
|
96
|
+
}
|
97
|
+
main_schema
|
98
|
+
else
|
99
|
+
schema
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def elements_and_types(service)
|
104
|
+
schema = definition_schema(definitions(service))
|
105
|
+
[Array.wrap(schema['element']),
|
106
|
+
Array.wrap(schema['complexType'])]
|
107
|
+
end
|
70
108
|
|
71
109
|
# Определение доступных операций и их характеристик
|
72
110
|
# в соответствии с wsdl:definition по указанному сервису
|
@@ -75,10 +113,8 @@ module Tehportal
|
|
75
113
|
# e.g.: ATC:INC:AKEOS-List
|
76
114
|
def operations_map(service)
|
77
115
|
defs = definitions(service)
|
78
|
-
|
116
|
+
elements, types = elements_and_types(service)
|
79
117
|
messages = Array.wrap(defs['message'])
|
80
|
-
elements = Array.wrap(schema['element'])
|
81
|
-
types = Array.wrap(schema['complexType'])
|
82
118
|
operations = Array.wrap(defs['portType']['operation'])
|
83
119
|
|
84
120
|
res = operations.map do |op|
|
@@ -90,14 +126,10 @@ module Tehportal
|
|
90
126
|
# undasherize для удобства обхода (совместимо с текущим кодом)
|
91
127
|
element_name.tr! '-', '_'
|
92
128
|
|
93
|
-
|
94
|
-
|
95
|
-
if type_input
|
96
|
-
fields = Array.wrap(type_input['element'])
|
97
|
-
field_names = fields.map {|f| f['@name']}
|
98
|
-
end
|
129
|
+
fields = operation_fields op_name, elements: elements, types: types
|
130
|
+
field_names = fields.map {|f| f['@name']}
|
99
131
|
|
100
|
-
[op_name, {output: element_name, input:
|
132
|
+
[op_name, {output: element_name, input: field_names}]
|
101
133
|
end
|
102
134
|
|
103
135
|
Hash[res]
|
data/lib/tehportal/version.rb
CHANGED