Example #1
0
        /// <summary>
        /// Validate that the CSDL metadata defined for a service matches the documentation.
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        private static async Task <bool> CheckServiceMetadataAsync(CheckMetadataOptions options)
        {
            List <Schema> schemas = await TryGetMetadataSchemasAsync(options);

            if (null == schemas)
            {
                return(false);
            }

            FancyConsole.WriteLine(FancyConsole.ConsoleSuccessColor, "  found {0} schema definitions: {1}", schemas.Count, (from s in schemas select s.Namespace).ComponentsJoinedByString(", "));

            var docSet = await GetDocSetAsync(options);

            if (null == docSet)
            {
                return(false);
            }

            const string testname = "validate-service-metadata";

            TestReport.StartTest(testname);

            List <ResourceDefinition> foundResources = ODataParser.GenerateResourcesFromSchemas(schemas);
            CheckResults results = new CheckResults();

            List <ValidationError> collectedErrors = new List <ValidationError>();

            foreach (var resource in foundResources)
            {
                FancyConsole.WriteLine();
                FancyConsole.Write(FancyConsole.ConsoleHeaderColor, "Checking resource: {0}...", resource.Metadata.ResourceType);

                FancyConsole.VerboseWriteLine();
                FancyConsole.VerboseWriteLine(resource.JsonExample);
                FancyConsole.VerboseWriteLine();

                // Verify that this resource matches the documentation
                ValidationError[] errors;
                docSet.ResourceCollection.ValidateJsonExample(resource.Metadata, resource.JsonExample, out errors, new ValidationOptions {
                    RelaxedStringValidation = true
                });
                results.IncrementResultCount(errors);

                collectedErrors.AddRange(errors);

                await WriteOutErrorsAndFinishTestAsync(errors, options.SilenceWarnings, successMessage : " no errors.");
            }

            if (options.IgnoreWarnings)
            {
                results.ConvertWarningsToSuccess();
            }

            var output = (from e in collectedErrors select e.ErrorText).ComponentsJoinedByString("\r\n");

            await TestReport.FinishTestAsync(testname, results.WereFailures?TestOutcome.Failed : TestOutcome.Passed, stdOut : output);

            results.PrintToConsole();
            return(!results.WereFailures);
        }
Example #2
0
        private static async Task <List <Schema> > TryGetMetadataSchemasAsync(CheckMetadataOptions options)
        {
            if (string.IsNullOrEmpty(options.ServiceMetadataLocation))
            {
                RecordError("No service metadata file location specified.");
                return(null);
            }

            FancyConsole.WriteLine(FancyConsole.ConsoleHeaderColor, "Loading service metadata from '{0}'...", options.ServiceMetadataLocation);

            List <Schema> schemas;

            try
            {
                Uri metadataUrl;
                if (Uri.TryCreate(options.ServiceMetadataLocation, UriKind.Absolute, out metadataUrl))
                {
                    schemas = await ODataParser.ReadSchemaFromMetadataUrlAsync(metadataUrl);
                }
                else
                {
                    schemas = await ODataParser.ReadSchemaFromFileAsync(options.ServiceMetadataLocation);
                }
            }
            catch (Exception ex)
            {
                RecordError("Error parsing service metadata: {0}", ex.Message);
                return(null);
            }

            return(schemas);
        }
