Skip to content

Instantly share code, notes, and snippets.

@tobz
Created November 16, 2022 18:55
Show Gist options
  • Save tobz/a8ca8563fa7a5dcbeeeaf46897d7ed7a to your computer and use it in GitHub Desktop.
Save tobz/a8ca8563fa7a5dcbeeeaf46897d7ed7a to your computer and use it in GitHub Desktop.
def find_nested_object_property_schema(schema, property_name)
@logger.debug "Starting search for nested property '#{property_name}'"
@logger.debug "Starting schema: #{JSON.dump(get_reduced_schema(schema))}"
# See if we're checking an object schema directly.
if !schema['properties'].nil?
@logger.debug "Schema is object, checking properties directly."
return schema['properties'][property_name]
end
# The schema isn't an object schema, so check to see if it's a `oneOf`/`allOf`, and if so,
# recursively visit each of those subschemas, looking for object schemas along the way that we can
# check for the given property within.
matching_property_schemas = []
unvisited_subschemas = schema['oneOf'] || schema['allOf'] || []
visited_subschemas = []
if !unvisited_subschemas.empty?
@logger.debug "Searching through nested subschemas..."
@logger.debug "Schema so far: #{JSON.dump(get_reduced_schema(schema))}"
end
while !unvisited_subschemas.empty? do
@logger.debug "Schema pre-pop: #{JSON.dump(get_reduced_schema(schema))}"
unvisited_subschema = unvisited_subschemas.pop
@logger.debug "Schema post-pop: #{JSON.dump(get_reduced_schema(schema))}"
# If the subschema has object properties, it won't be `oneOf`/`allOf`, so just try and grab the
# property if it exists, and move on.
if !unvisited_subschema['properties'].nil?
@logger.debug "Unvisited subschemas is object, checking properties directly."
subschema_property = unvisited_subschema.dig('properties', property_name)
matching_property_schemas.push(subschema_property) unless subschema_property.nil?
next
end
# If the subschema had no object properties, see if it's an `oneOf`/`allOf` subschema, and if
# so, collect any of _those_ subschemas and add them to our list of subschemas to visit.
maybe_unvisited_subschemas = unvisited_subschema['oneOf'] || unvisited_subschema['allOf'] || []
if !maybe_unvisited_subschemas.empty?
@logger.debug "Unvisited subschema had #{maybe_unvisited_subschemas.count} subschemas of its own, adding to unvisited list."
@logger.debug "Schema after grabbing nested unvisited subschemas: #{JSON.dump(get_reduced_schema(schema))}"
end
unvisited_subschemas.concat(maybe_unvisited_subschemas) unless maybe_unvisited_subschemas.nil?
@logger.debug "Schema at end of loop iteration: #{JSON.dump(get_reduced_schema(schema))}"
visited_subschemas.push(unvisited_subschema)
end
@logger.debug "Visited all subschemas. Found #{matching_property_schemas.count} matching properties for '#{property_name}'."
@logger.debug "Ending schema: #{JSON.dump(get_reduced_schema(schema))}"
# We collected all matching property schemas that we could find as we need to make sure that if we
# find multiple property schemas for the given property name, that they're all identical in shape.
# This lets us deal with schemas, such as buffer configuration, where enum variants may have
# overlapping fields -- both in name and type -- between them, and it's safe to return that
# property schema so long as all of the matches were identical.
case matching_property_schemas.count
when 0
nil
when 1
matching_property_schemas[0]
else
# Compare the property schemas in their reduced form.
reduced_matching_property_schemas = matching_property_schemas.map { |schema| get_reduced_schema(schema) }
if !reduced_matching_property_schemas.uniq.count != 1
@logger.error "Tried to find nested property in schema, but found multiple properties with the same name and different property schemas."
@logger.error "Matching property schemas: #{matching_property_schemas}"
exit
end
matching_property_schemas[0]
end
end
[2022-11-16T13:54:09] DEBUG Starting search for nested property 'max_events'
[2022-11-16T13:54:09] DEBUG Starting schema: {"oneOf":[{"oneOf":[{"type":"object","properties":{"max_events":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"memory"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk_v1"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk"}}}]},{"type":"array","items":{"oneOf":[{"type":"object","properties":{"max_events":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"memory"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk_v1"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk"}}}]}}]}
[2022-11-16T13:54:09] DEBUG Searching through nested subschemas...
[2022-11-16T13:54:09] DEBUG Schema so far: {"oneOf":[{"oneOf":[{"type":"object","properties":{"max_events":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"memory"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk_v1"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk"}}}]},{"type":"array","items":{"oneOf":[{"type":"object","properties":{"max_events":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"memory"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk_v1"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk"}}}]}}]}
[2022-11-16T13:54:09] DEBUG Schema pre-pop: {"oneOf":[{"oneOf":[{"type":"object","properties":{"max_events":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"memory"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk_v1"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk"}}}]},{"type":"array","items":{"oneOf":[{"type":"object","properties":{"max_events":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"memory"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk_v1"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk"}}}]}}]}
[2022-11-16T13:54:09] DEBUG Schema post-pop: {"oneOf":[{"oneOf":[{"type":"object","properties":{"max_events":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"memory"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk_v1"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk"}}}]}]}
[2022-11-16T13:54:09] DEBUG Schema at end of loop iteration: {"oneOf":[{"oneOf":[{"type":"object","properties":{"max_events":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"memory"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk_v1"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk"}}}]}]}
[2022-11-16T13:54:09] DEBUG Schema pre-pop: {"oneOf":[{"oneOf":[{"type":"object","properties":{"max_events":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"memory"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk_v1"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk"}}}]}]}
[2022-11-16T13:54:09] DEBUG Schema post-pop: {"oneOf":[]}
[2022-11-16T13:54:09] DEBUG Unvisited subschema had 3 subschemas of its own, adding to unvisited list.
[2022-11-16T13:54:09] DEBUG Schema after grabbing nested unvisited subschemas: {"oneOf":[]}
[2022-11-16T13:54:09] DEBUG Schema at end of loop iteration: {"oneOf":[{"type":"object","properties":{"max_events":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"memory"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk_v1"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk"}}}]}
[2022-11-16T13:54:09] DEBUG Schema pre-pop: {"oneOf":[{"type":"object","properties":{"max_events":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"memory"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk_v1"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk"}}}]}
[2022-11-16T13:54:09] DEBUG Schema post-pop: {"oneOf":[{"type":"object","properties":{"max_events":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"memory"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk_v1"}}}]}
[2022-11-16T13:54:09] DEBUG Unvisited subschemas is object, checking properties directly.
[2022-11-16T13:54:09] DEBUG Schema pre-pop: {"oneOf":[{"type":"object","properties":{"max_events":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"memory"}}},{"type":"object","properties":{"max_size":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"disk_v1"}}}]}
[2022-11-16T13:54:09] DEBUG Schema post-pop: {"oneOf":[{"type":"object","properties":{"max_events":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"memory"}}}]}
[2022-11-16T13:54:09] DEBUG Unvisited subschemas is object, checking properties directly.
[2022-11-16T13:54:09] DEBUG Schema pre-pop: {"oneOf":[{"type":"object","properties":{"max_events":{"type":"integer"},"when_full":{"oneOf":[{"const":"block"},{"const":"drop_newest"},{"const":"overflow"}]},"type":{"const":"memory"}}}]}
[2022-11-16T13:54:09] DEBUG Schema post-pop: {"oneOf":[]}
[2022-11-16T13:54:09] DEBUG Unvisited subschemas is object, checking properties directly.
[2022-11-16T13:54:09] DEBUG Visited all subschemas. Found 1 matching properties for 'max_events'.
[2022-11-16T13:54:09] DEBUG Ending schema: {"oneOf":[]}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment