diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Expected/CDN/Microsoft.Cdn.json b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Expected/CDN/Microsoft.Cdn.json index e700eddc424d5..aea39fe2be591 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Expected/CDN/Microsoft.Cdn.json +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Expected/CDN/Microsoft.Cdn.json @@ -35,6 +35,16 @@ "description": "The SKU (pricing tier) of the CDN profile." } }, + "resources": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/Microsoft.Cdn_profiles_endpoints_childResource" + } + ] + } + }, "required": [ "type", "apiVersion", @@ -73,6 +83,19 @@ "$ref": "#/definitions/EndpointPropertiesCreateParameters" } }, + "resources": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/Microsoft.Cdn_profiles_endpoints_customDomains_childResource" + }, + { + "$ref": "#/definitions/Microsoft.Cdn_profiles_endpoints_origins_childResource" + } + ] + } + }, "required": [ "type", "apiVersion", @@ -236,6 +259,109 @@ "origins" ] }, + "Microsoft.Cdn_profiles_endpoints_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "endpoints" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2016-04-02" + ] + }, + "location": { + "type": "string", + "description": "Endpoint location" + }, + "tags": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Endpoint tags" + }, + "properties": { + "$ref": "#/definitions/EndpointPropertiesCreateParameters" + } + }, + "resources": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/Microsoft.Cdn_profiles_endpoints_customDomains_childResource" + }, + { + "$ref": "#/definitions/Microsoft.Cdn_profiles_endpoints_origins_childResource" + } + ] + } + }, + "required": [ + "type", + "apiVersion", + "properties", + "location" + ], + "description": "Microsoft.Cdn/profiles/endpoints" + }, + "Microsoft.Cdn_profiles_endpoints_customDomains_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "customDomains" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2016-04-02" + ] + }, + "properties": { + "$ref": "#/definitions/CustomDomainPropertiesParameters" + } + }, + "required": [ + "type", + "apiVersion", + "properties" + ], + "description": "Microsoft.Cdn/profiles/endpoints/customDomains" + }, + "Microsoft.Cdn_profiles_endpoints_origins_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "origins" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2016-04-02" + ] + }, + "properties": { + "$ref": "#/definitions/OriginPropertiesParameters" + } + }, + "required": [ + "type", + "apiVersion", + "properties" + ], + "description": "Microsoft.Cdn/profiles/endpoints/origins" + }, "OriginPropertiesParameters": { "type": "object", "properties": { diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Expected/Compute/Microsoft.Compute.json b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Expected/Compute/Microsoft.Compute.json index 3f72704186ac0..bd56d31a80db4 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Expected/Compute/Microsoft.Compute.json +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Expected/Compute/Microsoft.Compute.json @@ -53,6 +53,16 @@ "$ref": "#/definitions/VirtualMachineProperties" } }, + "resources": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/Microsoft.Compute_virtualMachines_extensions_childResource" + } + ] + } + }, "required": [ "type", "apiVersion", @@ -458,6 +468,32 @@ }, "description": "Describes Windows Configuration of the OS Profile." }, + "Microsoft.Compute_virtualMachines_extensions_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "extensions" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2016-03-30" + ] + }, + "properties": { + "$ref": "#/definitions/VirtualMachineExtensionProperties" + } + }, + "required": [ + "type", + "apiVersion", + "properties" + ], + "description": "Microsoft.Compute/virtualMachines/extensions" + }, "NetworkInterfaceReference": { "type": "object", "properties": { diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Expected/Network/Microsoft.Network.json b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Expected/Network/Microsoft.Network.json index c547cb6314b49..30aa8da750f4e 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Expected/Network/Microsoft.Network.json +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Expected/Network/Microsoft.Network.json @@ -91,6 +91,19 @@ "description": "Gets a unique read-only string that changes whenever the resource is updated" } }, + "resources": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/Microsoft.Network_expressRouteCircuits_peerings_childResource" + }, + { + "$ref": "#/definitions/Microsoft.Network_expressRouteCircuits_authorizations_childResource" + } + ] + } + }, "required": [ "type", "apiVersion", @@ -279,6 +292,16 @@ "description": "Gets a unique read-only string that changes whenever the resource is updated" } }, + "resources": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/Microsoft.Network_networkSecurityGroups_securityRules_childResource" + } + ] + } + }, "required": [ "type", "apiVersion", @@ -373,6 +396,16 @@ "description": "Gets a unique read-only string that changes whenever the resource is updated" } }, + "resources": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/Microsoft.Network_routeTables_routes_childResource" + } + ] + } + }, "required": [ "type", "apiVersion", @@ -467,6 +500,16 @@ "description": "Gets a unique read-only string that changes whenever the resource is updated" } }, + "resources": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/Microsoft.Network_virtualnetworks_subnets_childResource" + } + ] + } + }, "required": [ "type", "apiVersion", @@ -1994,6 +2037,176 @@ }, "description": "LocalNetworkGateway properties" }, + "Microsoft.Network_expressRouteCircuits_authorizations_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "authorizations" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2016-03-30" + ] + }, + "properties": { + "$ref": "#/definitions/AuthorizationPropertiesFormat" + }, + "name": { + "type": "string", + "description": "Gets name of the resource that is unique within a resource group. This name can be used to access the resource" + }, + "etag": { + "type": "string", + "description": "A unique read-only string that changes whenever the resource is updated" + } + }, + "required": [ + "type", + "apiVersion", + "properties" + ], + "description": "Microsoft.Network/expressRouteCircuits/authorizations" + }, + "Microsoft.Network_expressRouteCircuits_peerings_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "peerings" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2016-03-30" + ] + }, + "properties": { + "$ref": "#/definitions/ExpressRouteCircuitPeeringPropertiesFormat" + }, + "name": { + "type": "string", + "description": "Gets name of the resource that is unique within a resource group. This name can be used to access the resource" + }, + "etag": { + "type": "string", + "description": "A unique read-only string that changes whenever the resource is updated" + } + }, + "required": [ + "type", + "apiVersion", + "properties" + ], + "description": "Microsoft.Network/expressRouteCircuits/peerings" + }, + "Microsoft.Network_networkSecurityGroups_securityRules_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "securityRules" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2016-03-30" + ] + }, + "properties": { + "$ref": "#/definitions/SecurityRulePropertiesFormat" + }, + "name": { + "type": "string", + "description": "Gets name of the resource that is unique within a resource group. This name can be used to access the resource" + }, + "etag": { + "type": "string", + "description": "A unique read-only string that changes whenever the resource is updated" + } + }, + "required": [ + "type", + "apiVersion", + "properties" + ], + "description": "Microsoft.Network/networkSecurityGroups/securityRules" + }, + "Microsoft.Network_routeTables_routes_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "routes" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2016-03-30" + ] + }, + "properties": { + "$ref": "#/definitions/RoutePropertiesFormat" + }, + "name": { + "type": "string", + "description": "Gets name of the resource that is unique within a resource group. This name can be used to access the resource" + }, + "etag": { + "type": "string", + "description": "A unique read-only string that changes whenever the resource is updated" + } + }, + "required": [ + "type", + "apiVersion", + "properties" + ], + "description": "Microsoft.Network/routeTables/routes" + }, + "Microsoft.Network_virtualnetworks_subnets_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "subnets" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2016-03-30" + ] + }, + "properties": { + "$ref": "#/definitions/SubnetPropertiesFormat" + }, + "name": { + "type": "string", + "description": "Gets name of the resource that is unique within a resource group. This name can be used to access the resource" + }, + "etag": { + "type": "string", + "description": "A unique read-only string that changes whenever the resource is updated" + } + }, + "required": [ + "type", + "apiVersion", + "properties" + ], + "description": "Microsoft.Network/virtualnetworks/subnets" + }, "NetworkInterface": { "type": "object", "properties": { diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Expected/Web/Microsoft.CertificateRegistration.json b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Expected/Web/Microsoft.CertificateRegistration.json index 827a0c795ff75..827c3149acf29 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Expected/Web/Microsoft.CertificateRegistration.json +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Expected/Web/Microsoft.CertificateRegistration.json @@ -23,6 +23,16 @@ "$ref": "#/definitions/CertificateOrder_properties" } }, + "resources": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/Microsoft.CertificateRegistration_certificateOrders_certificates_childResource" + } + ] + } + }, "required": [ "type", "apiVersion", @@ -300,6 +310,32 @@ "description": "Status of the Key Vault secret. Possible values include: 'Initialized', 'WaitingOnCertificateOrder', 'Succeeded', 'CertificateOrderFailed', 'OperationNotPermittedOnKeyVault', 'AzureServiceUnauthorizedToAccessKeyVault', 'KeyVaultDoesNotExist', 'KeyVaultSecretDoesNotExist', 'UnknownError', 'Unknown'" } } + }, + "Microsoft.CertificateRegistration_certificateOrders_certificates_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "certificates" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2015-08-01" + ] + }, + "properties": { + "$ref": "#/definitions/CertificateOrderCertificate_properties" + } + }, + "required": [ + "type", + "apiVersion", + "properties" + ], + "description": "Microsoft.CertificateRegistration/certificateOrders/certificates" } } } diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Expected/Web/Microsoft.Web.json b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Expected/Web/Microsoft.Web.json index 151bb9d3ee88f..170afb6aae065 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Expected/Web/Microsoft.Web.json +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Expected/Web/Microsoft.Web.json @@ -75,6 +75,16 @@ "$ref": "#/definitions/HostingEnvironment_properties" } }, + "resources": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/Microsoft.Web_hostingEnvironments_workerPools_childResource" + } + ] + } + }, "required": [ "type", "apiVersion", @@ -237,6 +247,28 @@ "$ref": "#/definitions/Site_properties" } }, + "resources": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/Microsoft.Web_sites_hybridconnection_childResource" + }, + { + "$ref": "#/definitions/Microsoft.Web_sites_hostNameBindings_childResource" + }, + { + "$ref": "#/definitions/Microsoft.Web_sites_deployments_childResource" + }, + { + "$ref": "#/definitions/Microsoft.Web_sites_slots_childResource" + }, + { + "$ref": "#/definitions/Microsoft.Web_sites_virtualNetworkConnections_childResource" + } + ] + } + }, "required": [ "type", "apiVersion", @@ -367,6 +399,25 @@ "$ref": "#/definitions/Site_properties" } }, + "resources": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/Microsoft.Web_sites_slots_hybridconnection_childResource" + }, + { + "$ref": "#/definitions/Microsoft.Web_sites_slots_hostNameBindings_childResource" + }, + { + "$ref": "#/definitions/Microsoft.Web_sites_slots_deployments_childResource" + }, + { + "$ref": "#/definitions/Microsoft.Web_sites_slots_virtualNetworkConnections_childResource" + } + ] + } + }, "required": [ "type", "apiVersion", @@ -497,6 +548,16 @@ "$ref": "#/definitions/VnetInfo_properties" } }, + "resources": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/Microsoft.Web_sites_slots_virtualNetworkConnections_gateways_childResource" + } + ] + } + }, "required": [ "type", "apiVersion", @@ -549,6 +610,16 @@ "$ref": "#/definitions/VnetInfo_properties" } }, + "resources": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/Microsoft.Web_sites_virtualNetworkConnections_gateways_childResource" + } + ] + } + }, "required": [ "type", "apiVersion", @@ -1216,6 +1287,357 @@ }, "description": "Represents an ip security restriction on a web app." }, + "Microsoft.Web_hostingEnvironments_workerPools_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "workerPools" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2015-08-01" + ] + }, + "properties": { + "$ref": "#/definitions/WorkerPool_properties" + }, + "sku": { + "$ref": "#/definitions/SkuDescription" + } + }, + "required": [ + "type", + "apiVersion", + "properties" + ], + "description": "Microsoft.Web/hostingEnvironments/workerPools" + }, + "Microsoft.Web_sites_deployments_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "deployments" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2015-08-01" + ] + }, + "properties": { + "$ref": "#/definitions/Deployment_properties" + } + }, + "required": [ + "type", + "apiVersion", + "properties" + ], + "description": "Microsoft.Web/sites/deployments" + }, + "Microsoft.Web_sites_hostNameBindings_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "hostNameBindings" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2015-08-01" + ] + }, + "properties": { + "$ref": "#/definitions/HostNameBinding_properties" + } + }, + "required": [ + "type", + "apiVersion", + "properties" + ], + "description": "Microsoft.Web/sites/hostNameBindings" + }, + "Microsoft.Web_sites_hybridconnection_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "hybridconnection" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2015-08-01" + ] + }, + "properties": { + "$ref": "#/definitions/RelayServiceConnectionEntity_properties" + } + }, + "required": [ + "type", + "apiVersion", + "properties" + ], + "description": "Microsoft.Web/sites/hybridconnection" + }, + "Microsoft.Web_sites_slots_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "slots" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2015-08-01" + ] + }, + "properties": { + "$ref": "#/definitions/Site_properties" + } + }, + "resources": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/Microsoft.Web_sites_slots_hybridconnection_childResource" + }, + { + "$ref": "#/definitions/Microsoft.Web_sites_slots_hostNameBindings_childResource" + }, + { + "$ref": "#/definitions/Microsoft.Web_sites_slots_deployments_childResource" + } + ] + } + }, + "required": [ + "type", + "apiVersion", + "properties" + ], + "description": "Microsoft.Web/sites/slots" + }, + "Microsoft.Web_sites_slots_deployments_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "deployments" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2015-08-01" + ] + }, + "properties": { + "$ref": "#/definitions/Deployment_properties" + } + }, + "required": [ + "type", + "apiVersion", + "properties" + ], + "description": "Microsoft.Web/sites/slots/deployments" + }, + "Microsoft.Web_sites_slots_hostNameBindings_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "hostNameBindings" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2015-08-01" + ] + }, + "properties": { + "$ref": "#/definitions/HostNameBinding_properties" + } + }, + "required": [ + "type", + "apiVersion", + "properties" + ], + "description": "Microsoft.Web/sites/slots/hostNameBindings" + }, + "Microsoft.Web_sites_slots_hybridconnection_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "hybridconnection" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2015-08-01" + ] + }, + "properties": { + "$ref": "#/definitions/RelayServiceConnectionEntity_properties" + } + }, + "required": [ + "type", + "apiVersion", + "properties" + ], + "description": "Microsoft.Web/sites/slots/hybridconnection" + }, + "Microsoft.Web_sites_slots_virtualNetworkConnections_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "virtualNetworkConnections" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2015-08-01" + ] + }, + "properties": { + "$ref": "#/definitions/VnetInfo_properties" + } + }, + "resources": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/Microsoft.Web_sites_slots_virtualNetworkConnections_gateways_childResource" + } + ] + } + }, + "required": [ + "type", + "apiVersion", + "properties" + ], + "description": "Microsoft.Web/sites/slots/virtualNetworkConnections" + }, + "Microsoft.Web_sites_slots_virtualNetworkConnections_gateways_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "gateways" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2015-08-01" + ] + }, + "properties": { + "$ref": "#/definitions/VnetGateway_properties" + } + }, + "required": [ + "type", + "apiVersion", + "properties" + ], + "description": "Microsoft.Web/sites/slots/virtualNetworkConnections/gateways" + }, + "Microsoft.Web_sites_virtualNetworkConnections_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "virtualNetworkConnections" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2015-08-01" + ] + }, + "properties": { + "$ref": "#/definitions/VnetInfo_properties" + } + }, + "resources": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/Microsoft.Web_sites_virtualNetworkConnections_gateways_childResource" + } + ] + } + }, + "required": [ + "type", + "apiVersion", + "properties" + ], + "description": "Microsoft.Web/sites/virtualNetworkConnections" + }, + "Microsoft.Web_sites_virtualNetworkConnections_gateways_childResource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "gateways" + ] + }, + "apiVersion": { + "type": "string", + "enum": [ + "2015-08-01" + ] + }, + "properties": { + "$ref": "#/definitions/VnetGateway_properties" + } + }, + "required": [ + "type", + "apiVersion", + "properties" + ], + "description": "Microsoft.Web/sites/virtualNetworkConnections/gateways" + }, "NameValuePair": { "type": "object", "properties": { diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/JsonSchema.cs b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/JsonSchema.cs index b178f93c57265..26beb8c8606a7 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/JsonSchema.cs +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/JsonSchema.cs @@ -16,16 +16,7 @@ public class JsonSchema private IList enumList; private IDictionary properties; private IList requiredList; - - /// - /// The $schema metadata that points to a URL or file location where this schema's schema is stored. - /// - public string Schema { get; set; } - - /// - /// The title metadata for this schema. - /// - public string Title { get; set; } + private IList resources; /// /// A reference to the location in the parent schema where this schema's definition can be @@ -46,9 +37,47 @@ public class JsonSchema /// /// The type metadata of this schema that describes what type matching JSON values must be. + /// For example, this value will be either "object", "string", "array", "integer", + /// "number", or "boolean". /// public string JsonType { get; set; } + /// + /// Get the resource type of this JsonSchema. If this JsonSchema defines an Azure Resource, + /// then this value will be found in definition.properties.type.enum[0]. If this JsonSchema + /// does not define an Azure Resource, then this will return null. + /// + public string ResourceType + { + get + { + string result = null; + + if (Properties != null && + Properties.ContainsKey("type") && + Properties["type"].Enum != null) + { + result = Properties["type"].Enum.SingleOrDefault(); + } + + return result; + } + set + { + if (properties == null) + { + properties = new Dictionary(); + } + + if (!Properties.ContainsKey("type")) + { + Properties["type"] = new JsonSchema(); + } + + Properties["type"].enumList = new List() { value }; + } + } + /// /// The schema that matches additional properties that have not been specified in the /// Properties dictionary. @@ -59,7 +88,7 @@ public class JsonSchema /// An enumeration of values that will match this JSON schema. Any value not in this /// enumeration will not match this schema. /// - public IEnumerable Enum + public IList Enum { get { return enumList; } } @@ -80,6 +109,14 @@ public IList Required get { return requiredList; } } + /// + /// The child resources that are allowed for this JsonSchema. + /// + public IList Resources + { + get { return resources; } + } + /// /// Add a new value (or values) to this JsonSchema's enum list. This JsonSchema (with the /// new value(s)) is then returned so that additional changes can be chained together. @@ -213,6 +250,102 @@ public JsonSchema AddRequired(string requiredPropertyName, params string[] extra return this; } + /// + /// Add a child resource schema to this JsonSchema. + /// + /// The child resource schema to add to this JsonSchema. + /// + public JsonSchema AddResource(JsonSchema childResourceSchema) + { + if (childResourceSchema == null) + { + throw new ArgumentNullException("childResourceSchema"); + } + + if (resources == null) + { + resources = new List(); + } + resources.Add(childResourceSchema); + + return this; + } + + /// + /// Create a new JsonSchema that is an exact copy of this one. + /// + /// + public JsonSchema Clone() + { + JsonSchema result = new JsonSchema(); + result.Ref = Ref; + result.Items = Clone(Items); + result.Description = Description; + result.JsonType = JsonType; + result.AdditionalProperties = Clone(AdditionalProperties); + result.enumList = Clone(Enum); + result.properties = Clone(Properties); + result.requiredList = Clone(Required); + result.resources = Clone(Resources); + return result; + } + + private static JsonSchema Clone(JsonSchema toClone) + { + JsonSchema result = null; + + if (toClone != null) + { + result = toClone.Clone(); + } + + return result; + } + + private static IList Clone(IList toClone) + { + IList result = null; + + if (toClone != null) + { + result = new List(toClone); + } + + return result; + } + + private static IList Clone(IList toClone) + { + IList result = null; + + if (toClone != null) + { + result = new List(); + foreach (JsonSchema schema in toClone) + { + result.Add(Clone(schema)); + } + } + + return result; + } + + private static IDictionary Clone(IDictionary toClone) + { + IDictionary result = null; + + if (toClone != null) + { + result = new Dictionary(); + foreach (string key in toClone.Keys) + { + result.Add(key, Clone(toClone[key])); + } + } + + return result; + } + public override bool Equals(object obj) { bool result = false; @@ -220,9 +353,7 @@ public override bool Equals(object obj) JsonSchema rhs = obj as JsonSchema; if (rhs != null) { - result = Equals(Schema, rhs.Schema) && - Equals(Title, rhs.Title) && - Equals(Ref, rhs.Ref) && + result = Equals(Ref, rhs.Ref) && Equals(Items, rhs.Items) && Equals(JsonType, rhs.JsonType) && Equals(AdditionalProperties, rhs.AdditionalProperties) && @@ -238,8 +369,6 @@ public override bool Equals(object obj) public override int GetHashCode() { return GetHashCode(GetType()) ^ - GetHashCode(Schema) ^ - GetHashCode(Title) ^ GetHashCode(Ref) ^ GetHashCode(Items) ^ GetHashCode(Description) ^ diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/ResourceSchema.cs b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/ResourceSchema.cs index 201d998023d4e..b13224550c1cd 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/ResourceSchema.cs +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/ResourceSchema.cs @@ -55,6 +55,35 @@ public IDictionary Definitions get { return definitions; } } + /// + /// Search this ResourceSchema for a resource definition that has the provided type. + /// + /// The resource type to look for in this ResourceSchema. + /// + public JsonSchema GetResourceDefinitionByResourceType(string resourceType) + { + if (string.IsNullOrWhiteSpace(resourceType)) + { + throw new ArgumentException("resourceType cannot be null or whitespace.", "resourceType"); + } + + JsonSchema result = null; + + if (resourceDefinitions != null && resourceDefinitions.Count > 0) + { + foreach(JsonSchema resourceDefinition in resourceDefinitions.Values) + { + if (resourceDefinition.ResourceType == resourceType) + { + result = resourceDefinition; + break; + } + } + } + + return result; + } + /// /// Add the provided resource definition JSON schema to this resourceh schema. /// diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/ResourceSchemaParser.cs b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/ResourceSchemaParser.cs index cf8ada84843c4..28abf47ca8657 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/ResourceSchemaParser.cs +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/ResourceSchemaParser.cs @@ -122,9 +122,46 @@ public static IDictionary Parse(ServiceClient serviceClie } } - string resourceName = resourceType.Replace('/', '_'); - Debug.Assert(!resourceSchema.ResourceDefinitions.ContainsKey(resourceName)); - resourceSchema.AddResourceDefinition(resourceName, resourceDefinition); + string resourcePropertyName = resourceType.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 = resourcePropertyName + "_childResource"; + resourceSchema.AddDefinition(childResourceDefinitionPropertyName, childResourceDefinition); + + parentResourceDefinition.AddResource(new JsonSchema() + { + Ref = "#/definitions/" + childResourceDefinitionPropertyName, + }); + } + } } return result; diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/ResourceSchemaWriter.cs b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/ResourceSchemaWriter.cs index 9ab0f1ba8b81a..ad9ae3b4fa2b8 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/ResourceSchemaWriter.cs +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/ResourceSchemaWriter.cs @@ -85,19 +85,30 @@ internal static void WriteDefinition(JsonTextWriter writer, string resourceName, if (definition != null) { writer.WritePropertyName(resourceName); - writer.WriteStartObject(); - - WriteProperty(writer, "type", definition.JsonType); - WriteStringArray(writer, "enum", definition.Enum); - WriteProperty(writer, "$ref", definition.Ref); - WriteDefinition(writer, "items", definition.Items); - WriteDefinition(writer, "additionalProperties", definition.AdditionalProperties); - WriteDefinitionMap(writer, "properties", definition.Properties); - WriteStringArray(writer, "required", definition.Required); - WriteProperty(writer, "description", definition.Description); + WriteDefinition(writer, definition); + } + } - writer.WriteEndObject(); + private static void WriteDefinition(JsonTextWriter writer, JsonSchema definition) + { + if (definition == null) + { + throw new ArgumentNullException("definition"); } + + writer.WriteStartObject(); + + WriteProperty(writer, "type", definition.JsonType); + WriteStringArray(writer, "enum", definition.Enum); + WriteProperty(writer, "$ref", definition.Ref); + WriteDefinition(writer, "items", definition.Items); + WriteDefinition(writer, "additionalProperties", definition.AdditionalProperties); + WriteDefinitionMap(writer, "properties", definition.Properties); + WriteDefinitionArray(writer, "resources", definition.Resources); + WriteStringArray(writer, "required", definition.Required); + WriteProperty(writer, "description", definition.Description); + + writer.WriteEndObject(); } private static void WriteStringArray(JsonTextWriter writer, string arrayName, IEnumerable arrayValues) @@ -114,6 +125,32 @@ private static void WriteStringArray(JsonTextWriter writer, string arrayName, IE } } + private static void WriteDefinitionArray(JsonTextWriter writer, string arrayName, IEnumerable arrayDefinitions) + { + if (arrayDefinitions != null && arrayDefinitions.Count() > 0) + { + writer.WritePropertyName(arrayName); + writer.WriteStartObject(); + + WriteProperty(writer, "type", "array"); + + writer.WritePropertyName("items"); + writer.WriteStartObject(); + + writer.WritePropertyName("oneOf"); + writer.WriteStartArray(); + foreach (JsonSchema definition in arrayDefinitions) + { + WriteDefinition(writer, definition); + } + writer.WriteEndArray(); + + writer.WriteEndObject(); + + writer.WriteEndObject(); + } + } + internal static void WriteProperty(JsonTextWriter writer, string propertyName, string propertyValue) { if (writer == null)