Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate JSON Schema for both Resolved Telemetry Schema and Resolved Registry #187

Merged
merged 10 commits into from
Jun 3, 2024
Merged
40 changes: 40 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,15 @@ thiserror = "1.0.58"
ureq = "2.9.7"
regex = "1.10.3"
rayon = "1.10.0"
ordered-float = { version = "4.2.0", features = ["serde"] }
ordered-float = { version = "4.2.0", features = ["serde", "schemars"] }
walkdir = "2.5.0"
anyhow = "1.0.83"
itertools = "0.12.1"
globset = { version = "0.4.14", features = ["serde1"] }
miette = { version = "7.2.0", features = ["fancy", "serde"] }
include_dir = "0.7.3"
tempdir = "0.3.7"
schemars = "0.8.21"

# Features definition =========================================================
[features]
Expand Down
4 changes: 2 additions & 2 deletions crates/weaver_codegen_test/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use weaver_cache::Cache;
use weaver_common::in_memory::LogMessage;
use weaver_common::{in_memory, Logger};
use weaver_forge::file_loader::FileSystemFileLoader;
use weaver_forge::registry::TemplateRegistry;
use weaver_forge::registry::ResolvedRegistry;
use weaver_forge::{OutputDirective, TemplateEngine};
use weaver_resolver::SchemaResolver;
use weaver_semconv::path::RegistryPath;
Expand Down Expand Up @@ -51,7 +51,7 @@ fn main() {
let loader = FileSystemFileLoader::try_new(TEMPLATES_PATH.into(), TARGET)
.unwrap_or_else(|e| process_error(&logger, e));
let engine = TemplateEngine::try_new(loader).unwrap_or_else(|e| process_error(&logger, e));
let template_registry = TemplateRegistry::try_from_resolved_registry(
let template_registry = ResolvedRegistry::try_from_resolved_registry(
schema
.registry(REGISTRY_ID)
.expect("Failed to get the registry from the resolved schema"),
Expand Down
1 change: 1 addition & 0 deletions crates/weaver_forge/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ walkdir.workspace = true
globset.workspace = true
miette.workspace = true
include_dir.workspace = true
schemars.workspace = true

[dev-dependencies]
opentelemetry = { version = "0.22.0", features = ["trace", "metrics", "logs", "otel_unstable"] }
Expand Down
1 change: 1 addition & 0 deletions crates/weaver_forge/allowed-external-types.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ allowed_external_types = [
"minijinja::value::Value",
"miette::protocol::Diagnostic",
"include_dir::dir::Dir",
"schemars::JsonSchema",
]
12 changes: 6 additions & 6 deletions crates/weaver_forge/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use crate::debug::error_summary;
use crate::error::Error::InvalidConfigFile;
use crate::extensions::{ansi, case, code, otel, util};
use crate::file_loader::FileLoader;
use crate::registry::{TemplateGroup, TemplateRegistry};
use crate::registry::{ResolvedGroup, ResolvedRegistry};

mod config;
pub mod debug;
Expand Down Expand Up @@ -109,11 +109,11 @@ pub struct TemplateEngine {
#[derive(Serialize, Debug)]
pub struct Context<'a> {
/// The semantic convention registry.
pub registry: &'a TemplateRegistry,
pub registry: &'a ResolvedRegistry,
/// The group to generate doc or code for.
pub group: Option<&'a TemplateGroup>,
pub group: Option<&'a ResolvedGroup>,
/// The groups to generate doc or code for.
pub groups: Option<Vec<&'a TemplateGroup>>,
pub groups: Option<Vec<&'a ResolvedGroup>>,
}

/// Global context for the template engine.
Expand Down Expand Up @@ -432,7 +432,7 @@ mod tests {
use crate::extensions::case::case_converter;
use crate::file_loader::FileSystemFileLoader;
use crate::filter::Filter;
use crate::registry::TemplateRegistry;
use crate::registry::ResolvedRegistry;
use crate::OutputDirective;

#[test]
Expand Down Expand Up @@ -580,7 +580,7 @@ mod tests {
let schema = SchemaResolver::resolve_semantic_convention_registry(&mut registry)
.expect("Failed to resolve registry");

let template_registry = TemplateRegistry::try_from_resolved_registry(
let template_registry = ResolvedRegistry::try_from_resolved_registry(
schema.registry(registry_id).expect("registry not found"),
schema.catalog(),
)
Expand Down
40 changes: 29 additions & 11 deletions crates/weaver_forge/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//! evaluation.

use crate::error::Error;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use weaver_resolved_schema::attribute::Attribute;
use weaver_resolved_schema::catalog::Catalog;
Expand All @@ -13,20 +14,21 @@ use weaver_resolved_schema::registry::{Constraint, Group, Registry};
use weaver_semconv::group::{GroupType, InstrumentSpec, SpanKindSpec};
use weaver_semconv::stability::Stability;

/// A semantic convention registry used in the context of the template engine.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
/// A resolved semantic convention registry used in the context of the template and policy
/// engines.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct TemplateRegistry {
pub struct ResolvedRegistry {
/// The semantic convention registry url.
#[serde(skip_serializing_if = "String::is_empty")]
pub registry_url: String,
/// A list of semantic convention groups.
pub groups: Vec<TemplateGroup>,
pub groups: Vec<ResolvedGroup>,
}

/// Group specification used in the context of the template engine.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct TemplateGroup {
/// Resolved group specification used in the context of the template engine.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema)]
pub struct ResolvedGroup {
/// The id that uniquely identifies the semantic convention.
pub id: String,
/// The type of the group including the specific fields for each type.
Expand Down Expand Up @@ -102,7 +104,7 @@ pub struct TemplateGroup {
pub lineage: Option<GroupLineage>,
}

impl TemplateGroup {
impl ResolvedGroup {
/// Constructs a Template-friendly groups structure from resolved registry structures.
pub fn try_from_resolved(group: &Group, catalog: &Catalog) -> Result<Self, Error> {
let mut errors = Vec::new();
Expand Down Expand Up @@ -133,7 +135,7 @@ impl TemplateGroup {
if !errors.is_empty() {
return Err(Error::CompoundError(errors));
}
Ok(TemplateGroup {
Ok(ResolvedGroup {
id,
r#type: group_type,
brief,
Expand All @@ -155,7 +157,7 @@ impl TemplateGroup {
}
}

impl TemplateRegistry {
impl ResolvedRegistry {
/// Create a new template registry from a resolved registry.
pub fn try_from_resolved_registry(
registry: &Registry,
Expand Down Expand Up @@ -191,7 +193,7 @@ impl TemplateRegistry {
})
.collect();
let lineage = group.lineage.clone();
TemplateGroup {
ResolvedGroup {
id,
r#type: group_type,
brief,
Expand Down Expand Up @@ -223,3 +225,19 @@ impl TemplateRegistry {
})
}
}

#[cfg(test)]
mod tests {
use crate::ResolvedRegistry;
use schemars::schema_for;
use serde_json::to_string_pretty;

#[test]
fn test_json_schema_gen() {
// Ensure the JSON schema can be generated for the TemplateRegistry
let schema = schema_for!(ResolvedRegistry);

// Ensure the schema can be serialized to a string
assert!(to_string_pretty(&schema).is_ok());
}
}
1 change: 1 addition & 0 deletions crates/weaver_resolved_schema/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ weaver_semconv = { path = "../weaver_semconv" }
thiserror.workspace = true
serde.workspace = true
ordered-float.workspace = true
schemars.workspace = true

[dev-dependencies]
serde_json.workspace = true
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ allowed_external_types = [
"ordered_float::OrderedFloat", # ToDo: Remove this dependency before version 1.0
"weaver_semconv::*",
"weaver_version::*",
"schemars::JsonSchema",
]
7 changes: 5 additions & 2 deletions crates/weaver_resolved_schema/src/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@

use crate::tags::Tags;
use crate::value::Value;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::fmt::Display;
use weaver_semconv::attribute::{AttributeSpec, AttributeType, Examples, RequirementLevel};
use weaver_semconv::stability::Stability;

/// An attribute definition.
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Hash)]
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Hash, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct Attribute {
/// Attribute name.
Expand Down Expand Up @@ -81,7 +82,9 @@ pub struct UnresolvedAttribute {
}

/// An internal reference to an attribute in the catalog.
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
#[derive(
Serialize, Deserialize, Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord, JsonSchema,
)]
pub struct AttributeRef(pub u32);

impl Display for AttributeRef {
Expand Down
3 changes: 2 additions & 1 deletion crates/weaver_resolved_schema/src/catalog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//! that are shared across multiple signals in the Resolved Telemetry Schema.

use crate::attribute::{Attribute, AttributeRef};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap};
use std::fmt::Debug;
Expand All @@ -14,7 +15,7 @@ use weaver_semconv::stability::Stability;
/// Attribute references are used to refer to attributes in the catalog.
///
/// Note : In the future, this catalog could be extended with other entities.
#[derive(Serialize, Deserialize, Debug, Clone)]
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema)]
#[serde(deny_unknown_fields)]
#[must_use]
pub struct Catalog {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@

use crate::signal::{Event, MultivariateMetric, Span, UnivariateMetric};
use crate::tags::Tags;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

/// An instrumentation library specification.
/// MUST be used both by applications and libraries.
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct InstrumentationLibrary {
/// An optional name for the instrumentation library.
Expand Down
19 changes: 18 additions & 1 deletion crates/weaver_resolved_schema/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::catalog::Catalog;
use crate::instrumentation_library::InstrumentationLibrary;
use crate::registry::Registry;
use crate::resource::Resource;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use weaver_version::Versions;
Expand All @@ -31,7 +32,7 @@ pub const OTEL_REGISTRY_ID: &str = "OTEL";
/// A Resolved Telemetry Schema.
/// A Resolved Telemetry Schema is self-contained and doesn't contain any
/// external references to other schemas or semantic conventions.
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct ResolvedTelemetrySchema {
/// Version of the file structure.
Expand Down Expand Up @@ -102,3 +103,19 @@ impl ResolvedTelemetrySchema {
}
}
}

#[cfg(test)]
mod tests {
use crate::ResolvedTelemetrySchema;
use schemars::schema_for;
use serde_json::to_string_pretty;

#[test]
fn test_json_schema_gen() {
// Ensure the JSON schema can be generated for the ResolvedTelemetrySchema
let schema = schema_for!(ResolvedTelemetrySchema);

// Ensure the schema can be serialized to a string
assert!(to_string_pretty(&schema).is_ok());
}
}
Loading
Loading