[ARVADOS] updated: 07e4083ea451913b988d77e8e4c926da8ad844a4
Git user
git at public.curoverse.com
Fri Mar 3 16:23:00 EST 2017
Summary of changes:
services/api/lib/serializers.rb | 54 ++++++++++++++++++++------------
services/api/test/unit/seralizer_test.rb | 22 +++++++++++++
2 files changed, 56 insertions(+), 20 deletions(-)
create mode 100644 services/api/test/unit/seralizer_test.rb
via 07e4083ea451913b988d77e8e4c926da8ad844a4 (commit)
from 594e00f9311da95f73843f55b6e1c7c3ad55d8df (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
commit 07e4083ea451913b988d77e8e4c926da8ad844a4
Author: Tom Clegg <tom at curoverse.com>
Date: Fri Mar 3 16:18:10 2017 -0500
11168: Double-decode serialized fields if database was mangled by downgraded API server.
diff --git a/services/api/lib/serializers.rb b/services/api/lib/serializers.rb
index d7a81e1..41379f3 100644
--- a/services/api/lib/serializers.rb
+++ b/services/api/lib/serializers.rb
@@ -1,40 +1,54 @@
require 'safe_json'
-class HashSerializer
+class Serializer
+ def self.dump(val)
+ SafeJSON.dump(val)
+ end
+
+ def self.legacy_load(s)
+ val = Psych.safe_load(s)
+ if val.is_a? String
+ # If apiserver was downgraded to a YAML-only version after
+ # storing JSON in the database, the old code would have loaded
+ # the JSON document as a plain string, and then YAML-encoded
+ # it when saving it back to the database. It's too late now to
+ # make the old code behave better, but at least we can
+ # gracefully handle the mess it leaves in the database by
+ # double-decoding on the way out.
+ return SafeJSON.load(val)
+ else
+ return val
+ end
+ end
+
def self.load(s)
if s.nil?
- {}
- elsif s[0] == "{"
+ object_class.new()
+ elsif s[0] == first_json_char
SafeJSON.load(s)
elsif s[0..2] == "---"
- Psych.safe_load(s)
+ legacy_load(s)
else
raise "invalid serialized data #{s[0..5].inspect}"
end
end
- def self.dump(h)
- SafeJSON.dump(h)
+end
+
+class HashSerializer < Serializer
+ def self.first_json_char
+ "{"
end
+
def self.object_class
::Hash
end
end
-class ArraySerializer
- def self.load(s)
- if s.nil?
- []
- elsif s[0] == "["
- SafeJSON.load(s)
- elsif s[0..2] == "---"
- Psych.safe_load(s)
- else
- raise "invalid serialized data #{s[0..5].inspect}"
- end
- end
- def self.dump(a)
- SafeJSON.dump(a)
+class ArraySerializer < Serializer
+ def self.first_json_char
+ "["
end
+
def self.object_class
::Array
end
diff --git a/services/api/test/unit/seralizer_test.rb b/services/api/test/unit/seralizer_test.rb
new file mode 100644
index 0000000..4d7ca2a
--- /dev/null
+++ b/services/api/test/unit/seralizer_test.rb
@@ -0,0 +1,22 @@
+require 'test_helper'
+require 'serializers'
+
+class SerializerTest < ActiveSupport::TestCase
+ test 'serialize' do
+ assert_equal('{}', HashSerializer.dump({}))
+ assert_equal('{"foo":"bar"}', HashSerializer.dump(foo: 'bar'))
+ assert_equal('{"foo":"bar"}', HashSerializer.dump('foo' => 'bar'))
+ assert_equal('[]', ArraySerializer.dump([]))
+ assert_equal('["foo",{"foo":"bar"}]',
+ ArraySerializer.dump(['foo', 'foo' => 'bar']))
+ assert_equal(['foo'],
+ ArraySerializer.load(ArraySerializer.dump([:foo])))
+ assert_equal([1,'bar'],
+ ArraySerializer.load(ArraySerializer.dump([1,'bar'])))
+ end
+
+ test 'load array that was saved as json, then mangled by an old version' do
+ assert_equal(['foo'],
+ ArraySerializer.load(YAML.dump(ArraySerializer.dump(['foo']))))
+ end
+end
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list