Beispiel #1
0
        /// <summary>
        ///     Generate NodeJS client code 
        /// </summary>
        /// <param name="serviceClient"></param>
        /// <returns></returns>
        public override async Task Generate(CodeModel cm)
        {
            var disableTypeScriptGeneration = Singleton<GeneratorSettingsJs>.Instance.DisableTypeScriptGeneration;

            var codeModel = cm as CodeModelJs;
            if (codeModel == null)
            {
                throw new InvalidCastException("CodeModel is not a NodeJS code model.");
            }

            // Service client
            var serviceClientTemplate = new ServiceClientTemplate {Model = codeModel};
            await Write(serviceClientTemplate, codeModel.Name.ToCamelCase() + ".js");

            if (!disableTypeScriptGeneration)
            {
                var serviceClientTemplateTS = new ServiceClientTemplateTS {Model = codeModel};
                await Write(serviceClientTemplateTS, codeModel.Name.ToCamelCase() + ".d.ts");
            }

            //Models
            if (codeModel.ModelTypes.Any())
            {
                var modelIndexTemplate = new ModelIndexTemplate {Model = codeModel};
                await Write(modelIndexTemplate, Path.Combine("models", "index.js"));

                if (!disableTypeScriptGeneration)
                {
                    var modelIndexTemplateTS = new ModelIndexTemplateTS {Model = codeModel};
                    await Write(modelIndexTemplateTS, Path.Combine("models", "index.d.ts"));
                }

                foreach (var modelType in codeModel.ModelTemplateModels)
                {
                    var modelTemplate = new ModelTemplate {Model = modelType};
                    await Write(modelTemplate, Path.Combine("models", modelType.NameAsFileName.ToCamelCase() + ".js"));
                }
            }

            //MethodGroups
            if (codeModel.MethodGroupModels.Any())
            {
                var methodGroupIndexTemplate = new MethodGroupIndexTemplate {Model = codeModel};
                await Write(methodGroupIndexTemplate, Path.Combine("operations", "index.js"));

                if (!disableTypeScriptGeneration)
                {
                    var methodGroupIndexTemplateTS = new MethodGroupIndexTemplateTS {Model = codeModel};
                    await Write(methodGroupIndexTemplateTS, Path.Combine("operations", "index.d.ts"));
                }

                foreach (var methodGroupModel in codeModel.MethodGroupModels)
                {
                    var methodGroupTemplate = new MethodGroupTemplate {Model = methodGroupModel};
                    await
                        Write(methodGroupTemplate,
                            Path.Combine("operations", methodGroupModel.TypeName.ToCamelCase() + ".js"));
                }
            }
        }
 public override async Task Generate(CodeModel codeModel)
 {
     var viewModel = new SampleViewModel();
     var model = new SampleModel();
     model.Model = viewModel;
     await Write(model, Path.Combine(Settings.Instance.ModelsName, "Pet.cs"));
 }
Beispiel #3
0
        /// <summary>
        /// Generates code and outputs it in the file system.
        /// </summary>
        /// <param name="codeModel"></param>
        /// <returns></returns>
        public virtual /* async */ Task Generate(CodeModel codeModel)
        {
            ResetFileList();

            // since we're not actually async, return a completed task.
            return "".AsResultTask();
        }
Beispiel #4
0
        /// <summary>
        /// Normalizes client model using Azure-specific extensions.
        /// </summary>
        /// <param name="codeModelient">Service client</param>
        /// <param name="settings">AutoRest settings</param>
        /// <param name="codeNamer">AutoRest settings</param>
        /// <returns></returns>
        public static void NormalizeAzureClientModel(CodeModel codeModel)
        {
            var settings = Settings.Instance;
            using (NewContext)
            {
                settings = new Settings().LoadFrom(settings);
                settings.AddCredentials = true;

                if (codeModel == null)
                {
                    throw new ArgumentNullException("codeModel");
                }
               

                // This extension from general extensions must be run prior to Azure specific extensions.
                ProcessParameterizedHost(codeModel);

                ProcessClientRequestIdExtension(codeModel);
                UpdateHeadMethods(codeModel);
                ParseODataExtension(codeModel);
                ProcessGlobalParameters(codeModel);
                FlattenModels(codeModel);
                FlattenMethodParameters(codeModel);
                ParameterGroupExtensionHelper.AddParameterGroups(codeModel);
                AddLongRunningOperations(codeModel);
                AddAzureProperties(codeModel);
                SetDefaultResponses(codeModel);
                AddPageableMethod(codeModel);
            }
        }
Beispiel #5
0
 /// <summary>
 /// Normalizes client model using generic extensions.
 /// </summary>
 /// <param name="codeModelient">Service client</param>
 /// <param name="settings">AutoRest settings</param>
 /// <returns></returns>
 public static void NormalizeClientModel(CodeModel codeModel)
 {
     ProcessGlobalParameters(codeModel);
     FlattenModels(codeModel);
     FlattenMethodParameters(codeModel);
     ParameterGroupExtensionHelper.AddParameterGroups(codeModel);
     ProcessParameterizedHost(codeModel);
 }
