huginn_record_link_agent 1.1.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.
- checksums.yaml +7 -0
- data/LICENSE.txt +7 -0
- data/lib/huginn_record_link_agent.rb +7 -0
- data/lib/huginn_record_link_agent/engine.rb +6 -0
- data/lib/huginn_record_link_agent/record_link_agent.rb +480 -0
- data/spec/record_link_agent_spec.rb +13 -0
- metadata +92 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b22216e5476990eb8c5d7d172714c305eda08b05
|
4
|
+
data.tar.gz: 5e26a8864f5abd30b59a77ad9eeb64377d256de7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7406438bd05bc4dab39f8f29d6c1686305787974bc748403a3d5eb4157cdce4e227f5a1c2ec26a5bd3d03f80c2fbd3b432a6a34252019b48fe3286023ce63f75
|
7
|
+
data.tar.gz: 2359d01fd5b259e7178923dc8b903134b48790f456911d8f84b4345654543c2a31678314d3e5dad8b4f6ab3eada863d475067de2566785bc649de8dacbb59a65
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright (c) 2019 Jacob Spizziri
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,480 @@
|
|
1
|
+
module Agents
|
2
|
+
class RecordLinkAgent < Agent
|
3
|
+
|
4
|
+
can_dry_run!
|
5
|
+
no_bulk_receive!
|
6
|
+
default_schedule "never"
|
7
|
+
|
8
|
+
description do
|
9
|
+
<<-MD
|
10
|
+
This agent manages bi-directional links between systems that lack viable support for external ID fields.
|
11
|
+
|
12
|
+
## Agent Options
|
13
|
+
|
14
|
+
- `create_link` - When `true`, this agent will create a link between a source and target record. When false, this agent will simple look for matching record links.
|
15
|
+
- `lookup_type` - One of `source`, `target`, `both`. Determines which link type to retrieve
|
16
|
+
- `emit_each` - When `true`, each linked record will be emitted as a single event
|
17
|
+
- `emit_events` - Setting this to `true` will result in the generated RecordLink being emitted as an Event which can be subsequently consumed by another agent
|
18
|
+
- `output_mode` - Setting this value to `merge` will result in the emitted Event being merged into the original contents of the received Event. Setting it to `clean` will result in no merge.
|
19
|
+
|
20
|
+
###Create Record Link
|
21
|
+
Link creation leverages Rails `find_or_create_by` to avoid errors. This allows users to inject a link creation into their existing
|
22
|
+
flow without requiring trigger agents that check to see whether a link already exists. In most implementations, this check will have
|
23
|
+
run earlier in the flow (prior to upserting records to the external system)
|
24
|
+
|
25
|
+
**Required Options:**
|
26
|
+
- `source_system` - The source/authority for the record in question
|
27
|
+
- `source_type` - The record type in the source system
|
28
|
+
- `source_id` - The record ID (or an array of IDs) from the source system
|
29
|
+
- `target_system` - The system the source record is being sent to
|
30
|
+
- `target_type` - The record type in the target system
|
31
|
+
- `target_id` - The record ID (or array of IDs) in the target system
|
32
|
+
- `create_link` - Set to `true`
|
33
|
+
|
34
|
+
**Additional Notes:**
|
35
|
+
`target_id` and `source_id` can be set to an array in order to link multiple records together in a single execution.
|
36
|
+
In such cases, link creation will be wrapped in a transaction. The agent will only emit a successful event if all links
|
37
|
+
are created without error. If any of the links fail, a failure status will be emitted.
|
38
|
+
|
39
|
+
If _both_ `target_id` and `source_id` are arrays, then _all_ provided source records will be linked to _all_ provided targets
|
40
|
+
|
41
|
+
###Find Target Record Links
|
42
|
+
|
43
|
+
**Required Options:**
|
44
|
+
|
45
|
+
- `source_system` - The source/authority for the record in question
|
46
|
+
- `source_type` - The record type in the source system
|
47
|
+
- `source_id` - The record ID(or array of IDs) from the source system
|
48
|
+
|
49
|
+
**Optional Filters/Settings:**
|
50
|
+
- `target_system` - Only return matches from the specified system
|
51
|
+
- `target_type` - Only return matches of the specified type (**Note:** When set, `target_system` is required)
|
52
|
+
- `create_link` - Set to `false`. This value defaults to `false` if not provided
|
53
|
+
- `require_all` - If `true`, this Agent will only emit a successful event if a matching target is found for all provided source_id values
|
54
|
+
|
55
|
+
**Additional Notes:**
|
56
|
+
If `source_id` is an array and `require_all` is `true`, this Agent will ensure that at least one matching target exists for each
|
57
|
+
provided source. If any source is missing a target, then a 404 - Links Missing event will be emitted.
|
58
|
+
|
59
|
+
###Find Source Record Links
|
60
|
+
|
61
|
+
**Required Options:**
|
62
|
+
|
63
|
+
- `target_system` - The system the record was sent to
|
64
|
+
- `target_type` - The record type in the target system
|
65
|
+
- `target_id` - The record ID (or array of IDs) from the target system
|
66
|
+
|
67
|
+
**Optional Filters/Options:**
|
68
|
+
- `source_system` - Only return matches from the specified system
|
69
|
+
- `source_type` - Only return matches of the specified type (**Note:** When set, `target_system` is required)
|
70
|
+
- `create_link` - Set to `false`. This value defaults to `false` if not provided
|
71
|
+
- `require_all` - If `true`, this Agent will only emit a successful event if a matching source is found for all provided target_id values
|
72
|
+
|
73
|
+
**Additional Notes:**
|
74
|
+
If `target_id` is an array and `require_all` is `true`, this Agent will ensure that at least one matching source exists for each
|
75
|
+
provided target. If any source is missing a target, then a 404 - Links Missing event will be emitted.
|
76
|
+
|
77
|
+
###Find All Record Links
|
78
|
+
|
79
|
+
**Required Options:**
|
80
|
+
|
81
|
+
- `record_system` - The system containing the record
|
82
|
+
- `record_type` - The record type in the specified system
|
83
|
+
- `record_id` - The ID of the record
|
84
|
+
- `create_link` - Set to `false`. This value defaults to `false` if not provided
|
85
|
+
|
86
|
+
**Optional Filters:**
|
87
|
+
|
88
|
+
- `system_filter` - Only return links to or from the specified system
|
89
|
+
- `type_filter` - Only return links to or from the specified type
|
90
|
+
|
91
|
+
###Hard Errors vs Soft Errors
|
92
|
+
This agent issues two distinct error statuses: `404` and `500`.
|
93
|
+
|
94
|
+
A `404` is treated like a soft error. These errors will be reported for
|
95
|
+
debugging purposes, but they will not result in a task failure unless the
|
96
|
+
`require_all` parameter is set to true.
|
97
|
+
|
98
|
+
If `emit_each` is set to `true`, and `emit_events` is `true`, soft errors
|
99
|
+
will be emitted individually with a `link_status` of `404`. If `emit_each`
|
100
|
+
is false, a single error will be emitted with a `link_status` of `404` and
|
101
|
+
an array of each individua error.
|
102
|
+
|
103
|
+
A `500` status is considered a critical failure and is only issued when
|
104
|
+
unexpected errors are encountered during processing (usually related to
|
105
|
+
database interactions) If a critical error is encountered, this will always
|
106
|
+
result in a task failure.
|
107
|
+
|
108
|
+
When a 500 error occurs, if `emit_events` is `true`, then all errors
|
109
|
+
encountered during processing will be consolidated in to a single `link_error`
|
110
|
+
payload with a `link_status` of `500`.
|
111
|
+
|
112
|
+
**NOTE:** If `emit_each` is `true`, the option
|
113
|
+
is ignored when a 500 error occurs.
|
114
|
+
|
115
|
+
### Recommended Usage
|
116
|
+
|
117
|
+
Traditionally bi-directional relationships work because one knows both endpoints in
|
118
|
+
the relationship, and associated tables are defined accordingly, but in this case,
|
119
|
+
the endpoints are unknwon. As a result, some sense of direction must be maintained
|
120
|
+
in order to accurately identify what the link represents.
|
121
|
+
|
122
|
+
When linking records together with this agent, it is up to the user to maintain
|
123
|
+
knowledge of that direction. As a general rule of thumb, it is recommended that the
|
124
|
+
`source` fields be defined as the authority/origin point of the data and the `target`
|
125
|
+
fields be identified as the destination of the data.
|
126
|
+
|
127
|
+
In the case of an integration between an eCommerce platform and an external product
|
128
|
+
catalog, the product catalog would be considered the `source` for product and category
|
129
|
+
information as it is likely the authority on all product/category information.
|
130
|
+
|
131
|
+
**Regarding require_all:**
|
132
|
+
When looking up source or target records, if `require_all` is set to `true`, it is recommended that `emit_each` be omitted
|
133
|
+
(or explicitly set to `false`) so that further operations can be performed on the entire batch of matched records.
|
134
|
+
MD
|
135
|
+
end
|
136
|
+
|
137
|
+
event_description <<-MD
|
138
|
+
|
139
|
+
When `emit_each` is set to `true`, events look like this:
|
140
|
+
|
141
|
+
{
|
142
|
+
record_link {
|
143
|
+
link_status: "200",
|
144
|
+
source_system: "source_system",
|
145
|
+
source_type: "source_type",
|
146
|
+
source_id: 123,
|
147
|
+
target_system: "target_system",
|
148
|
+
target_type: "target_type",
|
149
|
+
target_id: "target_id"
|
150
|
+
}
|
151
|
+
}
|
152
|
+
|
153
|
+
When `emit_each` is set to `false`, events look like this:
|
154
|
+
|
155
|
+
```
|
156
|
+
{
|
157
|
+
"record_link": {
|
158
|
+
"link_status": "200",
|
159
|
+
"system": "system",
|
160
|
+
"type": "type",
|
161
|
+
"record_id": 123,
|
162
|
+
"targets": [
|
163
|
+
{
|
164
|
+
"target_system": "system",
|
165
|
+
"target_type": "type",
|
166
|
+
"target_id": 123
|
167
|
+
},
|
168
|
+
{ ... }
|
169
|
+
],
|
170
|
+
"sources": [
|
171
|
+
{
|
172
|
+
"source_system": "system",
|
173
|
+
"source_type": "type",
|
174
|
+
"source_id": 123
|
175
|
+
},
|
176
|
+
{ ... }
|
177
|
+
]
|
178
|
+
}
|
179
|
+
}
|
180
|
+
|
181
|
+
On error, events look like this:
|
182
|
+
|
183
|
+
{
|
184
|
+
"record_link": {
|
185
|
+
"link_status": "...",
|
186
|
+
"link_errors": [...]
|
187
|
+
}
|
188
|
+
}
|
189
|
+
|
190
|
+
```
|
191
|
+
Original event contents will be merged when `output_mode` is set to `merge`.
|
192
|
+
MD
|
193
|
+
|
194
|
+
def default_options
|
195
|
+
{
|
196
|
+
'expected_receive_period_in_days' => '1',
|
197
|
+
'source_system' => 'Target System',
|
198
|
+
'source_type' => 'Target Model',
|
199
|
+
'source_id' => '123',
|
200
|
+
'target_system' => 'Target System',
|
201
|
+
'target_type' => 'Target Type',
|
202
|
+
'target_id' => '123',
|
203
|
+
'create_link' => 'true',
|
204
|
+
'emit_each' => 'true',
|
205
|
+
'emit_events' => 'true',
|
206
|
+
'output_mode' => 'clean',
|
207
|
+
}
|
208
|
+
end
|
209
|
+
|
210
|
+
def working?
|
211
|
+
return false if recent_error_logs?
|
212
|
+
|
213
|
+
if interpolated['expected_receive_period_in_days'].present?
|
214
|
+
return false unless last_receive_at && last_receive_at > interpolated['expected_receive_period_in_days'].to_i.days.ago
|
215
|
+
end
|
216
|
+
|
217
|
+
true
|
218
|
+
end
|
219
|
+
|
220
|
+
def validate_options
|
221
|
+
|
222
|
+
if options.has_key?('emit_each') && boolify(options['emit_each']).nil?
|
223
|
+
errors.add(:base, 'when provided, `emit_each` bust be either true or false')
|
224
|
+
end
|
225
|
+
|
226
|
+
if options.has_key?('emit_events') && boolify(options['emit_events']).nil?
|
227
|
+
errors.add(:base, "if provided, emit_events must be true or false")
|
228
|
+
end
|
229
|
+
|
230
|
+
if options['output_mode'].present? && !options['output_mode'].to_s.include?('{') && !%[clean merge].include?(options['output_mode'].to_s)
|
231
|
+
errors.add(:base, "if provided, output_mode must be 'clean' or 'merge'")
|
232
|
+
end
|
233
|
+
|
234
|
+
if options.has_key?('create_link') && boolify(options['create_link'])
|
235
|
+
self.validate_create_params
|
236
|
+
|
237
|
+
elsif options.has_key?('lookup_type')
|
238
|
+
if options['lookup_type'] == 'source'
|
239
|
+
self.validate_source_lookup_params
|
240
|
+
|
241
|
+
elsif options['lookup_type'] == 'target'
|
242
|
+
self.validate_target_lookup_params
|
243
|
+
|
244
|
+
elsif options['lookup_type'] == 'all'
|
245
|
+
self.validate_all_lookup_params
|
246
|
+
|
247
|
+
else
|
248
|
+
errors.add(:base, "when provided, `lookup_type` must be one of `source`, `target` or `all`")
|
249
|
+
end
|
250
|
+
|
251
|
+
else
|
252
|
+
# By default, this agent returns ALL record links
|
253
|
+
self.validate_all_lookup_params
|
254
|
+
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
def validate_create_params
|
259
|
+
|
260
|
+
if options.has_key?('emit_each') && !boolify(options['emit_each'])
|
261
|
+
errors.add(:base, "when `create_link` is true, `emit_each` must be true if provided")
|
262
|
+
end
|
263
|
+
|
264
|
+
unless options['source_system'].present?
|
265
|
+
errors.add(:base, "when creating record links `source_system` is a required field")
|
266
|
+
end
|
267
|
+
|
268
|
+
unless options['source_type'].present?
|
269
|
+
errors.add(:base, "when creating record links `source_type` is a required field")
|
270
|
+
end
|
271
|
+
|
272
|
+
unless options['source_id'].present?
|
273
|
+
errors.add(:base, "when creating record links `source_id` is a required field")
|
274
|
+
end
|
275
|
+
|
276
|
+
unless options['target_system'].present?
|
277
|
+
errors.add(:base, "when creating record links `target_system` is a required field")
|
278
|
+
end
|
279
|
+
|
280
|
+
unless options['target_type'].present?
|
281
|
+
errors.add(:base, "when creating record links `target_type` is a required field")
|
282
|
+
end
|
283
|
+
|
284
|
+
unless options['target_id'].present?
|
285
|
+
errors.add(:base, "when creating record links `target_id` is a required field")
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
def validate_target_lookup_params
|
290
|
+
unless options['source_system'].present?
|
291
|
+
errors.add(:base, "when fetching target links `source_system` is a required field")
|
292
|
+
end
|
293
|
+
|
294
|
+
unless options['source_type'].present?
|
295
|
+
errors.add(:base, "when fetching target links `source_type` is a required field")
|
296
|
+
end
|
297
|
+
|
298
|
+
unless options['source_id'].present?
|
299
|
+
errors.add(:base, "when fetching target links `source_id` is a required field")
|
300
|
+
end
|
301
|
+
|
302
|
+
if options.has_key?('target_type')
|
303
|
+
unless options.has_key?('target_system')
|
304
|
+
errors.add(:base, "when looking up linked target records, if `target_type` is provided, `target_system` is required")
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
def validate_source_lookup_params
|
310
|
+
unless options['target_system'].present?
|
311
|
+
errors.add(:base, "when fetching source links `target_system` is a required field")
|
312
|
+
end
|
313
|
+
|
314
|
+
unless options['target_type'].present?
|
315
|
+
errors.add(:base, "when fetching source links `target_type` is a required field")
|
316
|
+
end
|
317
|
+
|
318
|
+
unless options['target_id'].present?
|
319
|
+
errors.add(:base, "when fetching source links `target_id` is a required field")
|
320
|
+
end
|
321
|
+
|
322
|
+
if options.has_key?('source_type')
|
323
|
+
unless options.has_key?('source_system')
|
324
|
+
errors.add(:base, "when looking up linked source records, if `source_type` is provided, `source_system` is required")
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
def validate_all_lookup_params
|
330
|
+
unless options['record_system'].present?
|
331
|
+
errors.add(:base, "when fetching all record links `record_system` is a required field")
|
332
|
+
end
|
333
|
+
|
334
|
+
unless options['record_type'].present?
|
335
|
+
errors.add(:base, "when fetching all record links `record_type` is a required field")
|
336
|
+
end
|
337
|
+
|
338
|
+
unless options['record_id'].present?
|
339
|
+
errors.add(:base, "when fetching all record links `record_id` is a required field")
|
340
|
+
end
|
341
|
+
|
342
|
+
if options.has_key?('filter_type')
|
343
|
+
unless options.has_key?('filter_system')
|
344
|
+
errors.add(:base, "If `filter_type` is provided, `filter_system` is required")
|
345
|
+
end
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
def receive(incoming_events)
|
350
|
+
incoming_events.each do |event|
|
351
|
+
|
352
|
+
data = interpolated(event)
|
353
|
+
|
354
|
+
if boolify(data['create_link'])
|
355
|
+
create_record_link(event, data)
|
356
|
+
|
357
|
+
elsif (data['lookup_type'] == 'source')
|
358
|
+
find_source_links(event, data)
|
359
|
+
|
360
|
+
elsif(data['lookup_type'] == 'target')
|
361
|
+
find_target_links(event, data)
|
362
|
+
|
363
|
+
else
|
364
|
+
find_all_links(event, data)
|
365
|
+
end
|
366
|
+
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
def create_record_link(event, data)
|
371
|
+
source_system = data['source_system']
|
372
|
+
source_type = data['source_type']
|
373
|
+
source_id = data['source_id']
|
374
|
+
|
375
|
+
target_system = data['target_system']
|
376
|
+
target_type = data['target_type']
|
377
|
+
target_id = data['target_id']
|
378
|
+
|
379
|
+
log("Creating RecordLink from #{source_system} #{source_type} #{source_id} to #{target_system} #{target_type} #{target_id}")
|
380
|
+
results = HuginnRecordLinkAgent::RecordLinkBuilder.create_links(user, source_system, source_type, source_id, target_system, target_type, target_id)
|
381
|
+
|
382
|
+
if results[:link_status] == 200
|
383
|
+
if boolify(options['emit_each']) || results[:links].length == 1
|
384
|
+
results[:links].each do |record_link|
|
385
|
+
payload = { link_status: results[:link_status] }.merge(record_link)
|
386
|
+
emit(data, event, payload) if boolify(options['emit_events'])
|
387
|
+
end
|
388
|
+
else
|
389
|
+
# :results will be a hash object with :link_status and :links keys
|
390
|
+
payload = results
|
391
|
+
emit(data, event, payload) if boolify(options['emit_events'])
|
392
|
+
end
|
393
|
+
|
394
|
+
else
|
395
|
+
# :results will be a hash object with :link_status and :error_detail keys
|
396
|
+
payload = results
|
397
|
+
emit(data, event, payload) if boolify(options['emit_events'])
|
398
|
+
end
|
399
|
+
|
400
|
+
end
|
401
|
+
|
402
|
+
def find_source_links(event, data)
|
403
|
+
# Required Params
|
404
|
+
target_system = data['target_system']
|
405
|
+
target_type = data['target_type']
|
406
|
+
target_id = data['target_id']
|
407
|
+
|
408
|
+
# Optional Filters
|
409
|
+
source_system = data['source_system']
|
410
|
+
source_type = data['source_type']
|
411
|
+
|
412
|
+
# Ensure we have an array for iteration purposes
|
413
|
+
lookup_ids = target_id.respond_to?('each') ? target_id : [target_id]
|
414
|
+
results = HuginnRecordLinkAgent::RecordLinkLookupTool.lookup_records(user, target_system, target_type, lookup_ids, source_system, source_type, 'source')
|
415
|
+
|
416
|
+
payloads = HuginnRecordLinkAgent::RecordLinkPayloadBuilder.build_payloads(results, boolify(options['emit_each']), boolify(options['require_all']))
|
417
|
+
payloads.each do |payload|
|
418
|
+
emit(data, event, payload) if boolify(options['emit_events'])
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
def find_target_links(event, data)
|
423
|
+
# Required Params
|
424
|
+
source_system = data['source_system']
|
425
|
+
source_type = data['source_type']
|
426
|
+
source_id = data['source_id']
|
427
|
+
# Optional Filters
|
428
|
+
target_system = data['target_system']
|
429
|
+
target_type = data['target_type']
|
430
|
+
|
431
|
+
# Ensure we have an array for iteration purposes
|
432
|
+
lookup_ids = source_id.respond_to?('each') ? source_id : [source_id]
|
433
|
+
results = HuginnRecordLinkAgent::RecordLinkLookupTool.lookup_records(user, source_system, source_type, lookup_ids, target_system, target_type, 'target')
|
434
|
+
log(results.inspect)
|
435
|
+
|
436
|
+
payloads = HuginnRecordLinkAgent::RecordLinkPayloadBuilder.build_payloads(results, boolify(options['emit_each']), boolify(options['require_all']))
|
437
|
+
log(payloads.inspect)
|
438
|
+
payloads.each do |payload|
|
439
|
+
emit(data, event, payload) if boolify(options['emit_events'])
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
def find_all_links(event, data)
|
444
|
+
# Required Params
|
445
|
+
record_system = data['record_system']
|
446
|
+
record_type = data['record_type']
|
447
|
+
record_id = data['record_id']
|
448
|
+
|
449
|
+
# Optional Filters
|
450
|
+
filter_system = data['filter_system']
|
451
|
+
filter_type = data['filter_type']
|
452
|
+
|
453
|
+
# Ensure we have an array for iteration purposes
|
454
|
+
lookup_ids = record_id.respond_to?('each') ? lookup_id : [lookup_id]
|
455
|
+
results = HuginnRecordLinkAgent::RecordLinkLookupTool.lookup_records(user, record_system, record_type, record_ids, filter_system, filter_type)
|
456
|
+
|
457
|
+
payloads = HuginnRecordLinkAgent::RecordLinkPayloadBuilder.build_payloads(results, boolify(options['emit_each']), boolify(options['require_all']))
|
458
|
+
payloads.each do |payload|
|
459
|
+
emit(data, event, payload) if boolify(options['emit_events'])
|
460
|
+
end
|
461
|
+
end
|
462
|
+
|
463
|
+
|
464
|
+
#--------------- UTILITY METHODS ---------------#
|
465
|
+
def emit(data, event, payload)
|
466
|
+
|
467
|
+
if (payload[:link_status] == 200)
|
468
|
+
payload = { record_link: payload }
|
469
|
+
else
|
470
|
+
payload = { link_error: payload }
|
471
|
+
end
|
472
|
+
|
473
|
+
base_event = data['output_mode'].to_s == 'merge' ? event.payload.dup : {}
|
474
|
+
payload = base_event.merge(payload)
|
475
|
+
|
476
|
+
create_event(payload: payload)
|
477
|
+
end
|
478
|
+
|
479
|
+
end
|
480
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
require 'huginn_agent/spec_helper'
|
3
|
+
|
4
|
+
describe Agents::RecordLinkAgent do
|
5
|
+
before(:each) do
|
6
|
+
@valid_options = Agents::RecordLinkAgent.new.default_options
|
7
|
+
@checker = Agents::RecordLinkAgent.new(:name => "RecordLinkAgent", :options => @valid_options)
|
8
|
+
@checker.user = users(:bob)
|
9
|
+
@checker.save!
|
10
|
+
end
|
11
|
+
|
12
|
+
pending "add specs here"
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: huginn_record_link_agent
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mike Rogers
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-01-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: huginn_agent
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description:
|
56
|
+
email:
|
57
|
+
- mrogers@weare5stones.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- LICENSE.txt
|
63
|
+
- lib/huginn_record_link_agent.rb
|
64
|
+
- lib/huginn_record_link_agent/engine.rb
|
65
|
+
- lib/huginn_record_link_agent/record_link_agent.rb
|
66
|
+
- spec/record_link_agent_spec.rb
|
67
|
+
homepage: https://github.com/5stones/huginn_http_request_agent
|
68
|
+
licenses:
|
69
|
+
- MIT
|
70
|
+
metadata: {}
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
requirements: []
|
86
|
+
rubyforge_project:
|
87
|
+
rubygems_version: 2.5.2.3
|
88
|
+
signing_key:
|
89
|
+
specification_version: 4
|
90
|
+
summary: Write a short summary, because Rubygems requires one.
|
91
|
+
test_files:
|
92
|
+
- spec/record_link_agent_spec.rb
|