/// <summary> /// Creates long running operation methods. /// </summary> /// <param name="codeModelient"></param> public static void AddLongRunningOperations(CodeModel codeModel) { if (codeModel == null) { throw new ArgumentNullException("codeModel"); } foreach (var method in codeModel.Methods.Where(each => each.Extensions.ContainsKey(LongRunningExtension)).Distinct(each => each.Group + each.Name).ToArray()) { var isLongRunning = method.Extensions[LongRunningExtension]; if (true == isLongRunning as bool?) { // copy the method var m = Duplicate(method); // x-ms-examples of source method do not really apply m.Extensions.Remove(Core.Model.XmsExtensions.Examples.Name); // change the name, remove the extension. m.Name = "Begin" + m.Name.ToPascalCase(); m.Extensions.Remove(LongRunningExtension); codeModel.Add(m); } } }
/// <summary> /// Set default response to CloudError if not defined explicitly. /// </summary> /// <param name="codeModelient"></param> public static void SetDefaultResponses(CodeModel codeModel) { if (codeModel == null) { throw new ArgumentNullException("codeModel"); } // Create CloudError if not already defined CompositeType cloudError = codeModel.ModelTypes.FirstOrDefault(c => c.Name.EqualsIgnoreCase("cloudError")); if (cloudError == null) { cloudError = New <CompositeType>(new { Name = "cloudError", SerializedName = "cloudError" }); cloudError.Extensions[ExternalExtension] = true; codeModel.Add(cloudError); } // Set default response if not defined explicitly foreach (var method in codeModel.Methods) { if (method.DefaultResponse.Body == null) { method.DefaultResponse = New <Response>(cloudError, method.ReturnType.Headers); } } }
private static async Task TestGenerate(string apiVersion, string[] methodUrls, string expectedJsonString) { using (NewContext) { MemoryFileSystem fileSystem = new MemoryFileSystem(); Settings settings = new Settings(); settings.FileSystemOutput = fileSystem; CodeModel serviceClient = New <CodeModel>(); serviceClient.ApiVersion = apiVersion; foreach (string methodUrl in methodUrls) { serviceClient.Add(New <Method>(new { Url = methodUrl, HttpMethod = HttpMethod.Put, })); } await CreatePlugin().CodeGenerator.Generate(serviceClient); Assert.Equal(2, fileSystem.VirtualStore.Count); string folderPath = fileSystem.VirtualStore.Keys.First(); Assert.Equal("Folder", fileSystem.VirtualStore[folderPath].ToString()); JObject expectedJSON = JObject.Parse(expectedJsonString); string fileContents = fileSystem.VirtualStore[fileSystem.VirtualStore.Keys.Skip(1).First()].ToString(); JObject actualJson = JObject.Parse(fileContents); Assert.Equal(expectedJSON, actualJson); } }
public void Load(BinaryReader rdr) { P0.Clear(); Codes.Clear(); CodeSize = rdr.ReadInt32(); int count = rdr.ReadInt32(); for (int i = 0; i < count; i++) { int key = rdr.ReadInt32(); double value = rdr.ReadDouble(); P0.Add(key, value); } count = rdr.ReadInt32(); for (int i = 0; i < count; i++) { int key = rdr.ReadInt32(); var codeModel = new CodeModel(); int count2 = rdr.ReadInt32(); for (int j = 0; j < count2; j++) { codeModel.Add(rdr.ReadInt32(), rdr.ReadDouble()); } Codes[key] = codeModel; } }
private static Parameter CreateParameterFromGrouping(IEnumerable <ParameterTransformation> grouping, Method method, CodeModel codeModel) { var properties = new List <Property>(); string parameterGroupName = null; foreach (var parameter in grouping.Select(g => g.OutputParameter)) { Newtonsoft.Json.Linq.JContainer extensionObject = parameter.Extensions[ParameterGroupExtension] as Newtonsoft.Json.Linq.JContainer; string specifiedGroupName = extensionObject.Value <string>("name"); if (specifiedGroupName == null) { string postfix = extensionObject.Value <string>("postfix") ?? "Parameters"; parameterGroupName = method.Group + "-" + method.Name + "-" + postfix; } else { parameterGroupName = specifiedGroupName; } Property groupProperty = New <Property>(new { IsReadOnly = false, //Since these properties are used as parameters they are never read only Name = parameter.Name, IsRequired = parameter.IsRequired, DefaultValue = parameter.DefaultValue, //Constraints = parameter.Constraints, Omit these since we don't want to perform parameter validation Documentation = parameter.Documentation, ModelType = parameter.ModelType, SerializedName = default(string) //Parameter is never serialized directly }); properties.Add(groupProperty); } var parameterGroupType = New <CompositeType>(parameterGroupName, new { Documentation = "Additional parameters for the " + method.Name + " operation." }); //Add to the service client codeModel.Add(parameterGroupType); foreach (Property property in properties) { parameterGroupType.Add(property); } bool isGroupParameterRequired = parameterGroupType.Properties.Any(p => p.IsRequired); //Create the new parameter object based on the parameter group type return(New <Parameter>(new { Name = parameterGroupName, IsRequired = isGroupParameterRequired, Location = ParameterLocation.None, SerializedName = string.Empty, ModelType = parameterGroupType, Documentation = "Additional parameters for the operation" })); }
public void ParseWithCodeModelWithCreateResourceMethod() { CodeModel codeModel = New <CodeModel>(); codeModel.ApiVersion = "2016-01-01"; Parameter body = New <Parameter>(new { Location = ParameterLocation.Body, Type = New <CompositeType>(), }); CompositeType responseBody = New <CompositeType>(); responseBody.Extensions.Add("x-ms-azure-resource", true); const string url = "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Mock.Provider/mockResourceNames/{mockResourceName}"; Method method = New <Method>(new { HttpMethod = HttpMethod.Put, ReturnType = new Response(responseBody, null), Url = url, }); method.Add(body); codeModel.Add(method); IDictionary <string, ResourceSchema> schemas = ResourceSchemaParser.Parse(codeModel); Assert.NotNull(schemas); Assert.Equal(1, schemas.Count); ResourceSchema schema = schemas["Mock.Provider"]; Assert.Equal("http://schema.management.azure.com/schemas/2016-01-01/Mock.Provider.json#", schema.Id); Assert.Equal("http://json-schema.org/draft-04/schema#", schema.Schema); Assert.Equal("Mock.Provider", schema.Title); Assert.Equal("Mock Provider Resource Types", schema.Description); Assert.Equal(1, schema.ResourceDefinitions.Count); Assert.Equal("mockResourceNames", schema.ResourceDefinitions.Keys.Single()); Assert.Equal( new JsonSchema() { JsonType = "object", Description = "Mock.Provider/mockResourceNames" } .AddProperty("type", JsonSchema.CreateStringEnum("Mock.Provider/mockResourceNames"), true) .AddProperty("apiVersion", JsonSchema.CreateStringEnum("2016-01-01"), true), schema.ResourceDefinitions["mockResourceNames"]); Assert.NotNull(schema.Definitions); Assert.Equal(0, schema.Definitions.Count); }
protected void PopulateAdditionalProperties(CodeModel codeModel) { if (Settings.Instance.AddCredentials) { codeModel.Add(New <Property>(new { Name = "Credentials", ModelType = New <PrimaryType>(KnownPrimaryType.Credentials), IsRequired = true, IsReadOnly = true, Documentation = "Subscription credentials which uniquely identify client subscription." })); } }
private void PopulateAdditionalProperties(CodeModel codeModel) { if (Settings.Instance.AddCredentials) { if (!codeModel.Properties.Any(p => p.ModelType.IsPrimaryType(KnownPrimaryType.Credentials))) { codeModel.Add(New <Property>(new { Name = "credentials", SerializedName = "credentials", ModelType = New <PrimaryType>(KnownPrimaryType.Credentials), IsRequired = true, Documentation = "Subscription credentials which uniquely identify client subscription." })); } } }
/// <summary> /// Creates azure specific properties. /// </summary> /// <param name="codeModelient"></param> private static void AddAzureProperties(CodeModel codeModel) { var acceptLanguage = codeModel.Properties .FirstOrDefault(p => AzureExtensions.AcceptLanguage.EqualsIgnoreCase(p.SerializedName)); AzureExtensions.AddAzureProperties(codeModel); codeModel.Remove(codeModel.Properties.FirstOrDefault(p => p.Name == "long_running_operation_retry_timeout")); codeModel.Remove(codeModel.Properties.FirstOrDefault(p => p.Name == "generate_client_request_id")); codeModel.Remove(codeModel.Properties.FirstOrDefault(p => p.Name == "accept_language")); if (acceptLanguage != null) // && acceptLanguage.DefaultValue != "en-US" { acceptLanguage.IsReadOnly = true; acceptLanguage.IsRequired = false; acceptLanguage.ModelType = New <PrimaryType>(KnownPrimaryType.String); codeModel.Add(acceptLanguage); } }
/// <summary> /// Adds ListNext() method for each List method with x-ms-pageable extension. /// </summary> /// <param name="codeModelient"></param> /// <param name="codeNamer"></param> public static void AddPageableMethod(CodeModel codeModel) { if (codeModel == null) { throw new ArgumentNullException("codeModel"); } foreach (var method in codeModel.Methods.Distinct(each => each.Group + each.Name).ToArray()) { if (method.Extensions.ContainsKey(PageableExtension)) { var pageableExtension = JsonConvert.DeserializeObject <PageableExtension>(method.Extensions[PageableExtension].ToString()); if (string.IsNullOrWhiteSpace(pageableExtension.NextLinkName)) { continue; } Method nextLinkMethod = null; if (!string.IsNullOrEmpty(pageableExtension.OperationName)) { nextLinkMethod = codeModel.Methods.FirstOrDefault(m => pageableExtension.OperationName.EqualsIgnoreCase(m.SerializedName)); if (nextLinkMethod != null) { nextLinkMethod.Extensions["nextLinkMethod"] = true; method.Extensions["nextMethodName"] = nextLinkMethod.Name; method.Extensions["nextMethodGroup"] = nextLinkMethod.Group; } } if (nextLinkMethod == null) { nextLinkMethod = Duplicate <Method>(method); if (!string.IsNullOrEmpty(pageableExtension.OperationName)) { nextLinkMethod.Name = CodeNamer.Instance.GetMethodName(SwaggerModeler.GetMethodName( new Operation { OperationId = pageableExtension.OperationName })); nextLinkMethod.Group = CodeNamer.Instance.GetMethodGroupName(SwaggerModeler.GetMethodGroup( new Operation { OperationId = pageableExtension.OperationName })); } else { nextLinkMethod.Name = nextLinkMethod.Name + "Next"; } method.Extensions["nextMethodName"] = nextLinkMethod.Name; method.Extensions["nextMethodGroup"] = nextLinkMethod.Group; nextLinkMethod.Extensions["nextLinkMethod"] = true; nextLinkMethod.ClearParameters(); nextLinkMethod.Url = "{nextLink}"; nextLinkMethod.IsAbsoluteUrl = true; var nextLinkParameter = New <Parameter>(new { Name = "nextPageLink", SerializedName = "nextLink", ModelType = New <PrimaryType>(KnownPrimaryType.String), Documentation = "The NextLink from the previous successful call to List operation.", IsRequired = true, Location = ParameterLocation.Path }); nextLinkParameter.Extensions[SkipUrlEncodingExtension] = true; nextLinkMethod.Add(nextLinkParameter); // Need copy all the header parameters from List method to ListNext method foreach (var param in method.Parameters.Where(p => p.Location == ParameterLocation.Header)) { nextLinkMethod.Add(Duplicate(param)); } // Copy all grouped parameters that only contain header parameters nextLinkMethod.InputParameterTransformation.Clear(); method.InputParameterTransformation.GroupBy(t => t.ParameterMappings[0].InputParameter) .ForEach(grouping => { if (grouping.All(t => t.OutputParameter.Location == ParameterLocation.Header)) { // All grouped properties were header parameters, reuse data type nextLinkMethod.Add(grouping.Key); grouping.ForEach(t => nextLinkMethod.InputParameterTransformation.Add(t)); } else if (grouping.Any(t => t.OutputParameter.Location == ParameterLocation.Header)) { // Some grouped properties were header parameters, creating new data types var headerGrouping = grouping.Where(t => t.OutputParameter.Location == ParameterLocation.Header); headerGrouping.ForEach(t => nextLinkMethod.InputParameterTransformation.Add((ParameterTransformation)t.Clone())); var newGroupingParam = CreateParameterFromGrouping(headerGrouping, nextLinkMethod, codeModel); nextLinkMethod.Add(newGroupingParam); //grouping.Key.Name = newGroupingParam.Name; // var inputParameter = (Parameter) nextLinkMethod.InputParameterTransformation.First().ParameterMappings[0].InputParameter.Clone(); var inputParameter = Duplicate(nextLinkMethod.InputParameterTransformation.First().ParameterMappings[0].InputParameter); inputParameter.Name = CodeNamer.Instance.GetParameterName(newGroupingParam.Name); inputParameter.IsRequired = newGroupingParam.IsRequired; nextLinkMethod.InputParameterTransformation.ForEach(t => t.ParameterMappings[0].InputParameter = inputParameter); } }); codeModel.Add(nextLinkMethod); } } } }
/// <summary> /// Creates azure specific properties. /// </summary> /// <param name="codeModelient"></param> public static void AddAzureProperties(CodeModel codeModel) { if (codeModel == null) { throw new ArgumentNullException("codeModel"); } var apiVersion = codeModel.Properties .FirstOrDefault(p => ApiVersion.EqualsIgnoreCase(p.SerializedName)); if (apiVersion != null) { apiVersion.DefaultValue = codeModel.ApiVersion; apiVersion.IsReadOnly = true; apiVersion.IsRequired = false; } var subscriptionId = codeModel.Properties.FirstOrDefault( p => p.Name.EqualsIgnoreCase("subscriptionId")); if (subscriptionId != null) { subscriptionId.IsRequired = true; } var acceptLanguage = codeModel.Properties .FirstOrDefault(p => AcceptLanguage.EqualsIgnoreCase(p.SerializedName)); if (acceptLanguage == null) { acceptLanguage = New <Property>(new { Name = AcceptLanguage, Documentation = "Gets or sets the preferred language for the response.", SerializedName = AcceptLanguage, DefaultValue = "en-US" }); codeModel.Add(acceptLanguage); } acceptLanguage.IsReadOnly = false; acceptLanguage.IsRequired = false; acceptLanguage.ModelType = New <PrimaryType>(KnownPrimaryType.String); codeModel.Methods .Where(m => !m.Parameters.Any(p => AcceptLanguage.EqualsIgnoreCase(p.SerializedName))) .ForEach(m2 => m2.Add(New <Parameter>(new { ClientProperty = acceptLanguage, Location = ParameterLocation.Header }).LoadFrom(acceptLanguage))); codeModel.Insert(New <Property>(new { Name = "Credentials", SerializedName = "credentials", ModelType = New <PrimaryType>(KnownPrimaryType.Credentials), IsRequired = true, IsReadOnly = true, Documentation = "Credentials needed for the client to connect to Azure." })); codeModel.Add(New <Property>(new { Name = "LongRunningOperationRetryTimeout", SerializedName = "longRunningOperationRetryTimeout", ModelType = New <PrimaryType>(KnownPrimaryType.Int), Documentation = "Gets or sets the retry timeout in seconds for Long Running Operations. Default value is 30.", DefaultValue = "30" })); codeModel.Add(New <Property>(new { Name = "GenerateClientRequestId", SerializedName = "generateClientRequestId", ModelType = New <PrimaryType>(KnownPrimaryType.Boolean), Documentation = "When set to true a unique x-ms-client-request-id value is generated and included in each request. Default is true.", DefaultValue = "true" })); }
private static CodeModel Merge(CodeModel compositeClient, CodeModel subClient) { if (compositeClient == null) { throw new ArgumentNullException("compositeClient"); } if (subClient == null) { throw new ArgumentNullException("subClient"); } // Merge if (compositeClient.BaseUrl == null) { compositeClient.BaseUrl = subClient.BaseUrl; } else { AssertEquals(compositeClient.BaseUrl, subClient.BaseUrl, "BaseUrl"); } // Copy client properties foreach (var subClientProperty in subClient.Properties) { if (subClientProperty.SerializedName == "api-version") { continue; } var compositeClientProperty = compositeClient.Properties.FirstOrDefault(p => p.Name == subClientProperty.Name); if (compositeClientProperty == null) { compositeClient.Add(subClientProperty); } else { AssertJsonEquals(compositeClientProperty, subClientProperty); } } // Copy models foreach (var subClientModel in subClient.ModelTypes) { var compositeClientModel = compositeClient.ModelTypes.FirstOrDefault(p => p.Name == subClientModel.Name); if (compositeClientModel == null) { compositeClient.Add(subClientModel); } else { AssertJsonEquals(compositeClientModel, subClientModel); } } // Copy enum types foreach (var subClientModel in subClient.EnumTypes) { var compositeClientModel = compositeClient.EnumTypes.FirstOrDefault(p => p.Name == subClientModel.Name); if (compositeClientModel == null) { compositeClient.Add(subClientModel); } else { AssertJsonEquals(compositeClientModel, subClientModel); } } // Copy error types foreach (var subClientModel in subClient.ErrorTypes) { var compositeClientModel = compositeClient.ErrorTypes.FirstOrDefault(p => p.Name == subClientModel.Name); if (compositeClientModel == null) { compositeClient.AddError(subClientModel); } else { AssertJsonEquals(compositeClientModel, subClientModel); } } // Copy header types foreach (var subClientModel in subClient.HeaderTypes) { var compositeClientModel = compositeClient.HeaderTypes.FirstOrDefault(p => p.Name == subClientModel.Name); if (compositeClientModel == null) { compositeClient.AddHeader(subClientModel); } else { AssertJsonEquals(compositeClientModel, subClientModel); } } // Copy methods foreach (var subClientMethod in subClient.Methods) { var apiVersionParameter = subClientMethod.Parameters.FirstOrDefault(p => p.SerializedName == "api-version"); if (apiVersionParameter != null) { apiVersionParameter.ClientProperty = null; apiVersionParameter.IsConstant = true; apiVersionParameter.DefaultValue = subClient.ApiVersion; apiVersionParameter.IsRequired = true; } var compositeClientMethod = compositeClient.Methods.FirstOrDefault(m => m.ToString() == subClientMethod.ToString() && m.Group == subClientMethod.Group); if (compositeClientMethod == null) { // Re-link client parameters foreach (var parameter in subClientMethod.Parameters.Where(p => p.IsClientProperty)) { var clientProperty = compositeClient.Properties .FirstOrDefault(p => p.SerializedName == parameter.ClientProperty.SerializedName); if (clientProperty != null) { parameter.ClientProperty = clientProperty; } } compositeClient.Add(subClientMethod); } } // make sure that properties and parameters are using the types from the new model // and not the types from the original. foreach (var property in compositeClient.Properties) { EnsureUsesTypeFromModel(property, compositeClient); } foreach (var method in compositeClient.Methods) { foreach (var parameter in method.Parameters) { EnsureUsesTypeFromModel(parameter, compositeClient); } method.ReturnType.Body = EnsureUsesTypeFromModel(method.ReturnType.Body, compositeClient); method.ReturnType.Headers = EnsureUsesTypeFromModel(method.ReturnType.Headers, compositeClient); } foreach (var modelType in compositeClient.ModelTypes) { foreach (var property in modelType.Properties) { EnsureUsesTypeFromModel(property, compositeClient); } } return(compositeClient); }
/// <summary> /// Adds the parameter groups to operation parameters. /// </summary> /// <param name="codeModelient"></param> public static void AddParameterGroups(CodeModel codeModel) { if (codeModel == null) { throw new ArgumentNullException("codeModel"); } HashSet <CompositeType> generatedParameterGroups = new HashSet <CompositeType>(); foreach (Method method in codeModel.Methods) { //Copy out flattening transformations as they should be the last List <ParameterTransformation> flatteningTransformations = method.InputParameterTransformation.ToList(); method.InputParameterTransformation.Clear(); //This group name is normalized by each languages code generator later, so it need not happen here. IEnumerable <ParameterGroup> parameterGroups = ExtractParameterGroups(method); List <Parameter> parametersToAddToMethod = new List <Parameter>(); List <Parameter> parametersToRemoveFromMethod = new List <Parameter>(); foreach (ParameterGroup parameterGroup in parameterGroups) { CompositeType parameterGroupType = generatedParameterGroups.FirstOrDefault(item => item.Name.RawValue == parameterGroup.Name); if (parameterGroupType == null) { IEnumerable <Method> methodsWhichUseGroup = GetMethodsUsingParameterGroup(codeModel.Methods, parameterGroup); parameterGroupType = New <CompositeType>(parameterGroup.Name, new { Documentation = GenerateParameterGroupModelText(methodsWhichUseGroup) }); generatedParameterGroups.Add(parameterGroupType); //Add to the service client codeModel.Add(parameterGroupType); } foreach (Property property in parameterGroup.ParameterMapping.Keys) { Property matchingProperty = parameterGroupType.Properties.FirstOrDefault( item => item.Name.RawValue == property.Name.RawValue && item.IsReadOnly == property.IsReadOnly && item.DefaultValue.RawValue == property.DefaultValue.RawValue && item.SerializedName.RawValue == property.SerializedName.RawValue); if (matchingProperty == null) { parameterGroupType.Add(property); } } bool isGroupParameterRequired = parameterGroupType.Properties.Any(p => p.IsRequired); //Create the new parameter object based on the parameter group type Parameter newParameter = New <Parameter>(new { Name = parameterGroup.Name, IsRequired = isGroupParameterRequired, Location = ParameterLocation.None, SerializedName = string.Empty, ModelType = parameterGroupType, Documentation = "Additional parameters for the operation" }); parametersToAddToMethod.Add(newParameter); //Link the grouped parameters to their parent, and remove them from the method parameters foreach (Property property in parameterGroup.ParameterMapping.Keys) { Parameter p = parameterGroup.ParameterMapping[property]; var parameterTransformation = new ParameterTransformation { OutputParameter = p }; parameterTransformation.ParameterMappings.Add(new ParameterMapping { InputParameter = newParameter, InputParameterProperty = property.GetClientName() }); method.InputParameterTransformation.Add(parameterTransformation); parametersToRemoveFromMethod.Add(p); } } method.Remove(p => parametersToRemoveFromMethod.Contains(p)); method.AddRange(parametersToAddToMethod); // Copy back flattening transformations if any flatteningTransformations.ForEach(t => method.InputParameterTransformation.Add(t)); } }
public CodeModel Build(ServiceDefinition serviceDefinition) { ServiceDefinition = serviceDefinition; // Update settings UpdateSettings(); InitializeClientModel(); BuildCompositeTypes(); // Build client parameters foreach (var swaggerParameter in ServiceDefinition.Components.Parameters.Values) { var parameter = ((ParameterBuilder)swaggerParameter.GetBuilder(this)).Build(); var clientProperty = New <Property>(); clientProperty.LoadFrom(parameter); clientProperty.RealPath = new string[] { parameter.SerializedName }; CodeModel.Add(clientProperty); } var methods = new List <Method>(); // Build methods foreach (var path in ServiceDefinition.Paths.Concat(ServiceDefinition.CustomPaths)) { foreach (var verb in path.Value.Keys) { var operation = path.Value[verb]; if (string.IsNullOrWhiteSpace(operation.OperationId)) { throw ErrorManager.CreateError( string.Format(CultureInfo.InvariantCulture, Resources.OperationIdMissing, verb, path.Key)); } var methodName = GetMethodNameFromOperationId(operation.OperationId); var methodGroup = GetMethodGroup(operation); if (verb.ToHttpMethod() != HttpMethod.Options) { string url = path.Key; if (url.Contains("?")) { url = url.Substring(0, url.IndexOf('?')); } var method = BuildMethod(verb.ToHttpMethod(), url, methodName, operation); method.Group = methodGroup; methods.Add(method); if (method.DefaultResponse.Body is CompositeType) { CodeModel.AddError((CompositeType)method.DefaultResponse.Body); } } else { Logger.Instance.Log(Category.Warning, Resources.OptionsNotSupported); } } } // Set base type foreach (var typeName in GeneratedTypes.Keys) { var objectType = GeneratedTypes[typeName]; if (ExtendedTypes.ContainsKey(typeName)) { objectType.BaseModelType = GeneratedTypes[ExtendedTypes[typeName]]; } CodeModel.Add(objectType); } CodeModel.AddRange(methods); // Build ContentType enum if (ContentTypeChoices.Count > 0) { var enumType = New <EnumType>(); enumType.ModelAsString = true; enumType.SetName("ContentTypes"); enumType.Values.AddRange(ContentTypeChoices.Select(v => new EnumValue { Name = v, SerializedName = v })); CodeModel.Add(enumType); } ProcessParameterizedHost(); return(CodeModel); }
public override CodeModel Build(out IEnumerable <ValidationMessage> messages) { Logger.LogInfo(Resources.ParsingSwagger); if (string.IsNullOrWhiteSpace(Settings.Input)) { throw ErrorManager.CreateError(Resources.InputRequired); } ServiceDefinition = SwaggerParser.Load(Settings.Input, Settings.FileSystem); // Look for semantic errors and warnings in the document. var validator = new RecursiveObjectValidator(PropertyNameResolver.JsonName); messages = validator.GetValidationExceptions(ServiceDefinition).ToList(); Logger.LogInfo(Resources.GeneratingClient); // Update settings UpdateSettings(); InitializeClientModel(); BuildCompositeTypes(); // Build client parameters foreach (var swaggerParameter in ServiceDefinition.Parameters.Values) { var parameter = ((ParameterBuilder)swaggerParameter.GetBuilder(this)).Build(); var clientProperty = New <Property>(); clientProperty.LoadFrom(parameter); CodeModel.Add(clientProperty); } var methods = new List <Method>(); // Build methods foreach (var path in ServiceDefinition.Paths.Concat(ServiceDefinition.CustomPaths)) { foreach (var verb in path.Value.Keys) { var operation = path.Value[verb]; if (string.IsNullOrWhiteSpace(operation.OperationId)) { throw ErrorManager.CreateError( string.Format(CultureInfo.InvariantCulture, Resources.OperationIdMissing, verb, path.Key)); } var methodName = GetMethodName(operation); var methodGroup = GetMethodGroup(operation); if (verb.ToHttpMethod() != HttpMethod.Options) { string url = path.Key; if (url.Contains("?")) { url = url.Substring(0, url.IndexOf('?')); } var method = BuildMethod(verb.ToHttpMethod(), url, methodName, operation); method.Group = methodGroup; methods.Add(method); if (method.DefaultResponse.Body is CompositeType) { CodeModel.AddError((CompositeType)method.DefaultResponse.Body); } } else { Logger.LogWarning(Resources.OptionsNotSupported); } } } // Set base type foreach (var typeName in GeneratedTypes.Keys) { var objectType = GeneratedTypes[typeName]; if (ExtendedTypes.ContainsKey(typeName)) { objectType.BaseModelType = GeneratedTypes[ExtendedTypes[typeName]]; } CodeModel.Add(objectType); } CodeModel.AddRange(methods); return(CodeModel); }
public CodeModel Build(ServiceDefinition serviceDefinition) { ServiceDefinition = serviceDefinition; // Update settings UpdateSettings(); InitializeClientModel(); BuildCompositeTypes(); // Build client parameters foreach (var swaggerParameter in ServiceDefinition.Components.Parameters.Values) { var parameter = ((ParameterBuilder)swaggerParameter.GetBuilder(this)).Build(); var clientProperty = New <Property>(); clientProperty.LoadFrom(parameter); clientProperty.RealPath = new string[] { parameter.SerializedName }; CodeModel.Add(clientProperty); } var baseErrorResponses = new List <Fixable <string> >(); var methods = new List <Method>(); // Build methods foreach (var path in ServiceDefinition.Paths.Concat(ServiceDefinition.CustomPaths)) { foreach (var verb in path.Value.Keys) { var operation = path.Value[verb]; if (string.IsNullOrWhiteSpace(operation.OperationId)) { throw ErrorManager.CreateError( string.Format(CultureInfo.InvariantCulture, Resources.OperationIdMissing, verb, path.Key)); } var methodName = GetMethodNameFromOperationId(operation.OperationId); var methodGroup = GetMethodGroup(operation); if (verb.ToHttpMethod() != HttpMethod.Options) { string url = path.Key; if (url.Contains("?")) { url = url.Substring(0, url.IndexOf('?')); } var method = BuildMethod(verb.ToHttpMethod(), url, methodName, operation); method.Group = methodGroup; methods.Add(method); // Add error models marked by x-ms-error-response var xmsErrorResponses = method.Responses.Values.Where(resp => resp.Extensions.ContainsKey("x-ms-error-response") && (bool)resp.Extensions["x-ms-error-response"] && resp.Body is CompositeType) .Select(resp => (CompositeType)resp.Body); xmsErrorResponses.ForEach(errModel => CodeModel.AddError(errModel)); // If marked error models have a polymorphic discriminator, include all models that allOf on them (at any level of inheritence) baseErrorResponses = baseErrorResponses.Union(xmsErrorResponses.Where(errModel => !string.IsNullOrEmpty(errModel.PolymorphicDiscriminator) && ExtendedTypes.ContainsKey(errModel.Name)) .Select(errModel => errModel.Name)).ToList(); // Add the default error model if exists if (method.DefaultResponse.Body is CompositeType) { baseErrorResponses.Add(((CompositeType)method.DefaultResponse.Body).Name); CodeModel.AddError((CompositeType)method.DefaultResponse.Body); } } else { Logger.Instance.Log(Category.Warning, Resources.OptionsNotSupported); } } } ProcessForwardToMethods(methods); // Set base type foreach (var typeName in GeneratedTypes.Keys) { var objectType = GeneratedTypes[typeName]; if (ExtendedTypes.ContainsKey(typeName)) { objectType.BaseModelType = GeneratedTypes[ExtendedTypes[typeName]]; } CodeModel.Add(objectType); } CodeModel.AddRange(methods); foreach (var k in GeneratedTypes.Keys) { var baseModelType = GeneratedTypes[k].BaseModelType; while (baseModelType != null && baseModelType is CompositeType && !baseErrorResponses.Contains(k)) { if (baseErrorResponses.Contains(baseModelType.Name)) { CodeModel.AddError(GeneratedTypes[k]); break; } baseModelType = baseModelType.BaseModelType; } } // What operation returns it decides whether an object is to be modeled as a // regular model class or an exception class // Set base type var errorResponses = ServiceDefinition.Paths.Values.SelectMany(pathObj => pathObj.Values.SelectMany(opObj => opObj.Responses.Values.Where(res => res.Extensions?.ContainsKey("x-ms-error-response") == true && (bool)res.Extensions["x-ms-error-response"]))); var errorModels = errorResponses.Select(resp => resp.Schema?.Reference).Where(modelRef => !string.IsNullOrEmpty(modelRef)).Select(modelRef => GeneratedTypes[modelRef]); errorModels.ForEach(errorModel => CodeModel.AddError(errorModel)); // Build ContentType enum if (ContentTypeChoices.Count > 0) { var enumType = New <EnumType>(); enumType.ModelAsString = true; enumType.SetName("ContentTypes"); enumType.Values.AddRange(ContentTypeChoices.Select(v => new EnumValue { Name = v, SerializedName = v })); CodeModel.Add(enumType); } ProcessParameterizedHost(); return(CodeModel); }
public CodeModel Build(ServiceDefinition serviceDefinition) { ServiceDefinition = serviceDefinition; if (Settings.Instance.CodeGenerator.EqualsIgnoreCase("None")) { // Look for semantic errors and warnings in the document. var validator = new RecursiveObjectValidator(PropertyNameResolver.JsonName); foreach (var validationEx in validator.GetValidationExceptions(ServiceDefinition.FilePath, ServiceDefinition, new ServiceDefinitionMetadata { // LEGACY MODE! set defaults for the metadata, marked to be deprecated ServiceDefinitionDocumentType = ServiceDefinitionDocumentType.ARM, MergeState = ServiceDefinitionDocumentState.Composed })) { Logger.Instance.Log(validationEx); } return(New <CodeModel>()); } Logger.Instance.Log(Category.Info, Resources.GeneratingClient); // Update settings UpdateSettings(); InitializeClientModel(); BuildCompositeTypes(); // Build client parameters foreach (var swaggerParameter in ServiceDefinition.Parameters.Values) { var parameter = ((ParameterBuilder)swaggerParameter.GetBuilder(this)).Build(); var clientProperty = New <Property>(); clientProperty.LoadFrom(parameter); clientProperty.RealPath = new string[] { parameter.SerializedName.Value }; CodeModel.Add(clientProperty); } var methods = new List <Method>(); // Build methods foreach (var path in ServiceDefinition.Paths.Concat(ServiceDefinition.CustomPaths)) { foreach (var verb in path.Value.Keys) { var operation = path.Value[verb]; if (string.IsNullOrWhiteSpace(operation.OperationId)) { throw ErrorManager.CreateError( string.Format(CultureInfo.InvariantCulture, Resources.OperationIdMissing, verb, path.Key)); } var methodName = GetMethodName(operation); var methodGroup = GetMethodGroup(operation); if (verb.ToHttpMethod() != HttpMethod.Options) { string url = path.Key; if (url.Contains("?")) { url = url.Substring(0, url.IndexOf('?')); } var method = BuildMethod(verb.ToHttpMethod(), url, methodName, operation); method.Group = methodGroup; methods.Add(method); if (method.DefaultResponse.Body is CompositeType) { CodeModel.AddError((CompositeType)method.DefaultResponse.Body); } } else { Logger.Instance.Log(Category.Warning, Resources.OptionsNotSupported); } } } // Set base type foreach (var typeName in GeneratedTypes.Keys) { var objectType = GeneratedTypes[typeName]; if (ExtendedTypes.ContainsKey(typeName)) { objectType.BaseModelType = GeneratedTypes[ExtendedTypes[typeName]]; } CodeModel.Add(objectType); } CodeModel.AddRange(methods); return(CodeModel); }