Example #3
0
        internal static object GetAnnotation(this IODataServiceContext context, params object[] customs)
        {
            if (false == (null != customs && customs.Count() <= 3))
            {
                return(null);
            }

            var serviceUri = customs[0] as Uri;
            var requestUri = customs[1] as Uri;
            var metadata   = customs[2] as IODataServiceMetadata;

            IEdmModel     edmModel     = EdmxReader.Parse(XmlReader.Create(serviceUri + "/$metadata"));
            IEdmEntitySet edmEntitySet = edmModel.EntityContainers()
                                         .First()
                                         .EntitySets()
                                         .FirstOrDefault(es =>
                                                         es.Name.ToLower() == requestUri.Segments.Last().ToLower() ||
                                                         requestUri.Segments.Last().ToLower().StartsWith(es.Name.ToLower() + "(")
                                                         );
            IEdmEntityType edmEntityType  = edmEntitySet.ElementType;
            ODataUriParser internalParser = new ODataUriParser(edmModel, serviceUri);

            var odataParser = new ODataParser()
            {
                EdmModel       = edmModel,
                EdmEntitySet   = edmEntitySet,
                EdmEntityType  = edmEntityType,
                InternalParser = internalParser,
                Metadata       = metadata,
            };

            return(odataParser);
        }
        public async Task <string> PublishToStringAsync(IssueLogger issues)
        {
            string outputFilenameSuffix = "";

            Logger.Info("Begin creating metadata file with documentation annotations.");

            // Step 1: Generate an EntityFramework OM from the documentation and/or template file
            EntityFramework framework = CreateEntityFrameworkFromDocs(issues);

            if (null == framework)
            {
                return(string.Empty);
            }

            // Step 1a: Apply an transformations that may be defined in the documentation
            if (!string.IsNullOrEmpty(options.TransformOutput))
            {
                PublishSchemaChangesConfigFile transformations = DocSet.TryLoadConfigurationFiles <PublishSchemaChangesConfigFile>(options.DocumentationSetPath).Where(x => x.SchemaChanges.TransformationName == options.TransformOutput).FirstOrDefault();
                if (null == transformations)
                {
                    throw new KeyNotFoundException($"Unable to locate a transformation set named {options.TransformOutput}. Aborting.");
                }

                string[] versionsToPublish = options.Version?.Split(new char[] { ',', ' ' });
                framework.ApplyTransformation(transformations.SchemaChanges, versionsToPublish);
                if (!string.IsNullOrEmpty(options.Version))
                {
                    outputFilenameSuffix += $"-{options.Version}";
                }
            }

            if (options.Sort)
            {
                // Sorts the objects in collections, so that we have consistent output regardless of input
                framework.SortObjectGraph();
            }

            if (options.ValidateSchema)
            {
                framework.ValidateSchemaTypes();
            }

            // Step 2: Generate XML representation of EDMX
            string xmlData = ODataParser.Serialize <EntityFramework>(framework, options.AttributesOnNewLines);

            Logger.Info("Finish creating metadata file with documentation annotations.");

            return(xmlData);
        }
Example #5
0
        public DocumentationComplexType(EntityFramework entityFramework, ComplexType complexType)
        {
            this.Name        = complexType.Name;
            this.Description = complexType.GetDescription(entityFramework);
            this.Namespace   = complexType.Namespace;
            this.Properties  = complexType.Properties.Select(p => p.ToDocumentationProperty(entityFramework, complexType)).ToList();
            this.Json        = ODataParser.BuildJsonExample(complexType, entityFramework.DataServices.Schemas);//SampleJsonGenerator.GetSampleJson(entityFramework, complexType).ToString(Formatting.Indented);


            if (complexType.BaseType != null)
            {
                var baseComplexType = entityFramework.DataServices.Schemas.FindTypeWithIdentifier(complexType.BaseType) as ComplexType;
                if (baseComplexType != null)
                {
                    this.BaseType = baseComplexType.Name;
                }
            }
        }
Example #6
0
        public void ODataDemo()
        {
            Parser parser = new ODataParser();
            var    expr1  = parser.Parse <Person, bool>("contains(Address/City,'ams') and FirstName gt 'm'");

            // same query, using another syntax, and so using another parser
            parser = new CompactParser();
            var expr2 = parser.Parse <Person, bool>("Address.City?ams&FirstName>m");

            Assert.AreEqual(expr1.ToString(), expr2.ToString());

            parser = new Parser(new Grammar(ScriptSyntax <DefaultSyntaxExtender> .Instance));
            var    args   = new { a = 10, b = DateTime.Now, c = "foo", d = 10.2 };
            var    expr3  = parser.WithReturnType <double>().Parse("a + day(b) + length(c) + d/2", args);
            var    fn     = expr3.Compile();
            double result = fn(args);

            Debug.WriteLine(result);
        }
        public void FilteredEnumerable_Filtered_CSrv()
        {
            ODataTest(() =>
            {
                // ARRANGE
                var allContentTypes = ContentType.GetContentTypes();
                var refNodes        = new NodeList <Node>(allContentTypes.Select(ct => ct.Id).ToArray());
                var sort            = new[] { new SortInfo("Name") };
                var filter          = new ODataParser().Parse("substringof('Folder', Name) eq true");;

                var expectedNames = allContentTypes
                                    .Where(x => x.Name.Contains("Folder"))
                                    .OrderBy(x => x.Name)
                                    .Select(x => x.Name).ToArray();

                // ACTION
                var enumerable = new FilteredContentEnumerable(refNodes, filter, sort, 0, 0);

                // ASSERT
                var actualNames = enumerable.Select(x => x.Name).ToArray();
                AssertSequenceEqual(expectedNames, actualNames);
            });
        }
Example #8
0
        public static string Parser(string filter)
        {
            if (filter == null)
            {
                throw new ArgumentNullException(nameof(filter));
            }

            if (String.IsNullOrEmpty(filter))
            {
                return(filter);
            }

            var stream = new AntlrInputStream(filter);
            var lexer  = new ODataLexer(stream);
            var tokens = new CommonTokenStream(lexer);
            var parser = new ODataParser(tokens);
            var tree   = parser.program();

            var visitor = new ODataFilterVisitor();
            var result  = visitor.Visit(tree);

            return(result?.ToString());
        }
Example #9
0
        public override async Task PublishToFolderAsync(string outputFolder)
        {
            // Step 1: Generate an EntityFramework OM from the documentation
            EntityFramework framework = CreateEntityFrameworkFromDocs(this.baseUrl);

            // Step 2: Generate XML representation of EDMX
            var xmlData = ODataParser.GenerateEdmx(framework);

            // Step 3: Write the XML to disk
            var outputDir = new System.IO.DirectoryInfo(outputFolder);

            outputDir.Create();

            var outputFilename = System.IO.Path.Combine(outputFolder, "metadata.edmx");

            using (var writer = System.IO.File.CreateText(outputFilename))
            {
                await writer.WriteAsync(xmlData);

                await writer.FlushAsync();

                writer.Close();
            }
        }
        public override async Task PublishToFolderAsync(string outputFolder)
        {
            string outputFilenameSuffix = null;

            // Step 1: Generate an EntityFramework OM from the documentation and/or template file
            EntityFramework framework = CreateEntityFrameworkFromDocs();

            if (null == framework)
            {
                return;
            }

            // Step 1a: Apply an transformations that may be defined in the documentation
            if (!string.IsNullOrEmpty(options.TransformOutput))
            {
                PublishSchemaChangesConfigFile transformations = DocSet.TryLoadConfigurationFiles <PublishSchemaChangesConfigFile>(options.DocumentationSetPath).Where(x => x.SchemaChanges.TransformationName == options.TransformOutput).FirstOrDefault();
                if (null == transformations)
                {
                    throw new KeyNotFoundException($"Unable to locate a transformation set named {options.TransformOutput}. Aborting.");
                }

                string[] versionsToPublish = options.Version?.Split(new char[] { ',', ' ' });
                framework.ApplyTransformation(transformations.SchemaChanges, versionsToPublish);
                if (!string.IsNullOrEmpty(options.Version))
                {
                    outputFilenameSuffix = $"-{options.Version}";
                }
            }

            if (options.Sort)
            {
                // Sorts the objects in collections, so that we have consistent output regardless of input
                framework.SortObjectGraph();
            }

            if (options.ValidateSchema)
            {
                framework.ValidateSchemaTypes();
            }

            // Step 2: Generate XML representation of EDMX
            string xmlData = null;

            if (options.Formats.HasFlag(MetadataFormat.EdmxOutput))
            {
                xmlData = ODataParser.Serialize <EntityFramework>(framework, options.AttributesOnNewLines);
            }
            else if (options.Formats.HasFlag(MetadataFormat.SchemaOutput))
            {
                xmlData = ODataParser.Serialize <Schema>(framework.DataServices.Schemas.First(), options.AttributesOnNewLines);
            }

            // Step 3: Write the XML to disk

            var outputFullName = GenerateOutputFileFullName(options.SourceMetadataPath, outputFolder, outputFilenameSuffix);

            Console.WriteLine($"Publishing metadata to {outputFullName}");

            using (var writer = System.IO.File.CreateText(outputFullName))
            {
                await writer.WriteAsync(xmlData);

                await writer.FlushAsync();

                writer.Close();
            }
        }
        private EntityFramework CreateEntityFrameworkFromDocs()
        {
            EntityFramework edmx = new EntityFramework();

            if (!string.IsNullOrEmpty(options.SourceMetadataPath))
            {
                try
                {
                    if (!System.IO.File.Exists(options.SourceMetadataPath))
                    {
                        throw new System.IO.FileNotFoundException($"Unable to locate source file: {options.SourceMetadataPath}");
                    }

                    using (System.IO.FileStream stream = new System.IO.FileStream(options.SourceMetadataPath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                    {
                        if (options.Formats.HasFlag(MetadataFormat.EdmxInput))
                        {
                            edmx = ODataParser.Deserialize <EntityFramework>(stream);
                        }
                        else if (options.Formats.HasFlag(MetadataFormat.SchemaInput))
                        {
                            var schema = ODataParser.Deserialize <Schema>(stream);
                            edmx = new EntityFramework();
                            edmx.DataServices.Schemas.Add(schema);
                        }
                        else
                        {
                            throw new InvalidOperationException("Source file was specified but no format for source file was provided.");
                        }
                    }
                    if (options.Namespaces != null && options.Namespaces.Any())
                    {
                        var schemas = edmx.DataServices.Schemas.ToArray();
                        foreach (var s in schemas)
                        {
                            if (!options.Namespaces.Contains(s.Namespace))
                            {
                                edmx.DataServices.Schemas.Remove(s);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Unable to deserialize source template file: {ex.Message}");
                    if (ex.InnerException != null)
                    {
                        Console.WriteLine($"{ex.InnerException.Message}");
                    }
                    return(null);
                }
            }

            bool generateNewElements = !options.SkipMetadataGeneration;

            // Add resources
            if (Documents.Files.Any())
            {
                foreach (var resource in Documents.Resources)
                {
                    var targetSchema = FindOrCreateSchemaForNamespace(resource.Name.NamespaceOnly(), edmx, generateNewElements: generateNewElements);
                    if (targetSchema != null)
                    {
                        AddResourceToSchema(targetSchema, resource, edmx, generateNewElements: generateNewElements);
                    }
                }

                // Figure out the EntityCollection
                this.BuildEntityContainer(edmx, options.BaseUrl);

                // Add actions to the collection
                this.ProcessRestRequestPaths(edmx, options.BaseUrl);
            }

            return(edmx);
        }
Example #12
0
        static int Main(string[] args)
        {
            SqlServerTypes.Utilities.LoadNativeAssemblies(AppDomain.CurrentDomain.BaseDirectory);

            //const string ConnectionString = "Initial Catalog=MiniProf;Data Source=.\\SqlExpress;Integrated Security=true;";
            //using(var conn = new SqlConnection(ConnectionString))
            //{
            //    conn.Open();
            //    conn.Execute(SqlServerStorage.TableCreationScript);
            //}
            //MiniProfiler.Settings.Storage = new SqlServerStorage(ConnectionString);
            MiniProfiler.Settings.ProfilerProvider = new SingletonProfilerProvider();
            MiniProfiler.Settings.ProfilerProvider.Start(ProfileLevel.Info);
            MiniProfiler.Settings.SqlFormatter = new StackExchange.Profiling.SqlFormatters.InlineFormatter();
            MiniProfilerEF6.Initialize();
            MiniProfiler.Start();

            Parser parser     = new CompactParser();
            var    debug      = true;
            Type   entityType = null;

            con.WriteLine("*** type help for command list ***");

            while (true)
            {
                if (entityType != null)
                {
                    System.Console.Write("[enter query for entity '" + entityType.Name + "'] : ");
                }
                else
                {
                    System.Console.Write(": ");
                }
                var input = System.Console.ReadLine();
                switch (input)
                {
                case "quit":
                case "exit":
                    return(0);

                case "cls":
                case "clr":
                    System.Console.Clear();
                    continue;

                case "strict":
                    parser.Grammar.Strict = !parser.Grammar.Strict;
                    System.Console.WriteLine("strict is: " + parser.Grammar.Strict);
                    break;

                case "entity":
                    System.Console.Write("[use entity type] : ");
                    var typeName = System.Console.ReadLine();
                    if (string.IsNullOrEmpty(typeName))
                    {
                        entityType = null;
                        break;
                    }
                    entityType = Type.GetType(typeof(Address).AssemblyQualifiedName.Replace("Address", typeName), false, true);
                    if (entityType == null)
                    {
                        con.WriteLine("Type " + typeName + " not found, use Address or Person");
                    }
                    break;

                case "debug":
                    debug = !debug;
                    System.Console.WriteLine("debug is: " + debug);
                    break;

                case "functions":
                    foreach (var m in parser.Grammar.Functions.Select(m => m.Name).Distinct().OrderBy(s => s))
                    {
                        System.Console.WriteLine(m);
                    }
                    break;

                case "?":
                case "help":
                    System.Console.WriteLine("Commands:");
                    System.Console.WriteLine(" quit       - quit program");
                    System.Console.WriteLine(" cls        - clear screen");
                    System.Console.WriteLine(" strict     - toggle strict on/off");
                    System.Console.WriteLine(" debug      - toggle debug on/off");
                    System.Console.WriteLine(" syntax     - change syntax");
                    System.Console.WriteLine(" functions  - show functions");
                    System.Console.WriteLine(" entity     - set/change entity type as a LINQ query target");
                    System.Console.WriteLine(" <other>    - expression that will be evaluated");
                    break;

                case "syntax":
                    System.Console.Write("[change syntax into] : ");
                    switch (System.Console.ReadLine())
                    {
                    case "odata":
                        parser = new ODataParser();
                        break;

                    case "compact":
                        parser = new CompactParser();
                        break;

                    case "query":
                        parser = new QueryParser();
                        break;

                    case "math":
                        parser = new MathParser();
                        break;

                    default:
                        System.Console.WriteLine("* Unknown syntax. Known syntax types: odata,compact,query,math");
                        break;
                    }
                    break;

                default:
                    if (entityType != null)
                    {
                        if (!string.IsNullOrEmpty(input))
                        {
                            var result = ExpressionToLinqExecuter.Execute(parser, entityType, input);
                            con.WriteLine("* Count: " + result.Count());
                            MiniProfiler.Settings.ProfilerProvider.Stop(false);
                            WriteExecutedQueries();
                            //MiniProfiler.Settings.Storage.Save(MiniProfiler.Current);
                            MiniProfiler.Settings.ProfilerProvider.Start(ProfileLevel.Info);
                        }
                        else
                        {
                            entityType = null;
                        }
                        break;
                    }
                    try
                    {
                        var lambda    = parser.Parse <object, object>(input);
                        var @delegate = lambda.Compile();
                        var result    = @delegate(new object());
                        if (debug)
                        {
                            System.Console.WriteLine("? {0} => {1}", lambda, lambda.Simplify());
                        }
                        System.Console.WriteLine("= {0}", result ?? "NULL");
                    }
                    catch (XPressionException ex)
                    {
                        System.Console.WriteLine(ex.FullMessage);
                    }
                    catch (Exception ex)
                    {
                        System.Console.WriteLine(ex.Message);
                    }
                    break;
                }
            }
        }