flapjack 0.9.3 → 0.9.4

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.
data/.gitignore CHANGED
@@ -25,7 +25,5 @@ tmp/spec*
25
25
  tmp/profiles
26
26
  flapjack-*.gem
27
27
  _site/*
28
- .rbenv-version
29
- .ruby-version
30
28
  .rvmrc
31
29
  artifacts/*
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 1.9.3-p125
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ## Flapjack Changelog
2
2
 
3
+ # 0.9.4 - 2014-09-21
4
+ - Bug: crash in pagerduty gateway when failing entities have no id #593 (@jessereynolds)
5
+ - Bug: bugfix for updating rule data without contact_ids (no-issue) (@ali-graham)
6
+ - Bug: set key expiry properly for scheduled maintenance spanning current time #634 (@ali-graham)
7
+
3
8
  # 0.9.3 - 2014-07-28
4
9
  - Bug: fix outage reports in jsonapi c8e09f7 (@ali-graham)
5
10
  - Bug: fix maintenance reports in jsonapi 234ce48 (@ali-graham)
@@ -30,10 +30,23 @@ module Flapjack
30
30
  def self.for_event_id(event_id, options = {})
31
31
  raise "Redis connection not set" unless redis = options[:redis]
32
32
  entity_name, check_name = event_id.split(':', 2)
33
- create_entity = options[:create_entity]
34
33
  logger = options[:logger]
34
+ if logger
35
+ logger.debug("Flapjack::Data::EntityCheck#self.for_event_id called for event_id: #{event_id}")
36
+ logger.debug("Flapjack::Data::EntityCheck#self.for_event_id found entity_name: #{entity_name}, check_name: #{check_name}")
37
+ end
38
+ create_entity = options[:create_entity]
35
39
  entity = Flapjack::Data::Entity.find_by_name(entity_name,
36
40
  :create => create_entity, :logger => logger, :redis => redis)
41
+ if logger
42
+ logger.debug("Flapjack::Data::EntityCheck#self.for_event_id found entity by name(#{entity_name}): #{entity.inspect}")
43
+ end
44
+ unless entity
45
+ if logger
46
+ logger.error("entity can't be instantiated for #{entity_name}!")
47
+ end
48
+ return nil
49
+ end
37
50
  self.new(entity, check_name, :logger => logger, :redis => redis)
38
51
  end
39
52
 
@@ -114,12 +127,13 @@ module Flapjack
114
127
 
115
128
  def self.unacknowledged_failing(options = {})
116
129
  raise "Redis connection not set" unless redis = options[:redis]
130
+ logger = options[:logger]
117
131
 
118
132
  redis.zrange('failed_checks', '0', '-1').reject {|entity_check|
119
133
  redis.exists(entity_check + ':unscheduled_maintenance')
120
134
  }.collect {|entity_check|
121
- Flapjack::Data::EntityCheck.for_event_id(entity_check, :redis => redis)
122
- }
135
+ Flapjack::Data::EntityCheck.for_event_id(entity_check, :redis => redis, :logger => logger)
136
+ }.compact
123
137
  end
124
138
 
125
139
  def self.conflate_to_keys(entity_checks_hash)
@@ -315,8 +329,11 @@ module Flapjack
315
329
  # if multiple scheduled maintenances found, find the end_time furthest in the future
316
330
  most_futuristic = current_sched_ms.max {|sm| sm[:end_time] }
317
331
  start_time = most_futuristic[:start_time]
318
- duration = most_futuristic[:duration]
319
- @redis.setex("#{@key}:scheduled_maintenance", duration.to_i, start_time)
332
+
333
+ duration = most_futuristic[:end_time] - current_time
334
+ if duration > 0
335
+ @redis.setex("#{@key}:scheduled_maintenance", duration.to_i, start_time)
336
+ end
320
337
  end
321
338
 
322
339
  # TODO allow summary to be changed as part of the termination
@@ -165,7 +165,9 @@ module Flapjack
165
165
  logger.debug(params.inspect)
166
166
 
167
167
  rule = find_rule(params[:id])
168
- contact = find_contact(rule.contact_id)
168
+
169
+ # previous bug may have led to rule's contact_id being wiped :(
170
+ contact = find_contact(rule.contact_id || params[:contact_id])
169
171
 
170
172
  rule_data = hashify(:entities, :regex_entities, :tags, :regex_tags,
171
173
  :unknown_media, :warning_media, :critical_media, :time_restrictions,
@@ -178,7 +178,7 @@ module Flapjack
178
178
  def find_pagerduty_acknowledgements
179
179
  @logger.debug("looking for acks in pagerduty for unack'd problems")
180
180
 
181
- unacknowledged_failing_checks = Flapjack::Data::EntityCheck.unacknowledged_failing(:redis => @redis)
181
+ unacknowledged_failing_checks = Flapjack::Data::EntityCheck.unacknowledged_failing(:redis => @redis, :logger => @logger)
182
182
 
183
183
  @logger.debug "found unacknowledged failing checks as follows: " + unacknowledged_failing_checks.join(', ')
184
184
 
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  module Flapjack
4
- VERSION = "0.9.3"
4
+ VERSION = "0.9.4"
5
5
  end
6
6
 
@@ -233,7 +233,6 @@ describe Flapjack::Data::EntityCheck, :redis => true do
233
233
  expect(duration).to eq(half_an_hour)
234
234
  end
235
235
 
236
- # TODO this should probably enforce that it starts in the future
237
236
  it "creates a scheduled maintenance period covering the current time" do
238
237
  t = Time.now.to_i
239
238
  ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
@@ -255,6 +254,11 @@ describe Flapjack::Data::EntityCheck, :redis => true do
255
254
  expect(duration).not_to be_nil
256
255
  expect(duration).to be_a(Float)
257
256
  expect(duration).to eq(2 * (60 * 60))
257
+
258
+ ttl = @redis.ttl("#{name}:#{check}:scheduled_maintenance")
259
+ expect(ttl).to be_within(20).of(60 * 60) # 20-second margin of error,
260
+ # should be large enough for a slow machine running the test -- duration
261
+ # is considered to start at the begininng of the period
258
262
  end
259
263
 
260
264
  it "removes a scheduled maintenance period for a future time" do
@@ -318,6 +318,29 @@ describe 'Flapjack::Gateways::API::ContactMethods', :sinatra => true, :logger =>
318
318
  expect(last_response).to be_forbidden
319
319
  end
320
320
 
321
+ it 'uses the contact_id param if the rule being updated lacks that data' do
322
+ nr_nil = double(Flapjack::Data::NotificationRule, :id => '1', :contact_id => nil)
323
+
324
+ expect(Flapjack::Data::Contact).to receive(:find_by_id).
325
+ with(contact.id, {:redis => redis, :logger => @logger}).and_return(contact)
326
+ expect(nr_nil).to receive(:to_json).and_return('"rule_1"')
327
+ expect(Flapjack::Data::NotificationRule).to receive(:find_by_id).
328
+ with(nr_nil.id, {:redis => redis, :logger => @logger}).and_return(nr_nil)
329
+
330
+ # symbolize the keys
331
+ notification_rule_data_sym = notification_rule_data.inject({}){|memo,(k,v)|
332
+ memo[k.to_sym] = v; memo
333
+ }
334
+ notification_rule_data_sym.delete(:contact_id)
335
+
336
+ expect(nr_nil).to receive(:update).with(notification_rule_data_sym, :logger => @logger).and_return(nil)
337
+
338
+ aput "/notification_rules/#{nr_nil.id}", notification_rule_data.to_json,
339
+ {'CONTENT_TYPE' => 'application/json'}
340
+ expect(last_response).to be_ok
341
+ expect(last_response.body).to eq('"rule_1"')
342
+ end
343
+
321
344
  # DELETE /notification_rules/RULE_ID
322
345
  it "deletes a notification rule" do
323
346
  expect(notification_rule).to receive(:contact_id).and_return(contact.id)
metadata CHANGED
@@ -1,7 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flapjack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 0.9.4
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Lindsay Holmwood
@@ -10,314 +11,358 @@ authors:
10
11
  autorequire:
11
12
  bindir: bin
12
13
  cert_chain: []
13
- date: 2014-07-28 00:00:00.000000000 Z
14
+ date: 2014-09-22 00:00:00.000000000 Z
14
15
  dependencies:
15
16
  - !ruby/object:Gem::Dependency
16
17
  name: dante
17
18
  requirement: !ruby/object:Gem::Requirement
19
+ none: false
18
20
  requirements:
19
- - - ">="
21
+ - - ! '>='
20
22
  - !ruby/object:Gem::Version
21
23
  version: '0'
22
24
  type: :runtime
23
25
  prerelease: false
24
26
  version_requirements: !ruby/object:Gem::Requirement
27
+ none: false
25
28
  requirements:
26
- - - ">="
29
+ - - ! '>='
27
30
  - !ruby/object:Gem::Version
28
31
  version: '0'
29
32
  - !ruby/object:Gem::Dependency
30
33
  name: oj
31
34
  requirement: !ruby/object:Gem::Requirement
35
+ none: false
32
36
  requirements:
33
- - - ">="
37
+ - - ! '>='
34
38
  - !ruby/object:Gem::Version
35
39
  version: 2.9.0
36
40
  type: :runtime
37
41
  prerelease: false
38
42
  version_requirements: !ruby/object:Gem::Requirement
43
+ none: false
39
44
  requirements:
40
- - - ">="
45
+ - - ! '>='
41
46
  - !ruby/object:Gem::Version
42
47
  version: 2.9.0
43
48
  - !ruby/object:Gem::Dependency
44
49
  name: eventmachine
45
50
  requirement: !ruby/object:Gem::Requirement
51
+ none: false
46
52
  requirements:
47
- - - "~>"
53
+ - - ~>
48
54
  - !ruby/object:Gem::Version
49
55
  version: 1.0.0
50
56
  type: :runtime
51
57
  prerelease: false
52
58
  version_requirements: !ruby/object:Gem::Requirement
59
+ none: false
53
60
  requirements:
54
- - - "~>"
61
+ - - ~>
55
62
  - !ruby/object:Gem::Version
56
63
  version: 1.0.0
57
64
  - !ruby/object:Gem::Dependency
58
65
  name: hiredis
59
66
  requirement: !ruby/object:Gem::Requirement
67
+ none: false
60
68
  requirements:
61
- - - ">="
69
+ - - ! '>='
62
70
  - !ruby/object:Gem::Version
63
71
  version: '0'
64
72
  type: :runtime
65
73
  prerelease: false
66
74
  version_requirements: !ruby/object:Gem::Requirement
75
+ none: false
67
76
  requirements:
68
- - - ">="
77
+ - - ! '>='
69
78
  - !ruby/object:Gem::Version
70
79
  version: '0'
71
80
  - !ruby/object:Gem::Dependency
72
81
  name: em-synchrony
73
82
  requirement: !ruby/object:Gem::Requirement
83
+ none: false
74
84
  requirements:
75
- - - "~>"
85
+ - - ~>
76
86
  - !ruby/object:Gem::Version
77
87
  version: 1.0.2
78
88
  type: :runtime
79
89
  prerelease: false
80
90
  version_requirements: !ruby/object:Gem::Requirement
91
+ none: false
81
92
  requirements:
82
- - - "~>"
93
+ - - ~>
83
94
  - !ruby/object:Gem::Version
84
95
  version: 1.0.2
85
96
  - !ruby/object:Gem::Dependency
86
97
  name: em-http-request
87
98
  requirement: !ruby/object:Gem::Requirement
99
+ none: false
88
100
  requirements:
89
- - - ">="
101
+ - - ! '>='
90
102
  - !ruby/object:Gem::Version
91
103
  version: '0'
92
104
  type: :runtime
93
105
  prerelease: false
94
106
  version_requirements: !ruby/object:Gem::Requirement
107
+ none: false
95
108
  requirements:
96
- - - ">="
109
+ - - ! '>='
97
110
  - !ruby/object:Gem::Version
98
111
  version: '0'
99
112
  - !ruby/object:Gem::Dependency
100
113
  name: redis
101
114
  requirement: !ruby/object:Gem::Requirement
115
+ none: false
102
116
  requirements:
103
- - - "~>"
117
+ - - ~>
104
118
  - !ruby/object:Gem::Version
105
119
  version: 3.0.6
106
120
  type: :runtime
107
121
  prerelease: false
108
122
  version_requirements: !ruby/object:Gem::Requirement
123
+ none: false
109
124
  requirements:
110
- - - "~>"
125
+ - - ~>
111
126
  - !ruby/object:Gem::Version
112
127
  version: 3.0.6
113
128
  - !ruby/object:Gem::Dependency
114
129
  name: em-resque
115
130
  requirement: !ruby/object:Gem::Requirement
131
+ none: false
116
132
  requirements:
117
- - - ">="
133
+ - - ! '>='
118
134
  - !ruby/object:Gem::Version
119
135
  version: '0'
120
136
  type: :runtime
121
137
  prerelease: false
122
138
  version_requirements: !ruby/object:Gem::Requirement
139
+ none: false
123
140
  requirements:
124
- - - ">="
141
+ - - ! '>='
125
142
  - !ruby/object:Gem::Version
126
143
  version: '0'
127
144
  - !ruby/object:Gem::Dependency
128
145
  name: resque
129
146
  requirement: !ruby/object:Gem::Requirement
147
+ none: false
130
148
  requirements:
131
- - - "~>"
149
+ - - ~>
132
150
  - !ruby/object:Gem::Version
133
151
  version: 1.23.0
134
152
  type: :runtime
135
153
  prerelease: false
136
154
  version_requirements: !ruby/object:Gem::Requirement
155
+ none: false
137
156
  requirements:
138
- - - "~>"
157
+ - - ~>
139
158
  - !ruby/object:Gem::Version
140
159
  version: 1.23.0
141
160
  - !ruby/object:Gem::Dependency
142
161
  name: sinatra
143
162
  requirement: !ruby/object:Gem::Requirement
163
+ none: false
144
164
  requirements:
145
- - - ">="
165
+ - - ! '>='
146
166
  - !ruby/object:Gem::Version
147
167
  version: '0'
148
168
  type: :runtime
149
169
  prerelease: false
150
170
  version_requirements: !ruby/object:Gem::Requirement
171
+ none: false
151
172
  requirements:
152
- - - ">="
173
+ - - ! '>='
153
174
  - !ruby/object:Gem::Version
154
175
  version: '0'
155
176
  - !ruby/object:Gem::Dependency
156
177
  name: rack-fiber_pool
157
178
  requirement: !ruby/object:Gem::Requirement
179
+ none: false
158
180
  requirements:
159
- - - ">="
181
+ - - ! '>='
160
182
  - !ruby/object:Gem::Version
161
183
  version: '0'
162
184
  type: :runtime
163
185
  prerelease: false
164
186
  version_requirements: !ruby/object:Gem::Requirement
187
+ none: false
165
188
  requirements:
166
- - - ">="
189
+ - - ! '>='
167
190
  - !ruby/object:Gem::Version
168
191
  version: '0'
169
192
  - !ruby/object:Gem::Dependency
170
193
  name: thin
171
194
  requirement: !ruby/object:Gem::Requirement
195
+ none: false
172
196
  requirements:
173
- - - "~>"
197
+ - - ~>
174
198
  - !ruby/object:Gem::Version
175
199
  version: 1.6.1
176
200
  type: :runtime
177
201
  prerelease: false
178
202
  version_requirements: !ruby/object:Gem::Requirement
203
+ none: false
179
204
  requirements:
180
- - - "~>"
205
+ - - ~>
181
206
  - !ruby/object:Gem::Version
182
207
  version: 1.6.1
183
208
  - !ruby/object:Gem::Dependency
184
209
  name: mail
185
210
  requirement: !ruby/object:Gem::Requirement
211
+ none: false
186
212
  requirements:
187
- - - ">="
213
+ - - ! '>='
188
214
  - !ruby/object:Gem::Version
189
215
  version: '0'
190
216
  type: :runtime
191
217
  prerelease: false
192
218
  version_requirements: !ruby/object:Gem::Requirement
219
+ none: false
193
220
  requirements:
194
- - - ">="
221
+ - - ! '>='
195
222
  - !ruby/object:Gem::Version
196
223
  version: '0'
197
224
  - !ruby/object:Gem::Dependency
198
225
  name: blather
199
226
  requirement: !ruby/object:Gem::Requirement
227
+ none: false
200
228
  requirements:
201
- - - "~>"
229
+ - - ~>
202
230
  - !ruby/object:Gem::Version
203
231
  version: 0.8.3
204
232
  type: :runtime
205
233
  prerelease: false
206
234
  version_requirements: !ruby/object:Gem::Requirement
235
+ none: false
207
236
  requirements:
208
- - - "~>"
237
+ - - ~>
209
238
  - !ruby/object:Gem::Version
210
239
  version: 0.8.3
211
240
  - !ruby/object:Gem::Dependency
212
241
  name: chronic
213
242
  requirement: !ruby/object:Gem::Requirement
243
+ none: false
214
244
  requirements:
215
- - - ">="
245
+ - - ! '>='
216
246
  - !ruby/object:Gem::Version
217
247
  version: '0'
218
248
  type: :runtime
219
249
  prerelease: false
220
250
  version_requirements: !ruby/object:Gem::Requirement
251
+ none: false
221
252
  requirements:
222
- - - ">="
253
+ - - ! '>='
223
254
  - !ruby/object:Gem::Version
224
255
  version: '0'
225
256
  - !ruby/object:Gem::Dependency
226
257
  name: chronic_duration
227
258
  requirement: !ruby/object:Gem::Requirement
259
+ none: false
228
260
  requirements:
229
- - - ">="
261
+ - - ! '>='
230
262
  - !ruby/object:Gem::Version
231
263
  version: '0'
232
264
  type: :runtime
233
265
  prerelease: false
234
266
  version_requirements: !ruby/object:Gem::Requirement
267
+ none: false
235
268
  requirements:
236
- - - ">="
269
+ - - ! '>='
237
270
  - !ruby/object:Gem::Version
238
271
  version: '0'
239
272
  - !ruby/object:Gem::Dependency
240
273
  name: activesupport
241
274
  requirement: !ruby/object:Gem::Requirement
275
+ none: false
242
276
  requirements:
243
- - - "~>"
277
+ - - ~>
244
278
  - !ruby/object:Gem::Version
245
279
  version: 3.2.14
246
280
  type: :runtime
247
281
  prerelease: false
248
282
  version_requirements: !ruby/object:Gem::Requirement
283
+ none: false
249
284
  requirements:
250
- - - "~>"
285
+ - - ~>
251
286
  - !ruby/object:Gem::Version
252
287
  version: 3.2.14
253
288
  - !ruby/object:Gem::Dependency
254
289
  name: ice_cube
255
290
  requirement: !ruby/object:Gem::Requirement
291
+ none: false
256
292
  requirements:
257
- - - ">="
293
+ - - ! '>='
258
294
  - !ruby/object:Gem::Version
259
295
  version: '0'
260
296
  type: :runtime
261
297
  prerelease: false
262
298
  version_requirements: !ruby/object:Gem::Requirement
299
+ none: false
263
300
  requirements:
264
- - - ">="
301
+ - - ! '>='
265
302
  - !ruby/object:Gem::Version
266
303
  version: '0'
267
304
  - !ruby/object:Gem::Dependency
268
305
  name: tzinfo
269
306
  requirement: !ruby/object:Gem::Requirement
307
+ none: false
270
308
  requirements:
271
- - - "~>"
309
+ - - ~>
272
310
  - !ruby/object:Gem::Version
273
311
  version: 1.0.1
274
312
  type: :runtime
275
313
  prerelease: false
276
314
  version_requirements: !ruby/object:Gem::Requirement
315
+ none: false
277
316
  requirements:
278
- - - "~>"
317
+ - - ~>
279
318
  - !ruby/object:Gem::Version
280
319
  version: 1.0.1
281
320
  - !ruby/object:Gem::Dependency
282
321
  name: tzinfo-data
283
322
  requirement: !ruby/object:Gem::Requirement
323
+ none: false
284
324
  requirements:
285
- - - ">="
325
+ - - ! '>='
286
326
  - !ruby/object:Gem::Version
287
327
  version: '0'
288
328
  type: :runtime
289
329
  prerelease: false
290
330
  version_requirements: !ruby/object:Gem::Requirement
331
+ none: false
291
332
  requirements:
292
- - - ">="
333
+ - - ! '>='
293
334
  - !ruby/object:Gem::Version
294
335
  version: '0'
295
336
  - !ruby/object:Gem::Dependency
296
337
  name: rbtrace
297
338
  requirement: !ruby/object:Gem::Requirement
339
+ none: false
298
340
  requirements:
299
- - - ">="
341
+ - - ! '>='
300
342
  - !ruby/object:Gem::Version
301
343
  version: '0'
302
344
  type: :runtime
303
345
  prerelease: false
304
346
  version_requirements: !ruby/object:Gem::Requirement
347
+ none: false
305
348
  requirements:
306
- - - ">="
349
+ - - ! '>='
307
350
  - !ruby/object:Gem::Version
308
351
  version: '0'
309
352
  - !ruby/object:Gem::Dependency
310
353
  name: rake
311
354
  requirement: !ruby/object:Gem::Requirement
355
+ none: false
312
356
  requirements:
313
- - - ">="
357
+ - - ! '>='
314
358
  - !ruby/object:Gem::Version
315
359
  version: '0'
316
360
  type: :runtime
317
361
  prerelease: false
318
362
  version_requirements: !ruby/object:Gem::Requirement
363
+ none: false
319
364
  requirements:
320
- - - ">="
365
+ - - ! '>='
321
366
  - !ruby/object:Gem::Version
322
367
  version: '0'
323
368
  description: Flapjack is a distributed monitoring notification system that provides
@@ -336,10 +381,11 @@ executables:
336
381
  extensions: []
337
382
  extra_rdoc_files: []
338
383
  files:
339
- - ".gitignore"
340
- - ".gitmodules"
341
- - ".rspec"
342
- - ".travis.yml"
384
+ - .gitignore
385
+ - .gitmodules
386
+ - .rspec
387
+ - .ruby-version
388
+ - .travis.yml
343
389
  - CHANGELOG.md
344
390
  - CONTRIBUTING.md
345
391
  - Gemfile
@@ -575,26 +621,33 @@ files:
575
621
  homepage: http://flapjack.io/
576
622
  licenses:
577
623
  - MIT
578
- metadata: {}
579
624
  post_install_message:
580
625
  rdoc_options: []
581
626
  require_paths:
582
627
  - lib
583
628
  required_ruby_version: !ruby/object:Gem::Requirement
629
+ none: false
584
630
  requirements:
585
- - - ">="
631
+ - - ! '>='
586
632
  - !ruby/object:Gem::Version
587
633
  version: '0'
634
+ segments:
635
+ - 0
636
+ hash: 1556922316348718500
588
637
  required_rubygems_version: !ruby/object:Gem::Requirement
638
+ none: false
589
639
  requirements:
590
- - - ">="
640
+ - - ! '>='
591
641
  - !ruby/object:Gem::Version
592
642
  version: '0'
643
+ segments:
644
+ - 0
645
+ hash: 1556922316348718500
593
646
  requirements: []
594
647
  rubyforge_project:
595
- rubygems_version: 2.2.2
648
+ rubygems_version: 1.8.23
596
649
  signing_key:
597
- specification_version: 4
650
+ specification_version: 3
598
651
  summary: Intelligent, scalable, distributed monitoring notification system.
599
652
  test_files:
600
653
  - features/cli.feature
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 0d000bd7c6fe6166ad1c537c91fe4c53ddc85d9b
4
- data.tar.gz: 678ebf7c7d42fbe6041d28df1748c8e607674d0a
5
- SHA512:
6
- metadata.gz: a0b577918c1f294d4c7619e5e97f025cd8b5d9bf7e1b144efdcedfc58f0d05e188a8394cd9b51b334e82cf5ff7a508ff20316a02c26e60b140426b3ef633d804
7
- data.tar.gz: 5acab492158136c9a110435c53c07480b8ea390beaea33ae31336b397611e0f576f270940639f9737907dd90e7261f6484a9629681303f111f1e448bf2540f83