Skip to content

JSON schema support and schema validation#365

Merged
ccaraman merged 12 commits intomasterfrom
ratelimit-schema
Jan 26, 2017
Merged

JSON schema support and schema validation#365
ccaraman merged 12 commits intomasterfrom
ratelimit-schema

Conversation

@ccaraman
Copy link
Copy Markdown
Contributor

Scheme validation has been implemented for listeners and the network filters. In addition, the network filters have been split into h/cc to improve testability.

Next PR will provide schema validation for HTTP Connection Manager Filter.

Network::ReadFilterPtr{new Filter::Auth::ClientSsl::Instance(config)});
};

const std::string ClientSslAuthConfigFactory::CLIENT_SSL_SCHEMA(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use literal strings for all the schemas. It will be much easier to read.


/**
* Validates JSON object against passed in schema.
* @param schema supplies the string format of the schema. A Json::Exception will be thrown, if
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

grammar

GetParseError_En(document.GetParseError())));
}

rapidjson::SchemaDocument schema_document(document);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't you need to check some type of error here and throw if the schema itself is not valid?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The schema is 'validated' by being converted into a rapidjson::Document in line 159. Line 159 ensures that is a properly formatted json object. There are no other checks for a proper json schema.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can't be the case / doesn't make sense. You can have a valid JSON document which is not a valid schema. So there must be a way of catching an invalid schema error somewhere, at the very least when you do line 169. I would be shocked if there is no way to check that the schema is valid syntax.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a test with an invalid schema that is in proper json format.


json_config.validateSchema(CLIENT_SSL_SCHEMA);

Filter::Auth::ClientSsl::ConfigPtr config(Filter::Auth::ClientSsl::Config::create(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The schema validation should be done closer to the relevant config code, so that unit tests are covered also. For example, in this case, it should be done inside Filter::Auth::ClientSsl::Config constructor. (Same applies for all the other cases). As long as you already did the h/cc splits for the filters, please keep that, and make sure all of the config stuff has code coverage, since we were missing that previously.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-All checks have been moved into the config constructor except for mongo proxy which does the check in network/mongo_proxy.cc
-Only bad config tests have been moved to the appropriate test files

}
},
"required": ["auth_api_cluster", "stat_prefix"],
"additionalProperties": false
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you see if there is any way to have this be the default when the validator runs, vs. having to specify it each time (since we are always going to specify it).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, there is no way to set it globally for schemas in rapidjson or in JSON schema.

"type": {"type" : "string", "enum" :["read", "write", "both"]},
"name" : {
"type": "string",
"enum" : ["client_ssl_auth", "echo", "mongo_proxy", "ratelimit", "tcp_proxy", "http_connection_manager"]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other people may compile in other filters. We can't specify the enum here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

}

TEST(JsonLoaderTest, Schema) {
ObjectPtr json1 = Factory::LoadFromString("{\"value1\": 10, \"value2\" : \"test\" }");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

literal strings please

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated.

"items" : {
"type": "string",
"format" : "ipv4"
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to enforce additional constrains here, such as

 "uniqueItems" : true,

Not sure if minItems:1 makes sense here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. Updated.

"value" : {"type" : "string"}
},
"additionalProperties": false
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above. uniqueItems: true and minItems: 1 ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated.

@rshriram
Copy link
Copy Markdown
Member

Thinking more about this, may I suggest a different approach?
How about having a single JSON schema for all of Envoy, encompassing all aspects of the configuration. This schema can be validated against the user provided config file at startup. Envoy's commandline would like both the JSON schema and the config file as inputs.

Benefits:

  • A single self-documenting schema would make it easier for users to understand the configuration structure, generate sample configurations, etc. There are several JSON schema viewers online.
  • It would consolidate all the schema stuff into one file, and one code snippet to validate.
  • Future additions/extensions can simply add more fields to the schema, and eliminate the need to perform extensive code validations in individual filters.
  • New filters can be added by simply extending the filters array in the JSON schema with additional filter definitions.

@mattklein123
Copy link
Copy Markdown
Member

@rshriram we have been back and forth on this. @ccaraman can follow up more. The issue is that people will compile in filters that are not present in the open source, which makes a single schema difficult/impossible. I'm also not crazy about having the user specify the schema file on the command line and somehow shipping it to them. These doesn't seem very user friendly.

The compromise that I discussed with @ccaraman is that all of the schema definitions will be inside a single CC file that we can document (we will likely eventually put this as a JSON file into the source distro and compile it into the exe).

I think this will balance flexibility with discoverability.

Copy link
Copy Markdown
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

few small things otherwise looks good


/**
* Validates JSON object against passed in schema.
* @param schema supplies the schema in string format. A Json::Exception will be thrown, if
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"A Json::Exception will be thrown if the JSON object doesn't conform to the supplied schema or the schema itself is not valid." (no comma after "will be thrown")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed.

}
)EOF");

const std::string Json::Schema::CLIENT_SSL_SCHEMA(R"EOF(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CLIENT_SSL_NETWORK_FILTER_SCHEMA

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

}
)EOF");

const std::string Json::Schema::MONGO_PROXY_SCHEMA(R"EOF(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MONGO_PROXY_NETWORK_FILTER_SCHEMA

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

}
)EOF");

const std::string Json::Schema::RATELIMIT_SCHEMA(R"EOF(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RATELIMIT_NETWORK_FILTER_SCHEMA

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

"items": {
"type": "object",
"properties": {
"key" : {"type" : "string"},
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't key required?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

made both key and value required

}
)EOF");

const std::string Json::Schema::REDIS_PROXY_SCHEMA(R"EOF(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

REDIS_PROXY_NETWORK_FILTER_SCHEMA

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

}
)EOF");

const std::string Json::Schema::TCP_PROXY_SCHEMA(R"EOF(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TCP_PROXY_NETWORK_FILTER_SCHEMA

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed.

static const std::string LISTENER_SCHEMA;

// Network Filter Schemas
static const std::string CLIENT_SSL_SCHEMA;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From a naming perspective I mentioned to rename them to include NETWORK_FILTER. The other option is to move this into a sub-struct called NetworkFilter. Either way.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added 'NETWORK_FILTER' to all of these names and updated call sites.

void createFilterChain(Network::Connection& connection) override;

private:
static const std::string LISTENER_SCHEMA;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed. Missed this one :)

/**
* Validates JSON object against passed in schema.
* @param schema supplies the schema in string format. A Json::Exception will be thrown, if
* @param schema supplies the schema in string format. A Json::Exception will be thrown if
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I already commented on this, but the exception will also be thrown if the schema itself is not valid. Please update docs.

* Validates JSON object against passed in schema.
* @param schema supplies the schema in string format. A Json::Exception will be thrown if
* the JSON object doesn't conform to the supplied schema or the schema itself is not
* valid.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indent

@ccaraman ccaraman merged commit 9dbcb86 into master Jan 26, 2017
@ccaraman ccaraman deleted the ratelimit-schema branch January 26, 2017 22:02
rshriram pushed a commit to rshriram/envoy that referenced this pull request Oct 30, 2018
* Added service_configs map to server config

* Defined message ServiceConfigTrafficPercentage

* Removed config_id from the ServerConfig

* Removed deprecated comment

* Removed the service_name

* Applied service_config.proto changes, disabled config_manager
jplevyak added a commit to jplevyak/envoy that referenced this pull request Jan 22, 2020
Use LTO for Wasm code.  Benchmarks show that it results in noticeable improvement.
jpsim pushed a commit that referenced this pull request Nov 28, 2022
Kotlin unary/stremaing interfaces implementation

Tests verify the interaction between the `Envoy` and the `EnvoyEngine` along with the underlying `EnvoyHTTPStream` objects

Signed-off-by: Alan Chiu <achiu@lyft.com>

For an explanation of how to fill out the fields, please see the relevant section
in [PULL_REQUESTS.md](https://github.com/envoyproxy/envoy/blob/master/PULL_REQUESTS.md)

Description: kotlin: implement unary and streaming interfaces
Risk Level: low
Testing: Unit
Docs Changes: n/a
Release Notes: n/a
[Optional Fixes #Issue]
[Optional Deprecated:]

Signed-off-by: JP Simard <jp@jpsim.com>
jpsim pushed a commit that referenced this pull request Nov 29, 2022
Kotlin unary/stremaing interfaces implementation

Tests verify the interaction between the `Envoy` and the `EnvoyEngine` along with the underlying `EnvoyHTTPStream` objects

Signed-off-by: Alan Chiu <achiu@lyft.com>

For an explanation of how to fill out the fields, please see the relevant section
in [PULL_REQUESTS.md](https://github.com/envoyproxy/envoy/blob/master/PULL_REQUESTS.md)

Description: kotlin: implement unary and streaming interfaces
Risk Level: low
Testing: Unit
Docs Changes: n/a
Release Notes: n/a
[Optional Fixes #Issue]
[Optional Deprecated:]

Signed-off-by: JP Simard <jp@jpsim.com>
mathetake pushed a commit that referenced this pull request Mar 3, 2026
**Commit Message**

Fix CSS styling for button placement and text size on the home page hero
for small screens.

Signed-off-by: Erica Hughberg <erica.sundberg.90@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants