From de9a1b0c95777a26f809cf8f6deda14dc27c47f6 Mon Sep 17 00:00:00 2001 From: Chris Stephens Date: Tue, 15 Jan 2019 12:15:55 -0800 Subject: [PATCH 1/3] Add custom JSON generation to_json will print out a more human readable representation of the api representation. It uses api property names as json key's in order to provide more useful breadcrumbs and viewing when collapsed. --- api/product.rb | 24 ++++++++++++++++++++++++ api/resource.rb | 15 +++++++++++++++ api/type.rb | 23 +++++++++++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/api/product.rb b/api/product.rb index 0258c294033f..d7562266c879 100644 --- a/api/product.rb +++ b/api/product.rb @@ -14,6 +14,7 @@ require 'api/object' require 'google/logger' require 'compile/core' +require 'json' module Api # Repesents a product to be managed @@ -33,6 +34,23 @@ def api_name name.delete(' ').downcase end + def to_json(opts = nil) + json_out = {} + + instance_variables.each do |v| + if v == :@objects + json_out['@resources'] = objects.map { |o| [o.name, o] }.to_h + elsif instance_variable_get(v) == false || instance_variable_get(v).nil? + # ignore false or missing because omitting them cleans up result + # and both are the effective defaults of their types + else + json_out[v] = instance_variable_get(v) + end + end + + JSON.generate(json_out, opts) + end + # The product full name is the "display name" in string form intended for # users to read in documentation; "Google Compute Engine", "Cloud Bigtable" def product_full_name @@ -84,6 +102,12 @@ def validate check :name, type: String, allowed: ORDER, required: true end + def to_s + str = "#{name}: #{base_url}" + str += ' (default)' if default + str + end + def <=>(other) ORDER.index(name) <=> ORDER.index(other.name) if other.is_a?(Version) end diff --git a/api/resource.rb b/api/resource.rb index 855a5bbfbc92..bbe25f29a7b8 100644 --- a/api/resource.rb +++ b/api/resource.rb @@ -134,6 +134,21 @@ def validate end end + def to_json(opts = nil) + # ignore fields that will contain references to parent resources + ignored_fields = %i[@__product @__parent @__resource @api_name @collection_url_response] + json_out = {} + + instance_variables.each do |v| + json_out[v] = instance_variable_get(v) unless ignored_fields.include? v + end + + json_out[:@properties] = properties.map { |p| [p.name, p] }.to_h + json_out[:@parameters] = parameters.map { |p| [p.name, p] }.to_h + + JSON.generate(json_out, opts) + end + def identity props = all_user_properties if @identity.nil? diff --git a/api/type.rb b/api/type.rb index 96f47df7c723..3ab701a4bdaf 100644 --- a/api/type.rb +++ b/api/type.rb @@ -74,6 +74,29 @@ def validate check_conflicts end + def to_json(opts = nil) + # ignore fields that will contain references to parent resources and + # those which will be added later + ignored_fields = %i[@resource @__parent @__resource @api_name] + json_out = {} + + instance_variables.each do |v| + if v == :@conflicts && instance_variable_get(v).empty? + # ignore empty conflict arrays + elsif instance_variable_get(v) == false + # ignore false booleans as non-existence indicates falsey + elsif !ignored_fields.include? v + json_out[v] = instance_variable_get(v) + end + end + + # convert properties to a hash based on name for nested readability + json_out[:@properties] = properties&.map { |p| [p.name, p] }.to_h \ + if respond_to? 'properties' + + JSON.generate(json_out, opts) + end + def check_default_value_property return if @default_value.nil? From f2855bf230ff11941a2a7f5114a8ea1aa8d0421e Mon Sep 17 00:00:00 2001 From: Chris Stephens Date: Fri, 1 Feb 2019 10:56:25 -0800 Subject: [PATCH 2/3] Make json the default string representation For Product, Resource and type override the to_s so that it will return pretty json instead of the name of the class. --- api/product.rb | 4 ++++ api/resource.rb | 4 ++++ api/type.rb | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/api/product.rb b/api/product.rb index d7562266c879..567c4a2f95d5 100644 --- a/api/product.rb +++ b/api/product.rb @@ -34,6 +34,10 @@ def api_name name.delete(' ').downcase end + def to_s + JSON.pretty_generate(self) + end + def to_json(opts = nil) json_out = {} diff --git a/api/resource.rb b/api/resource.rb index bbe25f29a7b8..ff6fd304d3e4 100644 --- a/api/resource.rb +++ b/api/resource.rb @@ -134,6 +134,10 @@ def validate end end + def to_s + JSON.pretty_generate(self) + end + def to_json(opts = nil) # ignore fields that will contain references to parent resources ignored_fields = %i[@__product @__parent @__resource @api_name @collection_url_response] diff --git a/api/type.rb b/api/type.rb index 3ab701a4bdaf..5d1ef9334483 100644 --- a/api/type.rb +++ b/api/type.rb @@ -83,7 +83,7 @@ def to_json(opts = nil) instance_variables.each do |v| if v == :@conflicts && instance_variable_get(v).empty? # ignore empty conflict arrays - elsif instance_variable_get(v) == false + elsif instance_variable_get(v) == false || instance_variable_get(v).nil? # ignore false booleans as non-existence indicates falsey elsif !ignored_fields.include? v json_out[v] = instance_variable_get(v) From 51aa647fe92de2e5ce7740cff004e3c00d614540 Mon Sep 17 00:00:00 2001 From: Chris Stephens Date: Fri, 1 Feb 2019 11:22:46 -0800 Subject: [PATCH 3/3] add to_s for type and comments --- api/product.rb | 1 + api/type.rb | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/api/product.rb b/api/product.rb index 567c4a2f95d5..d27f6a07b0b9 100644 --- a/api/product.rb +++ b/api/product.rb @@ -35,6 +35,7 @@ def api_name end def to_s + # relies on the custom to_json definitions JSON.pretty_generate(self) end diff --git a/api/type.rb b/api/type.rb index 5d1ef9334483..14efe0cc50c4 100644 --- a/api/type.rb +++ b/api/type.rb @@ -74,6 +74,10 @@ def validate check_conflicts end + def to_s + JSON.pretty_generate(self) + end + def to_json(opts = nil) # ignore fields that will contain references to parent resources and # those which will be added later