From 771c531947ca970c889acbfe40eaa08b2e5f3881 Mon Sep 17 00:00:00 2001 From: John Nunemaker Date: Mon, 13 Nov 2023 09:51:27 -0500 Subject: [PATCH] Change JSON.parse to Typecast.from_json --- lib/flipper/adapters/active_record.rb | 2 +- lib/flipper/adapters/http.rb | 8 ++++---- lib/flipper/adapters/http/error.rb | 2 +- lib/flipper/adapters/mongo.rb | 2 +- lib/flipper/adapters/pstore.rb | 2 +- lib/flipper/adapters/redis.rb | 2 +- lib/flipper/adapters/sequel.rb | 2 +- lib/flipper/api/json_params.rb | 2 +- lib/flipper/serializers/gzip.rb | 12 +++++++++++- lib/flipper/serializers/json.rb | 2 ++ spec/flipper/serializers/gzip_spec.rb | 5 +++++ spec/flipper/serializers/json_spec.rb | 5 +++++ 12 files changed, 34 insertions(+), 12 deletions(-) diff --git a/lib/flipper/adapters/active_record.rb b/lib/flipper/adapters/active_record.rb index b70d486d5..33ef56dbc 100644 --- a/lib/flipper/adapters/active_record.rb +++ b/lib/flipper/adapters/active_record.rb @@ -263,7 +263,7 @@ def result_for_gates(feature, gates) end when :json if row = gates.detect { |key, value| !key.nil? && key.to_sym == gate.key } - JSON.parse(row.last) + Typecast.from_json(row.last) end when :set gates.select { |key, value| !key.nil? && key.to_sym == gate.key }.map(&:last).to_set diff --git a/lib/flipper/adapters/http.rb b/lib/flipper/adapters/http.rb index 1aeefbb9d..cf190b310 100644 --- a/lib/flipper/adapters/http.rb +++ b/lib/flipper/adapters/http.rb @@ -27,7 +27,7 @@ def initialize(options = {}) def get(feature) response = @client.get("/features/#{feature.key}") if response.is_a?(Net::HTTPOK) - parsed_response = JSON.parse(response.body) + parsed_response = Typecast.from_json(response.body) result_for_feature(feature, parsed_response.fetch('gates')) elsif response.is_a?(Net::HTTPNotFound) default_config @@ -41,7 +41,7 @@ def get_multi(features) response = @client.get("/features?keys=#{csv_keys}&exclude_gate_names=true") raise Error, response unless response.is_a?(Net::HTTPOK) - parsed_response = JSON.parse(response.body) + parsed_response = Typecast.from_json(response.body) parsed_features = parsed_response.fetch('features') gates_by_key = parsed_features.each_with_object({}) do |parsed_feature, hash| hash[parsed_feature['key']] = parsed_feature['gates'] @@ -59,7 +59,7 @@ def get_all response = @client.get("/features?exclude_gate_names=true") raise Error, response unless response.is_a?(Net::HTTPOK) - parsed_response = JSON.parse(response.body) + parsed_response = Typecast.from_json(response.body) parsed_features = parsed_response.fetch('features') gates_by_key = parsed_features.each_with_object({}) do |parsed_feature, hash| hash[parsed_feature['key']] = parsed_feature['gates'] @@ -78,7 +78,7 @@ def features response = @client.get('/features?exclude_gate_names=true') raise Error, response unless response.is_a?(Net::HTTPOK) - parsed_response = JSON.parse(response.body) + parsed_response = Typecast.from_json(response.body) parsed_response['features'].map { |feature| feature['key'] }.to_set end diff --git a/lib/flipper/adapters/http/error.rb b/lib/flipper/adapters/http/error.rb index 925c6859e..7b4758635 100644 --- a/lib/flipper/adapters/http/error.rb +++ b/lib/flipper/adapters/http/error.rb @@ -11,7 +11,7 @@ def initialize(response) message = "Failed with status: #{response.code}" begin - data = JSON.parse(response.body) + data = Typecast.from_json(response.body) if error_message = data["message"] message << "\n\n#{data["message"]}" diff --git a/lib/flipper/adapters/mongo.rb b/lib/flipper/adapters/mongo.rb index 6ec4fd16f..e91dbc91f 100644 --- a/lib/flipper/adapters/mongo.rb +++ b/lib/flipper/adapters/mongo.rb @@ -175,7 +175,7 @@ def result_for_feature(feature, doc) doc.fetch(gate.key.to_s) { Set.new }.to_set when :json value = doc[gate.key.to_s] - JSON.parse(value) if value + Typecast.from_json(value) else unsupported_data_type gate.data_type end diff --git a/lib/flipper/adapters/pstore.rb b/lib/flipper/adapters/pstore.rb index e8c7c0577..b9a5534f5 100644 --- a/lib/flipper/adapters/pstore.rb +++ b/lib/flipper/adapters/pstore.rb @@ -161,7 +161,7 @@ def result_for_feature(feature) set_members key when :json value = read(key) - JSON.parse(value) if value + Typecast.from_json(value) else raise "#{gate} is not supported by this adapter yet" end diff --git a/lib/flipper/adapters/redis.rb b/lib/flipper/adapters/redis.rb index ee3aac4d7..e99b7c319 100644 --- a/lib/flipper/adapters/redis.rb +++ b/lib/flipper/adapters/redis.rb @@ -174,7 +174,7 @@ def result_for_feature(feature, doc) fields_to_gate_value fields, gate when :json value = doc[gate.key.to_s] - JSON.parse(value) if value + Typecast.from_json(value) else unsupported_data_type gate.data_type end diff --git a/lib/flipper/adapters/sequel.rb b/lib/flipper/adapters/sequel.rb index 17e1de7e5..8058db8fd 100644 --- a/lib/flipper/adapters/sequel.rb +++ b/lib/flipper/adapters/sequel.rb @@ -227,7 +227,7 @@ def result_for_feature(feature, db_gates) db_gates.select { |db_gate| db_gate.key == gate.key.to_s }.map(&:value).to_set when :json if detected_db_gate = db_gates.detect { |db_gate| db_gate.key == gate.key.to_s } - JSON.parse(detected_db_gate.value) + Typecast.from_json(detected_db_gate.value) end else unsupported_data_type gate.data_type diff --git a/lib/flipper/api/json_params.rb b/lib/flipper/api/json_params.rb index a8c4334d2..6c8792065 100644 --- a/lib/flipper/api/json_params.rb +++ b/lib/flipper/api/json_params.rb @@ -34,7 +34,7 @@ def call(env) # This method accomplishes similar functionality def update_params(env, data) return if data.empty? - parsed_request_body = JSON.parse(data) + parsed_request_body = Typecast.from_json(data) env["parsed_request_body".freeze] = parsed_request_body parsed_query_string = parse_query(env[QUERY_STRING]) parsed_query_string.merge!(parsed_request_body) diff --git a/lib/flipper/serializers/gzip.rb b/lib/flipper/serializers/gzip.rb index 1c2cb6e8a..31d9437c9 100644 --- a/lib/flipper/serializers/gzip.rb +++ b/lib/flipper/serializers/gzip.rb @@ -6,8 +6,17 @@ module Serializers module Gzip module_function + class Stream < StringIO + def initialize(*) + super + set_encoding "BINARY" + end + def close; rewind; end + end + def serialize(source) - output = StringIO.new + return if source.nil? + output = Stream.new gz = Zlib::GzipWriter.new(output) gz.write(source) gz.close @@ -15,6 +24,7 @@ def serialize(source) end def deserialize(source) + return if source.nil? Zlib::GzipReader.wrap(StringIO.new(source), &:read) end end diff --git a/lib/flipper/serializers/json.rb b/lib/flipper/serializers/json.rb index 97e4d229c..df09b403d 100644 --- a/lib/flipper/serializers/json.rb +++ b/lib/flipper/serializers/json.rb @@ -6,10 +6,12 @@ module Json module_function def serialize(source) + return if source.nil? JSON.generate(source) end def deserialize(source) + return if source.nil? JSON.parse(source) end end diff --git a/spec/flipper/serializers/gzip_spec.rb b/spec/flipper/serializers/gzip_spec.rb index d6448df06..cc1cc919c 100644 --- a/spec/flipper/serializers/gzip_spec.rb +++ b/spec/flipper/serializers/gzip_spec.rb @@ -5,4 +5,9 @@ serialized = described_class.serialize("my data") expect(described_class.deserialize(serialized)).to eq("my data") end + + it "doesn't fail with nil" do + expect(described_class.serialize(nil)).to be(nil) + expect(described_class.deserialize(nil)).to be(nil) + end end diff --git a/spec/flipper/serializers/json_spec.rb b/spec/flipper/serializers/json_spec.rb index 8bbdf6ba1..cb130c12a 100644 --- a/spec/flipper/serializers/json_spec.rb +++ b/spec/flipper/serializers/json_spec.rb @@ -5,4 +5,9 @@ serialized = described_class.serialize("my data") expect(described_class.deserialize(serialized)).to eq("my data") end + + it "doesn't fail with nil" do + expect(described_class.serialize(nil)).to be(nil) + expect(described_class.deserialize(nil)).to be(nil) + end end