Beispiel #6
0
        /// <summary>
        /// Generates C# code for service client.
        /// </summary>
        /// <param name="cm"></param>
        /// <returns></returns>
        public override async Task Generate(CodeModel cm)
        {
            // get c# specific codeModel
            var codeModel = cm as CodeModelCs;
            if (codeModel == null)
            {
                throw new InvalidCastException("CodeModel is not a c# CodeModel");
            }

            // Service client
            var serviceClientTemplate = new ServiceClientTemplate{ Model = codeModel };
            await Write(serviceClientTemplate, $"{codeModel.Name}{ImplementationFileExtension}" );

            // Service client interface
            var serviceClientInterfaceTemplate = new ServiceClientInterfaceTemplate { Model = codeModel };
            await Write(serviceClientInterfaceTemplate, $"I{codeModel.Name}{ImplementationFileExtension}");

            // operations
            foreach (MethodGroupCs methodGroup in codeModel.Operations)
            {
                if(!methodGroup.Name.IsNullOrEmpty()) { 
                    // Operation
                    var operationsTemplate = new MethodGroupTemplate { Model = methodGroup };
                    await Write(operationsTemplate, $"{operationsTemplate.Model.TypeName}{ImplementationFileExtension}");

                    // Operation interface
                    var operationsInterfaceTemplate = new MethodGroupInterfaceTemplate { Model = methodGroup };
                    await Write(operationsInterfaceTemplate, $"I{operationsInterfaceTemplate.Model.TypeName}{ImplementationFileExtension}");
                }

                var operationExtensionsTemplate = new ExtensionsTemplate { Model = methodGroup };
                await Write(operationExtensionsTemplate, $"{methodGroup.ExtensionTypeName}Extensions{ImplementationFileExtension}");
            }

            // Models
            foreach (CompositeTypeCs model in codeModel.ModelTypes.Union(codeModel.HeaderTypes))
            {
                var modelTemplate = new ModelTemplate{ Model = model };
                await Write(modelTemplate, Path.Combine(Settings.Instance.ModelsName, $"{model.Name}{ImplementationFileExtension}"));
            }

            // Enums
            foreach (EnumTypeCs enumType in codeModel.EnumTypes)
            {
                var enumTemplate = new EnumTemplate { Model = enumType };
                await Write(enumTemplate, Path.Combine(Settings.Instance.ModelsName, $"{enumTemplate.Model.Name}{ImplementationFileExtension}"));
            }

            // Exceptions
            foreach (CompositeTypeCs exceptionType in codeModel.ErrorTypes)
            {
                var exceptionTemplate = new ExceptionTemplate { Model = exceptionType, };
                await Write(exceptionTemplate, Path.Combine(Settings.Instance.ModelsName, $"{exceptionTemplate.Model.ExceptionTypeDefinitionName}{ImplementationFileExtension}"));
            }
        }
        public override async Task Generate(CodeModel serviceClient)
        {
            IDictionary<string, ResourceSchema> resourceSchemas = ResourceSchemaParser.Parse(serviceClient);

            foreach (string resourceProvider in resourceSchemas.Keys)
            {
                StringWriter stringWriter = new StringWriter();
                ResourceSchemaWriter.Write(stringWriter, resourceSchemas[resourceProvider]);

                // string schemaPath = Path.Combine(Settings.Instance.OutputDirectory,);
                await Write(stringWriter.ToString(), resourceProvider + ".json");
            }
        }
Beispiel #8
0
        /// <summary>
        /// Changes head method return type.
        /// </summary>
        /// <param name="codeModelient">Service client</param>
        public static void UpdateHeadMethods(CodeModel codeModel)
        {
            if (codeModel == null)
            {
                throw new ArgumentNullException("codeModel");
            }

            foreach (var method in codeModel.Methods.Where(m => m.HttpMethod == HttpMethod.Head)
                                                              .Where(m => m.ReturnType.Body == null))
            {
                HttpStatusCode successStatusCode = method.Responses.Keys.FirstOrDefault(AzureExtensions.HttpHeadStatusCodeSuccessFunc);

                if (method.Responses.Count == 2 &&
                    successStatusCode != default(HttpStatusCode) &&
                    method.Responses.ContainsKey(HttpStatusCode.NotFound))
                {
                    method.ReturnType = new Response(New<PrimaryType>(KnownPrimaryType.Boolean), method.ReturnType.Headers);
                }
                else
                {
                    Logger.LogInfo(string.Format(CultureInfo.InvariantCulture, Resources.HeadMethodPossibleIncorrectSpecification, method.Name));
                }
            }
        }
Beispiel #9
0
        /// <summary>
        /// Generates Ruby code for Azure service client.
        /// </summary>
        /// <param name="cm">The code model.</param>
        /// <returns>Async tasks which generates SDK files.</returns>
        public override async Task Generate(CodeModel cm)
        {
            var codeModel = cm as CodeModelRba;
            if (codeModel == null)
            {
                throw new InvalidCastException("CodeModel is not a Azure Ruby code model.");
            }

            // Service client
            var serviceClientTemplate = new ServiceClientTemplate { Model = codeModel };
            await Write(serviceClientTemplate, Path.Combine(GeneratorSettingsRba.Instance.sdkPath, CodeNamer.UnderscoreCase(codeModel.Name) + ImplementationFileExtension));

            // Operations
            foreach (MethodGroupRba group in codeModel.Operations.Where(each => !each.IsCodeModelMethodGroup))
            {
                // Operation
                var operationsTemplate = new AzureMethodGroupTemplate { Model = group };
                await Write(operationsTemplate, Path.Combine(GeneratorSettingsRba.Instance.sdkPath, CodeNamer.UnderscoreCase(operationsTemplate.Model.TypeName) + ImplementationFileExtension));
            }

            // Models
            foreach (CompositeTypeRba model in codeModel.ModelTypes)
            {
                if ((model.Extensions.ContainsKey(AzureExtensions.ExternalExtension) &&
                    (bool)model.Extensions[AzureExtensions.ExternalExtension])
                    || model.Name == "Resource" || model.Name == "SubResource")
                {
                    continue;
                }

                if( codeModel.pageModels.Any( each => each.Name.EqualsIgnoreCase(model.Name ) ) )
                {
                    // Skip, handled in the .pageModels section below.
                    continue;
                }

                var modelTemplate = new ModelTemplate { Model = model };
                await Write(modelTemplate, Path.Combine(GeneratorSettingsRb.Instance.modelsPath, CodeNamer.UnderscoreCase(model.Name) + ImplementationFileExtension));
            }
            // Paged Models
            foreach (var pageModel in codeModel.pageModels)
            {
                var pageTemplate = new PageModelTemplate { Model = pageModel };
                await Write(pageTemplate, Path.Combine(GeneratorSettingsRb.Instance.modelsPath, CodeNamer.UnderscoreCase(pageModel.Name) + ImplementationFileExtension));
            }

            // Enums
            foreach (EnumTypeRb enumType in codeModel.EnumTypes)
            {
                var enumTemplate = new EnumTemplate { Model = enumType };
                await Write(enumTemplate, Path.Combine(GeneratorSettingsRb.Instance.modelsPath, CodeNamer.UnderscoreCase(enumTemplate.Model.Name) + ImplementationFileExtension));
            }

            // Requirements
            var requirementsTemplate = new RequirementsTemplate{Model = new RequirementsRba(codeModel, this)};
            await Write(requirementsTemplate, CodeNamer.UnderscoreCase(GeneratorSettingsRb.Instance.packageName ?? GeneratorSettingsRb.Instance.sdkName) + ImplementationFileExtension);

            // Version File
            if (GeneratorSettingsRb.Instance.packageVersion != null)
            {
                var versionTemplate = new VersionTemplate { Model = GeneratorSettingsRb.Instance.packageVersion };
                await Write(versionTemplate, Path.Combine(GeneratorSettingsRb.Instance.sdkPath, "version" + ImplementationFileExtension));
            }

            // Module Definition File
            if (Settings.Instance.Namespace != null)
            {
                var modTemplate  = new ModuleDefinitionTemplate { Model = GeneratorSettingsRb.Instance.ModuleDeclarations };
                await Write(modTemplate, Path.Combine(GeneratorSettingsRb.Instance.sdkPath, "module_definition" + ImplementationFileExtension));
            }
        }
Beispiel #10
0
        /// <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.ReturnType.Body != null)
                {
                    method.DefaultResponse = new Response(cloudError, method.ReturnType.Headers);
                }                
            }
        }
Beispiel #11
0
        /// <summary>
        /// Converts Azure Parameters to regular parameters.
        /// </summary>
        /// <param name="codeModelient">Service client</param>
        public static void ParseODataExtension(CodeModel codeModel)
        {
            if (codeModel == null)
            {
                throw new ArgumentNullException("codeModel");
            }

            foreach (var method in codeModel.Methods.Where(m => m.Extensions.ContainsKey(ODataExtension)))
            {
                string odataModelPath = (string) method.Extensions[ODataExtension];
                if (odataModelPath == null)
                {
                    throw new InvalidOperationException(
                        string.Format(CultureInfo.InvariantCulture, 
                        Resources.ODataEmpty, ODataExtension));
                }

                odataModelPath = odataModelPath.StripDefinitionPath();

                CompositeType odataType = codeModel.ModelTypes
                    .FirstOrDefault(t => t.Name.EqualsIgnoreCase(odataModelPath));

                if (odataType == null)
                {
                    throw new InvalidOperationException(
                        string.Format(CultureInfo.InvariantCulture, 
                        Resources.ODataInvalidReferance, ODataExtension));
                }
                var filterParameter = method.Parameters
                    .FirstOrDefault(p => p.Location == ParameterLocation.Query &&
                                         p.Name.FixedValue == "$filter");
                if (filterParameter == null)
                {
                    throw new InvalidOperationException(
                        string.Format(CultureInfo.InvariantCulture, 
                        Resources.ODataFilterMissing, ODataExtension));
                }

                filterParameter.ModelType = odataType;
            }
        }
