public void WriteWithEmptyResourceSchema() { StringWriter stringWriter = new StringWriter(); JsonTextWriter writer = new JsonTextWriter(stringWriter); ResourceSchema resourceSchema = new ResourceSchema(); ResourceSchemaWriter.Write(writer, resourceSchema); Assert.Equal("{}", stringWriter.ToString()); }
public void WriteWithId() { StringWriter stringWriter = new StringWriter(); JsonTextWriter writer = new JsonTextWriter(stringWriter); writer.QuoteChar = '\''; ResourceSchema resourceSchema = new ResourceSchema(); resourceSchema.Id = "MockId"; ResourceSchemaWriter.Write(writer, resourceSchema); Assert.Equal("{'id':'MockId'}", stringWriter.ToString()); }
public void WriteWithTitle() { StringWriter stringWriter = new StringWriter(); JsonTextWriter writer = new JsonTextWriter(stringWriter); writer.QuoteChar = '\''; ResourceSchema resourceSchema = new ResourceSchema(); resourceSchema.Schema = "MockSchema"; resourceSchema.Title = "MockTitle"; ResourceSchemaWriter.Write(writer, resourceSchema); Assert.Equal("{'$schema':'MockSchema','title':'MockTitle'}", stringWriter.ToString()); }
private static void WriteSchema(JsonTextWriter writer, ResourceSchema schema) { WriteObject(writer, () => { WriteProperty(writer, "id", schema.Id); WriteProperty(writer, "$schema", "http://json-schema.org/draft-04/schema#"); WriteProperty(writer, "title", schema.Title); WriteProperty(writer, "description", schema.Description); WriteProperty(writer, "resourceDefinitions", () => { foreach (Resource resource in schema.Resources) { WriteResource(writer, resource); } }); }); }
public static void Write(TextWriter writer, ResourceSchema resourceSchema) { if (writer == null) { throw new ArgumentNullException("writer"); } if (resourceSchema == null) { throw new ArgumentNullException("resourceSchema"); } using (JsonTextWriter jsonWriter = new JsonTextWriter(writer)) { jsonWriter.Formatting = Formatting.Indented; jsonWriter.Indentation = 2; jsonWriter.IndentChar = ' '; jsonWriter.QuoteChar = '\"'; Write(jsonWriter, resourceSchema); } }
public static void Write(JsonWriter writer, ResourceSchema resourceSchema) { if (writer == null) { throw new ArgumentNullException("writer"); } if (resourceSchema == null) { throw new ArgumentNullException("resourceSchema"); } writer.WriteStartObject(); WriteProperty(writer, "id", resourceSchema.Id); WriteProperty(writer, "$schema", resourceSchema.Schema); WriteProperty(writer, "title", resourceSchema.Title); WriteProperty(writer, "description", resourceSchema.Description); WriteDefinitionMap(writer, "resourceDefinitions", resourceSchema.ResourceDefinitions, sortDefinitions: true); WriteDefinitionMap(writer, "definitions", resourceSchema.Definitions, sortDefinitions: true); writer.WriteEndObject(); }
/// <summary> /// Parse a ResourceSchemaModel from the provided ServiceClient. /// </summary> /// <param name="serviceClient"></param> /// <returns></returns> public static IDictionary <string, ResourceSchema> Parse(ServiceClient serviceClient) { if (serviceClient == null) { throw new ArgumentNullException(nameof(serviceClient)); } string apiVersion = serviceClient.ApiVersion; if (string.IsNullOrWhiteSpace(apiVersion)) { throw new ArgumentException("No API version is provided in the swagger document."); } Dictionary <string, ResourceSchema> resourceSchemas = new Dictionary <string, ResourceSchema>(); foreach (Method method in serviceClient.Methods) { if (method.HttpMethod != HttpMethod.Put || method.ReturnType.Body == null || !(method.ReturnType.Body is CompositeType) || string.IsNullOrWhiteSpace(method.Url) || !method.Url.StartsWith(resourceMethodPrefix, StringComparison.OrdinalIgnoreCase) || !method.Url.EndsWith("}", StringComparison.OrdinalIgnoreCase)) { continue; } string afterPrefix = method.Url.Substring(resourceMethodPrefix.Length); int forwardSlashIndexAfterProvider = afterPrefix.IndexOf('/'); string resourceProvider = afterPrefix.Substring(0, forwardSlashIndexAfterProvider); if (IsPathVariable(resourceProvider)) { // If the resourceProvider is a path variable, such as {someValue}, then this // is not a create resource method. Skip it. continue; } ResourceSchema resourceSchema; if (!resourceSchemas.ContainsKey(resourceProvider)) { resourceSchema = new ResourceSchema(); resourceSchema.Id = string.Format(CultureInfo.InvariantCulture, "http://schema.management.azure.com/schemas/{0}/{1}.json#", apiVersion, resourceProvider); resourceSchema.Title = resourceProvider; resourceSchema.Description = resourceProvider.Replace('.', ' ') + " Resource Types"; resourceSchema.Schema = "http://json-schema.org/draft-04/schema#"; resourceSchemas.Add(resourceProvider, resourceSchema); } else { resourceSchema = resourceSchemas[resourceProvider]; } string methodUrlPathAfterProvider = afterPrefix.Substring(forwardSlashIndexAfterProvider + 1); string[] resourceTypes = ParseResourceTypes(resourceProvider, methodUrlPathAfterProvider, method); foreach (string resourceType in resourceTypes) { JsonSchema resourceDefinition = new JsonSchema(); resourceDefinition.JsonType = "object"; resourceDefinition.AddProperty("type", JsonSchema.CreateStringEnum(resourceType), true); resourceDefinition.AddProperty("apiVersion", JsonSchema.CreateStringEnum(apiVersion), true); if (method.Body != null) { CompositeType body = method.Body.Type as CompositeType; Debug.Assert(body != null, "The create resource method's body must be a CompositeType and cannot be null."); if (body != null) { foreach (Property property in body.Properties) { if (!resourceDefinition.Properties.Keys.Contains(property.Name)) { JsonSchema propertyDefinition = ParseType(property, property.Type, resourceSchema.Definitions, serviceClient.ModelTypes); if (propertyDefinition != null) { resourceDefinition.AddProperty(property.Name, propertyDefinition, property.IsRequired || property.Name == "properties"); } } } } } resourceDefinition.Description = resourceType; string resourcePropertyName = resourceType.Substring(resourceProvider.Length + 1).Replace('/', '_'); Debug.Assert(!resourceSchema.ResourceDefinitions.ContainsKey(resourcePropertyName)); resourceSchema.AddResourceDefinition(resourcePropertyName, resourceDefinition); } } // This loop adds child resource schemas to their parent resource schemas. We can't do // this until we're done adding all resources as top level resources, though, because // it's possible that we will parse a child resource before we parse the parent // resource. foreach (ResourceSchema resourceSchema in resourceSchemas.Values) { // By iterating over the reverse order of the defined resource definitions, I'm // counting on the resource definitions being in sorted order. That way I'm // guaranteed to visit child resource definitions before I visit their parent // resource definitions. By doing this, I've guaranteed that grandchildren resource // definitions will be added to their grandparent (and beyond) ancestor // resource definitions. foreach (string resourcePropertyName in resourceSchema.ResourceDefinitions.Keys.Reverse()) { JsonSchema resourceDefinition = resourceSchema.ResourceDefinitions[resourcePropertyName]; string resourceType = resourceDefinition.ResourceType; int lastSlashIndex = resourceType.LastIndexOf('/'); string parentResourceType = resourceType.Substring(0, lastSlashIndex); JsonSchema parentResourceDefinition = resourceSchema.GetResourceDefinitionByResourceType(parentResourceType); if (parentResourceDefinition != null) { string childResourceType = resourceType.Substring(lastSlashIndex + 1); JsonSchema childResourceDefinition = resourceDefinition.Clone(); childResourceDefinition.ResourceType = childResourceType; string childResourceDefinitionPropertyName = string.Join("_", resourcePropertyName, "childResource"); resourceSchema.AddDefinition(childResourceDefinitionPropertyName, childResourceDefinition); JsonSchema childResources; if (parentResourceDefinition.Properties.ContainsKey("resources")) { childResources = parentResourceDefinition.Properties["resources"]; } else { childResources = new JsonSchema() { JsonType = "array", Items = new JsonSchema() }; parentResourceDefinition.AddProperty("resources", childResources); } childResources.Items.AddOneOf(new JsonSchema() { Ref = "#/definitions/" + childResourceDefinitionPropertyName, }); } } } return(resourceSchemas); }
/// <summary> /// Parse a ResourceSchemaModel from the provided ServiceClient. /// </summary> /// <param name="serviceClient"></param> /// <returns></returns> public static IDictionary<string, ResourceSchema> Parse(ServiceClient serviceClient) { if (serviceClient == null) { throw new ArgumentNullException("serviceClient"); } IDictionary<string, ResourceSchema> result = new Dictionary<string, ResourceSchema>(); List<Method> createResourceMethods = new List<Method>(); foreach (Method method in serviceClient.Methods) { if (IsCreateResourceMethod(method)) { createResourceMethods.Add(method); } } string apiVersion = serviceClient.ApiVersion; foreach (Method createResourceMethod in createResourceMethods) { string afterPrefix = createResourceMethod.Url.Substring(resourceMethodPrefix.Length); int forwardSlashIndexAfterProvider = afterPrefix.IndexOf('/'); string resourceProvider = afterPrefix.Substring(0, forwardSlashIndexAfterProvider); ResourceSchema resourceSchema; if (!result.ContainsKey(resourceProvider)) { resourceSchema = new ResourceSchema(); if (apiVersion != null) { resourceSchema.Id = string.Format(CultureInfo.InvariantCulture, "http://schema.management.azure.com/schemas/{0}/{1}.json#", apiVersion, resourceProvider); } resourceSchema.Title = resourceProvider; resourceSchema.Description = resourceProvider.Replace('.', ' ') + " Resource Types"; resourceSchema.Schema = "http://json-schema.org/draft-04/schema#"; result.Add(resourceProvider, resourceSchema); } else { resourceSchema = result[resourceProvider]; } string methodUrlPathAfterProvider = afterPrefix.Substring(forwardSlashIndexAfterProvider + 1); string[] resourceTypes = GetResourceTypes(resourceProvider, methodUrlPathAfterProvider, createResourceMethod.Parameters); foreach (string resourceType in resourceTypes) { JsonSchema resourceDefinition = new JsonSchema(); resourceDefinition.JsonType = "object"; resourceDefinition.AddProperty("type", new JsonSchema() { JsonType = "string" }.AddEnum(resourceType), true); if (!string.IsNullOrWhiteSpace(apiVersion)) { resourceDefinition.AddProperty("apiVersion", new JsonSchema() { JsonType = "string" }.AddEnum(apiVersion), true); } if (createResourceMethod.Body != null) { CompositeType body = createResourceMethod.Body.Type as CompositeType; Debug.Assert(body != null, "The create resource method's body must be a CompositeType and cannot be null."); if (body != null) { foreach (Property property in body.Properties) { if (!resourceDefinition.Properties.Keys.Contains(property.Name)) { JsonSchema propertyDefinition = ParseProperty(property, resourceSchema.Definitions); if (propertyDefinition != null) { resourceDefinition.AddProperty(property.Name, propertyDefinition, property.IsRequired || property.Name == "properties"); } } } } } resourceDefinition.Description = resourceType; string resourcePropertyName = resourceType.Substring(resourceProvider.Length + 1).Replace('/', '_'); Debug.Assert(!resourceSchema.ResourceDefinitions.ContainsKey(resourcePropertyName)); resourceSchema.AddResourceDefinition(resourcePropertyName, resourceDefinition); } } // This loop adds child resource schemas to their parent resource schemas. We can't do // this until we're done adding all resources as top level resources, though, because // it's possible that we will parse a child resource before we parse the parent // resource. foreach (ResourceSchema resourceSchema in result.Values) { // By iterating over the reverse order of the defined resource definitions, I'm // counting on the resource definitions being in sorted order. That way I'm // guaranteed to visit child resource definitions before I visit their parent // resource definitions. By doing this, I've guaranteed that grandchildren resource // definitions will be added to their grandparent (and beyond) ancestor // resource definitions. foreach (string resourcePropertyName in resourceSchema.ResourceDefinitions.Keys.Reverse()) { JsonSchema resourceDefinition = resourceSchema.ResourceDefinitions[resourcePropertyName]; string resourceType = resourceDefinition.ResourceType; int lastSlashIndex = resourceType.LastIndexOf('/'); string parentResourceType = resourceType.Substring(0, lastSlashIndex); JsonSchema parentResourceDefinition = resourceSchema.GetResourceDefinitionByResourceType(parentResourceType); if (parentResourceDefinition != null) { string childResourceType = resourceType.Substring(lastSlashIndex + 1); JsonSchema childResourceDefinition = resourceDefinition.Clone(); childResourceDefinition.ResourceType = childResourceType; string childResourceDefinitionPropertyName = string.Join("_", resourcePropertyName, "childResource"); resourceSchema.AddDefinition(childResourceDefinitionPropertyName, childResourceDefinition); parentResourceDefinition.AddResource(new JsonSchema() { Ref = "#/definitions/" + childResourceDefinitionPropertyName, }); } } } return result; }
public void WriteWithDescription() { StringWriter stringWriter = new StringWriter(); JsonTextWriter writer = new JsonTextWriter(stringWriter); writer.QuoteChar = '\''; ResourceSchema resourceSchema = new ResourceSchema(); resourceSchema.Title = "MockTitle"; resourceSchema.Description = "MockDescription"; ResourceSchemaWriter.Write(writer, resourceSchema); Assert.Equal("{'title':'MockTitle','description':'MockDescription'}", stringWriter.ToString()); }
public void WriteWithNullJsonTextWriter() { JsonTextWriter writer = null; ResourceSchema resourceSchema = new ResourceSchema(); Assert.Throws<ArgumentNullException>(() => { ResourceSchemaWriter.Write(writer, resourceSchema); }); }
public void WriteWithOneDefinition() { StringWriter stringWriter = new StringWriter(); JsonTextWriter writer = new JsonTextWriter(stringWriter); writer.QuoteChar = '\''; ResourceSchema resourceSchema = new ResourceSchema(); resourceSchema.AddResourceDefinition("mockResource", new JsonSchema()); resourceSchema.AddDefinition("mockDefinition", new JsonSchema()); ResourceSchemaWriter.Write(writer, resourceSchema); Assert.Equal("{'resourceDefinitions':{'mockResource':{}},'definitions':{'mockDefinition':{}}}", stringWriter.ToString()); }
/// <summary> /// Parse a ResourceSchemaModel from the provided ServiceClient. /// </summary> /// <param name="serviceClient"></param> /// <returns></returns> public static IDictionary <string, ResourceSchema> Parse(ServiceClient serviceClient) { if (serviceClient == null) { throw new ArgumentNullException("serviceClient"); } IDictionary <string, ResourceSchema> result = new Dictionary <string, ResourceSchema>(); List <Method> createResourceMethods = new List <Method>(); foreach (Method method in serviceClient.Methods) { if (IsCreateResourceMethod(method)) { createResourceMethods.Add(method); } } string apiVersion = serviceClient.ApiVersion; foreach (Method createResourceMethod in createResourceMethods) { string afterPrefix = createResourceMethod.Url.Substring(resourceMethodPrefix.Length); int forwardSlashIndexAfterProvider = afterPrefix.IndexOf('/'); string resourceProvider = afterPrefix.Substring(0, forwardSlashIndexAfterProvider); ResourceSchema resourceSchema; if (!result.ContainsKey(resourceProvider)) { resourceSchema = new ResourceSchema(); if (apiVersion != null) { resourceSchema.Id = string.Format(CultureInfo.InvariantCulture, "http://schema.management.azure.com/schemas/{0}/{1}.json#", apiVersion, resourceProvider); } resourceSchema.Title = resourceProvider; resourceSchema.Description = resourceProvider.Replace('.', ' ') + " Resource Types"; resourceSchema.Schema = "http://json-schema.org/draft-04/schema#"; result.Add(resourceProvider, resourceSchema); } else { resourceSchema = result[resourceProvider]; } string methodUrlPathAfterProvider = afterPrefix.Substring(forwardSlashIndexAfterProvider + 1); string[] resourceTypes = GetResourceTypes(resourceProvider, methodUrlPathAfterProvider, createResourceMethod.Parameters); foreach (string resourceType in resourceTypes) { JsonSchema resourceDefinition = new JsonSchema(); resourceDefinition.JsonType = "object"; resourceDefinition.AddProperty("type", new JsonSchema() { JsonType = "string" }.AddEnum(resourceType), true); if (!string.IsNullOrWhiteSpace(apiVersion)) { resourceDefinition.AddProperty("apiVersion", new JsonSchema() { JsonType = "string" }.AddEnum(apiVersion), true); } if (createResourceMethod.Body != null) { CompositeType body = createResourceMethod.Body.Type as CompositeType; Debug.Assert(body != null, "The create resource method's body must be a CompositeType and cannot be null."); if (body != null) { foreach (Property property in body.Properties) { if (!resourceDefinition.Properties.Keys.Contains(property.Name)) { JsonSchema propertyDefinition = ParseProperty(property, resourceSchema.Definitions); if (propertyDefinition != null) { resourceDefinition.AddProperty(property.Name, propertyDefinition, property.IsRequired || property.Name == "properties"); } } } } } resourceDefinition.Description = resourceType; string resourcePropertyName = resourceType.Substring(resourceProvider.Length + 1).Replace('/', '_'); Debug.Assert(!resourceSchema.ResourceDefinitions.ContainsKey(resourcePropertyName)); resourceSchema.AddResourceDefinition(resourcePropertyName, resourceDefinition); } } // This loop adds child resource schemas to their parent resource schemas. We can't do // this until we're done adding all resources as top level resources, though, because // it's possible that we will parse a child resource before we parse the parent // resource. foreach (ResourceSchema resourceSchema in result.Values) { // By iterating over the reverse order of the defined resource definitions, I'm // counting on the resource definitions being in sorted order. That way I'm // guaranteed to visit child resource definitions before I visit their parent // resource definitions. By doing this, I've guaranteed that grandchildren resource // definitions will be added to their grandparent (and beyond) ancestor // resource definitions. foreach (string resourcePropertyName in resourceSchema.ResourceDefinitions.Keys.Reverse()) { JsonSchema resourceDefinition = resourceSchema.ResourceDefinitions[resourcePropertyName]; string resourceType = resourceDefinition.ResourceType; int lastSlashIndex = resourceType.LastIndexOf('/'); string parentResourceType = resourceType.Substring(0, lastSlashIndex); JsonSchema parentResourceDefinition = resourceSchema.GetResourceDefinitionByResourceType(parentResourceType); if (parentResourceDefinition != null) { string childResourceType = resourceType.Substring(lastSlashIndex + 1); JsonSchema childResourceDefinition = resourceDefinition.Clone(); childResourceDefinition.ResourceType = childResourceType; string childResourceDefinitionPropertyName = string.Join("_", resourcePropertyName, "childResource"); resourceSchema.AddDefinition(childResourceDefinitionPropertyName, childResourceDefinition); parentResourceDefinition.AddResource(new JsonSchema() { Ref = "#/definitions/" + childResourceDefinitionPropertyName, }); } } } return(result); }