Beispiel #12
0
        public static void ProcessParameterizedHost(CodeModel codeModel)
        {
            using (NewContext)
            {
                if (codeModel == null)
                {
                    throw new ArgumentNullException("codeModel");
                }

                if (codeModel.Extensions.ContainsKey(ParameterizedHostExtension) && !hostChecked)
                {
                    SwaggerModeler modeler = new SwaggerModeler();
                    modeler.Build();
                    var hostExtension = codeModel.Extensions[ParameterizedHostExtension] as JObject;

                    if (hostExtension != null)
                    {
                        var hostTemplate = (string) hostExtension["hostTemplate"];
                        var parametersJson = hostExtension["parameters"].ToString();
                        var useSchemePrefix = true;
                        if (hostExtension[UseSchemePrefix] != null)
                        {
                            useSchemePrefix = bool.Parse(hostExtension[UseSchemePrefix].ToString());
                        }

                        var position = "first";

                        if (hostExtension[PositionInOperation] != null)
                        {
                            var pat = "^(fir|la)st$";
                            Regex r = new Regex(pat, RegexOptions.IgnoreCase);
                            var text = hostExtension[PositionInOperation].ToString();
                            Match m = r.Match(text);
                            if (!m.Success)
                            {
                                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture,
                                    Resources.InvalidExtensionProperty, text, PositionInOperation,
                                    ParameterizedHostExtension, "first, last"));
                            }
                            position = text;
                        }

                        if (!string.IsNullOrEmpty(parametersJson))
                        {
                            var jsonSettings = new JsonSerializerSettings
                            {
                                TypeNameHandling = TypeNameHandling.None,
                                MetadataPropertyHandling = MetadataPropertyHandling.Ignore
                            };

                            var swaggerParams = JsonConvert.DeserializeObject<List<SwaggerParameter>>(parametersJson,
                                jsonSettings);
                            List<Parameter> hostParamList = new List<Parameter>();
                            foreach (var swaggerParameter in swaggerParams)
                            {
                                // Build parameter
                                var parameterBuilder = new ParameterBuilder(swaggerParameter, modeler);
                                var parameter = parameterBuilder.Build();

                                // check to see if the parameter exists in properties, and needs to have its name normalized
                                if (codeModel.Properties.Any(p => p.SerializedName.EqualsIgnoreCase(parameter.SerializedName)))
                                {
                                    parameter.ClientProperty =
                                        codeModel.Properties.Single(
                                            p => p.SerializedName.Equals(parameter.SerializedName));
                                }
                                parameter.Extensions["hostParameter"] = true;
                                hostParamList.Add(parameter);
                            }

                            foreach (var method in codeModel.Methods)
                            {
                                if (position.EqualsIgnoreCase("first"))
                                {
                                    method.InsertRange(((IEnumerable<Parameter>)hostParamList).Reverse());
                                }
                                else
                                {
                                    method.AddRange(hostParamList);
                                }

                            }
                            if (useSchemePrefix)
                            {
                                codeModel.BaseUrl = string.Format(CultureInfo.InvariantCulture, "{0}://{1}{2}",
                                    modeler.ServiceDefinition.Schemes[0].ToString().ToLowerInvariant(),
                                    hostTemplate, modeler.ServiceDefinition.BasePath);
                            }
                            else
                            {
                                codeModel.BaseUrl = string.Format(CultureInfo.InvariantCulture, "{0}{1}",
                                    hostTemplate, modeler.ServiceDefinition.BasePath);
                            }

                        }
                    }
                }
            }
            hostChecked = true;
        }
Beispiel #13
0
        /// <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);

                    // change the name, remove the extension.
                    m.Name = "Begin" + m.Name.ToPascalCase();
                    m.Extensions.Remove(LongRunningExtension);

                    codeModel.Add(m);

                }
            }
        }
Beispiel #14
0
        /// <summary>
        /// Flattens the request payload if the number of properties of the 
        /// payload is less than or equal to the PayloadFlatteningThreshold.
        /// </summary>
        /// <param name="codeModelient">Service client</param>                            
        /// <param name="settings">AutoRest settings</param>                            
        public static void FlattenMethodParameters(CodeModel codeModel)
        {
            if (codeModel == null)
            {
                throw new ArgumentNullException("codeModel");    
            }
          

            foreach (var method in codeModel.Methods)
            {
                var bodyParameter = method.Parameters.FirstOrDefault(
                    p => p.Location == ParameterLocation.Body);

                if (bodyParameter != null)
                {
                    var bodyParameterType = bodyParameter.ModelType as CompositeType;
                    if (bodyParameterType != null && 
                        (bodyParameterType.ComposedProperties.Count(p => !p.IsConstant && !p.IsReadOnly) <= Settings.Instance.PayloadFlatteningThreshold ||
                         bodyParameter.ShouldBeFlattened()))
                    {
                        var parameterTransformation = new ParameterTransformation
                        {
                            OutputParameter = bodyParameter
                        };
                        method.InputParameterTransformation.Add(parameterTransformation);
                        method.Remove(bodyParameter);

                        foreach (var property in bodyParameterType.ComposedProperties.Where(p => !p.IsConstant && p.Name != null && !p.IsReadOnly))
                        {
                            var newMethodParameter = New<Parameter>();
                            newMethodParameter.LoadFrom(property);

                            var documentationString = !string.IsNullOrEmpty(property.Summary) ? property.Summary + " " : string.Empty;
                            documentationString += property.Documentation;
                            newMethodParameter.Documentation = documentationString;

                            bodyParameter.Extensions.ForEach(kv => { newMethodParameter.Extensions[kv.Key] = kv.Value; });
                            method.Add(newMethodParameter);

                            parameterTransformation.ParameterMappings.Add(new ParameterMapping
                            {
                                InputParameter = newMethodParameter,
                                OutputParameterProperty = property.GetClientName()
                            });
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Parse a ResourceSchemaModel from the provided ServiceClient.
        /// </summary>
        /// <param name="serviceClient"></param>
        /// <returns></returns>
        public static IDictionary<string, ResourceSchema> Parse(CodeModel 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 ||
                    string.IsNullOrWhiteSpace(method.Url) ||
                    !method.Url.Value.StartsWith(resourceMethodPrefix, StringComparison.OrdinalIgnoreCase) ||
                    !method.Url.Value.EndsWith("}", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                string afterPrefix = method.Url.Value.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.ModelType 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.ComposedProperties)
                            {
                                if (!resourceDefinition.Properties.Keys.Contains(property.Name.RawValue))
                                {
                                    JsonSchema propertyDefinition = ParseType(property, property.ModelType, resourceSchema.Definitions, serviceClient.ModelTypes);
                                    if (propertyDefinition != null)
                                    {
                                        resourceDefinition.AddProperty(property.Name.RawValue, propertyDefinition, property.IsRequired || property.Name.RawValue == "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;
        }
Beispiel #16
0
        /// <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"
            }));
        }
Beispiel #17
0
        /// <summary>
        /// Generate Python client code for given ServiceClient.
        /// </summary>
        /// <param name="serviceClient"></param>
        /// <returns></returns>
        public override async Task Generate(CodeModel cm)
        {
            var codeModel = cm as CodeModelPy;
            if (codeModel == null)
            {
                throw new Exception("Code model is not a Python Code Model");
            }

            // Service client
            var setupTemplate = new SetupTemplate { Model = codeModel };
            await Write(setupTemplate, "setup.py");

            var serviceClientInitTemplate = new ServiceClientInitTemplate { Model = codeModel };
            await Write(serviceClientInitTemplate, Path.Combine(codeModel.PackageName, "__init__.py"));

            var serviceClientTemplate = new ServiceClientTemplate { Model = codeModel };
            await Write(serviceClientTemplate, Path.Combine(codeModel.PackageName, codeModel.Name.ToPythonCase() + ".py"));

            var versionTemplate = new VersionTemplate { Model = codeModel };
            await Write(versionTemplate, Path.Combine(codeModel.PackageName, "version.py"));

            var exceptionTemplate = new ExceptionTemplate { Model = codeModel };
            await Write(exceptionTemplate, Path.Combine(codeModel.PackageName, "exceptions.py"));

            var credentialTemplate = new CredentialTemplate { Model = codeModel };
            await Write(credentialTemplate, Path.Combine(codeModel.PackageName, "credentials.py"));

            //Models
            if (codeModel.ModelTypes.Any())
            {
                var modelInitTemplate = new ModelInitTemplate { Model = codeModel };
                await Write(modelInitTemplate, Path.Combine(codeModel.PackageName, "models", "__init__.py"));

                foreach (var modelType in codeModel.ModelTemplateModels)
                {
                    var modelTemplate = new ModelTemplate
                    {
                        Model = modelType
                    };
                    await Write(modelTemplate, Path.Combine(codeModel.PackageName, "models", ((string)modelType.Name).ToPythonCase() + ".py"));
                }
            }

            //MethodGroups
            if (codeModel.MethodGroupModels.Any())
            {
                var methodGroupIndexTemplate = new MethodGroupInitTemplate
                {
                    Model = codeModel
                };
                await Write(methodGroupIndexTemplate, Path.Combine(codeModel.PackageName, "operations", "__init__.py"));

                foreach (var methodGroupModel in codeModel.MethodGroupModels)
                {
                    var methodGroupTemplate = new MethodGroupTemplate
                    {
                        Model = methodGroupModel
                    };
                    await Write(methodGroupTemplate, Path.Combine(codeModel.PackageName, "operations", ((string) methodGroupModel.TypeName).ToPythonCase() + ".py"));
                }
            }

            // Enums
            if (codeModel.EnumTypes.Any())
            {
                var enumTemplate = new EnumTemplate { Model = codeModel.EnumTypes };
                await Write(enumTemplate, Path.Combine(codeModel.PackageName, "models", codeModel.Name.ToPythonCase() + "_enums.py"));
            }
        }
        /// <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));
            }
        }
Beispiel #19
0
        /// <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);
                        
                    }
                }
            }
        }
Beispiel #20
0
        public static void ProcessClientRequestIdExtension(CodeModel codeModel)
        {
            if (codeModel == null)
            {
                throw new ArgumentNullException("codeModel");
            }

            foreach (Method method in codeModel.Methods)
            {
                const string defaultClientRequestIdName = "x-ms-client-request-id";
                string customClientRequestIdName =
                    method.Parameters.Where(parameter => parameter.Extensions.ContainsKey(ClientRequestIdExtension))
                    .Select(parameter =>
                        {
                            bool? extensionObject = parameter.Extensions[ClientRequestIdExtension] as bool?;
                            if (extensionObject != null && extensionObject.Value)
                            {
                                return parameter.SerializedName.Value;
                            }
                            return null;
                        })
                    .SingleOrDefault();

                string clientRequestIdName = customClientRequestIdName ?? defaultClientRequestIdName;
                method.Extensions.Add(ClientRequestIdExtension, clientRequestIdName);
            }
        }
Beispiel #21
0
        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"
            });
        }
Beispiel #22
0
        public static CodeModel RunExtensions(Trigger trigger, CodeModel codeModel)
        {
            /*
             foreach (var extension in extensions.Where(each => each.trigger == trugger).SortBy(each => each.Priority))
                 codeModel = extension.Transform(codeModel);
            */

            return codeModel;
        }
        /// <summary>
        /// Flattens the Resource Properties.
        /// </summary>
        /// <param name="codeModelient"></param>
        public static void FlattenModels(CodeModel codeModel)
        {
            if (codeModel == null)
            {
                throw new ArgumentNullException("codeModel");
            }

            HashSet<string> typesToDelete = new HashSet<string>();
            foreach (var compositeType in codeModel.ModelTypes)
            {
                if (compositeType.Properties.Any(p => p.ShouldBeFlattened())
                    && !typesToDelete.Contains(compositeType.Name))
                {
                    List<Property> oldProperties = compositeType.Properties.ToList();
                    compositeType.ClearProperties();

                    foreach (Property innerProperty in oldProperties)
                    {
                        if (innerProperty.ShouldBeFlattened() && compositeType != innerProperty.ModelType)
                        {
                            FlattenProperty(innerProperty, typesToDelete)
                                .ForEach(p => compositeType.Add(p));
                        }
                        else
                        {
                            compositeType.Add(innerProperty);
                        }
                    }

                    RemoveFlatteningConflicts(compositeType);
                }
            }

            RemoveUnreferencedTypes(codeModel, typesToDelete);
        }
Beispiel #24
0
        /// <summary>
        /// Generate Python client code for given ServiceClient.
        /// </summary>
        /// <param name="cm"></param>
        /// <returns></returns>
        public override async Task Generate(CodeModel cm)
        {
            
            var codeModel = cm as CodeModelPya;
            if (codeModel == null)
            {
                throw new Exception("CodeModel is not a Python Azure Code Model");
            }

            // Service client
            var setupTemplate = new SetupTemplate { Model = codeModel };
            await Write(setupTemplate, "setup.py");

            var serviceClientInitTemplate = new ServiceClientInitTemplate { Model = codeModel };
            await Write(serviceClientInitTemplate, Path.Combine(codeModel.PackageName, "__init__.py"));

            var serviceClientTemplate = new AzureServiceClientTemplate { Model = codeModel, };
            await Write(serviceClientTemplate, Path.Combine(codeModel.PackageName, codeModel.Name.ToPythonCase() + ".py"));

            var versionTemplate = new VersionTemplate { Model = codeModel, };
            await Write(versionTemplate, Path.Combine(codeModel.PackageName, "version.py"));

            var exceptionTemplate = new ExceptionTemplate { Model = codeModel, };
            await Write(exceptionTemplate, Path.Combine(codeModel.PackageName, "exceptions.py"));

            var credentialTemplate = new CredentialTemplate { Model = codeModel, };
            await Write(credentialTemplate, Path.Combine(codeModel.PackageName, "credentials.py"));

            //Models
            var models = codeModel.ModelTemplateModels.Where(each => !each.Extensions.ContainsKey(AzureExtensions.ExternalExtension));
            if (models.Any())
            {
                var modelInitTemplate = new AzureModelInitTemplate
                {
                    Model = codeModel
                };
                await Write(modelInitTemplate, Path.Combine(codeModel.PackageName, "models", "__init__.py"));

                foreach (var modelType in models)
                {
                    var modelTemplate = new ModelTemplate { Model = modelType };
                    await Write(modelTemplate, Path.Combine(codeModel.PackageName, "models", modelType.Name.ToPythonCase() + ".py"));
                }
            }

            //MethodGroups
            if (codeModel.MethodGroupModels.Any())
            {
                var methodGroupIndexTemplate = new MethodGroupInitTemplate
                {
                    Model = codeModel
                };
                await Write(methodGroupIndexTemplate, Path.Combine(codeModel.PackageName, "operations", "__init__.py"));

                foreach (var methodGroupModel in codeModel.MethodGroupModels)
                {
                    var methodGroupTemplate = new AzureMethodGroupTemplate
                    {
                        Model = methodGroupModel as MethodGroupPya
                    };
                    await Write(methodGroupTemplate, Path.Combine(codeModel.PackageName, "operations", ((string) methodGroupModel.TypeName).ToPythonCase() + ".py"));
                }
            }

            // Enums
            if (codeModel.EnumTypes.Any())
            {
                var enumTemplate = new EnumTemplate { Model = codeModel.EnumTypes };
                await Write(enumTemplate, Path.Combine(codeModel.PackageName, "models", codeModel.Name.ToPythonCase() + "_enums.py"));
            }

            // Page class
            foreach (var pageModel in codeModel.PageModels)
            {
                var pageTemplate = new PageTemplate
                {
                    Model = pageModel
                };
                await Write(pageTemplate, Path.Combine(codeModel.PackageName, "models", pageModel.TypeDefinitionName.ToPythonCase() + ".py"));
            }
        }
Beispiel #25
0
        /// <summary>
        /// Flattens the Resource Properties.
        /// </summary>
        /// <param name="codeModelient"></param>
        public static void FlattenModels(CodeModel codeModel)
        {
            if (codeModel == null)
            {
                throw new ArgumentNullException("codeModel");
            }

            // About "flattenDepth": flattening was not really deterministic and depended on order of specification
            // Sorting by the following method enforces the right behavior
            Func<IModelType, int, int> flattenDepth = null;
            flattenDepth = (type, depth) =>
            {
                var ct = type as CompositeType;
                if (ReferenceEquals(ct, null) || !ct.Properties.Any(p => p.ShouldBeFlattened()) || depth > 16)
                    return 0;
                return 1 + ct.Properties.Max(prop => flattenDepth(prop.ModelType, depth + 1));
            };

            HashSet<string> typesToDelete = new HashSet<string>();
            foreach (var compositeType in codeModel.ModelTypes.OrderByDescending(type => flattenDepth(type, 0)))
            {
                if (compositeType.Properties.Any(p => p.ShouldBeFlattened())
                    && !typesToDelete.Contains(compositeType.Name))
                {
                    List<Property> oldProperties = compositeType.Properties.ToList();
                    compositeType.ClearProperties();

                    foreach (Property innerProperty in oldProperties)
                    {
                        if (innerProperty.ShouldBeFlattened() && compositeType != innerProperty.ModelType)
                        {
                            FlattenProperty(innerProperty, typesToDelete)
                                .ForEach(p => compositeType.Add(p));
                        }
                        else
                        {
                            compositeType.Add(innerProperty);
                        }
                    }

                    RemoveFlatteningConflicts(compositeType);
                }
            }

            RemoveUnreferencedTypes(codeModel, typesToDelete);
        }
Beispiel #26
0
        /// <summary>
        /// Ensures that global parameters that are tagged with x-ms-paramater-location: "method" are not client properties
        /// </summary>
        /// <param name="codeModelient"></param>
        public static void ProcessGlobalParameters(CodeModel codeModel)
        {
            if (codeModel == null)
            {
                throw new ArgumentNullException("codeModel");
            }

            List<Property> propertiesToProcess = new List<Property>();
            foreach(var property in codeModel.Properties)
            {
                if (property.Extensions.ContainsKey(ParameterLocationExtension) && property.Extensions[ParameterLocationExtension].ToString().EqualsIgnoreCase("method"))
                {
                    propertiesToProcess.Add(property);
                }
            }
            //set the clientProperty to null for such parameters in the method.
            foreach(var prop in propertiesToProcess)
            {
                codeModel.Remove(prop);
                foreach(var method in codeModel.Operations.SelectMany(each => each.Methods))
                {
                    foreach(var parameter in method.Parameters)
                    {
                        if (parameter.Name.FixedValue == prop.Name.FixedValue && parameter.IsClientProperty)
                        {
                            parameter.ClientProperty = null;
                        } 
                    }
                }
            }
        }
Beispiel #27
0
        /// <summary>
        /// Cleans all model types that are not used
        /// </summary>
        /// <param name="codeModelient"></param>
        /// <param name="typeNames"></param>
        public static void RemoveUnreferencedTypes(CodeModel codeModel, HashSet<string> typeNames)
        {
            if (codeModel == null)
            {
                throw new ArgumentNullException("codeModel");
            }

            if (typeNames == null)
            {
                throw new ArgumentNullException("typeNames");
            }

            while (typeNames.Count > 0)
            {
                string typeName = typeNames.First();
                typeNames.Remove(typeName);

                var typeToDelete = codeModel.ModelTypes.First(t => t.Name == typeName);

                var isUsedInErrorTypes = codeModel.ErrorTypes.Any(e => e.Name == typeName);
                var isUsedInResponses = codeModel.Methods.Any(m => m.Responses.Any(r => r.Value.Body == typeToDelete));
                var isUsedInParameters = codeModel.Methods.Any(m => m.Parameters.Any(p => p.ModelType == typeToDelete));
                var isBaseType = codeModel.ModelTypes.Any(t => t.BaseModelType == typeToDelete);
                var isUsedInProperties = codeModel.ModelTypes.Where(t => !typeNames.Contains(t.Name))
                                                                 .Any(t => t.Properties.Any(p => p.ModelType == typeToDelete));
                if (!isUsedInErrorTypes &&
                    !isUsedInResponses &&
                    !isUsedInParameters &&
                    !isBaseType &&
                    !isUsedInProperties)
                {
                    codeModel.Remove(typeToDelete);
                }
            }
        }
Beispiel #28
0
        /// <summary>
        /// Generates C# code for service client.
        /// </summary>
        /// <param name="cm"></param>
        /// <returns></returns>
        public override async Task Generate(CodeModel cm)
        {
            var codeModel = cm as CodeModelCsa;
            if (codeModel == null)
            {
                throw new InvalidCastException("CodeModel is not a Azure c# CodeModel");
            }

            // Service client
            var serviceClientTemplate = new AzureServiceClientTemplate { Model = codeModel };
            await Write(serviceClientTemplate, $"{codeModel.Name}{ImplementationFileExtension}");

            // Service client interface
            var serviceClientInterfaceTemplate = new ServiceClientInterfaceTemplate { Model = codeModel };
            await Write(serviceClientInterfaceTemplate, "I" + codeModel.Name + ImplementationFileExtension);

            // Operations
            foreach (MethodGroupCs group in codeModel.Operations)
            {
                if (!group.IsCodeModelMethodGroup)
                {
                    // Operation
                    var operationsTemplate = new AzureMethodGroupTemplate { Model = group };
                    await Write(operationsTemplate, operationsTemplate.Model.TypeName + ImplementationFileExtension);

                    // Operation interface
                    var operationsInterfaceTemplate = new MethodGroupInterfaceTemplate { Model = group };
                    await Write(operationsInterfaceTemplate,
                        $"I{operationsInterfaceTemplate.Model.TypeName}{ImplementationFileExtension}");
                }
                var operationExtensionsTemplate = new ExtensionsTemplate { Model = group };
                await Write(operationExtensionsTemplate,
                    $"{group.ExtensionTypeName}Extensions{ImplementationFileExtension}");
            }

            // Models
            foreach (CompositeTypeCs model in codeModel.ModelTypes.Concat(codeModel.HeaderTypes))
            {
                if (model.Extensions.ContainsKey(AzureExtensions.ExternalExtension) &&
                    (bool)model.Extensions[AzureExtensions.ExternalExtension])
                {
                    continue;
                }
                if (model.IsResource())
                {
                    continue;
                }
                var modelTemplate = new ModelTemplate { Model = model };
                await Write(modelTemplate, Path.Combine(Settings.Instance.ModelsName,
                    $"{model.Name}{ImplementationFileExtension}"));
            }

            // Enums
            foreach (EnumTypeCs enumType in codeModel.EnumTypes)
            {
                var enumTemplate = new EnumTemplate { Model = enumType };
                await Write(enumTemplate, Path.Combine(Settings.Instance.ModelsName,
                    $"{enumTemplate.Model.Name}{ImplementationFileExtension}"));
            }

            // Page class
            foreach (var pageClass in codeModel.pageClasses)
            {
                var pageTemplate = new PageTemplate
                {
                    Model = new Page(pageClass.Value, pageClass.Key.Key, pageClass.Key.Value)
                };
                await Write(pageTemplate, Path.Combine(Settings.Instance.ModelsName,
                    $"{pageTemplate.Model.TypeDefinitionName}{ImplementationFileExtension}"));
            }
            // Exceptions
            foreach (CompositeTypeCs exceptionType in codeModel.ErrorTypes)
            {
                if (exceptionType.Name == "CloudError")
                {
                    continue;
                }

                var exceptionTemplate = new ExceptionTemplate { Model = exceptionType };
                await Write(exceptionTemplate, Path.Combine(Settings.Instance.ModelsName,
                     $"{exceptionTemplate.Model.ExceptionTypeDefinitionName}{ImplementationFileExtension}"));
            }
        }
        public static string GetExceptionDefinitionTypeIfExists(this CompositeType type, CodeModel serviceClient)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            if (serviceClient == null)
            {
                throw new ArgumentNullException("serviceClient");
            }

            if (serviceClient.ErrorTypes.Contains(type))
            {
                return type.GetExceptionDefineType();
            }
            else
            {
                return null;
            }
        }