public async Task ParserValidationResolveFromLocalRepository()
        {
            ModelParser parser           = new ModelParser();
            string      TestRegistryPath = TestHelpers.TestLocalModelRepository;

            List <string> parseModelPaths = new List <string>()
            {
                $"{TestRegistryPath}/dtmi/company/demodevice-2.json",
                $"{TestRegistryPath}/dtmi/com/example/temperaturecontroller-1.json",
                $"{TestRegistryPath}/dtmi/com/example/camera-3.json",
            };

            // Shows how to quickly integrate the resolver client with the parser.
            ResolverClient client = new ResolverClient(TestRegistryPath);

            parser.DtmiResolver = client.ParserDtmiResolver;

            foreach (string modelPath in parseModelPaths)
            {
                // Parser will throw on validation errors
                try {
                    await parser.ParseAsync(new string[] { File.ReadAllText(modelPath) });
                }
                catch (Exception e)
                {
                    Assert.Fail(e.Message);
                }
            }
        }
        public async Task ParseDemoAsync(DigitalTwinsClient client)
        {
            try
            {
                AsyncPageable <DigitalTwinsModelData> mdata = client.GetModelsAsync(new GetModelsOptions {
                    IncludeModelDefinition = true
                });
                var models = new List <string>();
                await foreach (DigitalTwinsModelData md in mdata)
                {
                    models.Add(md.DtdlModel);
                }
                var parser = new ModelParser();
                IReadOnlyDictionary <Dtmi, DTEntityInfo> dtdlOM = await parser.ParseAsync(models);

                var interfaces = new List <DTInterfaceInfo>();
                IEnumerable <DTInterfaceInfo> ifenum =
                    from entity in dtdlOM.Values
                    where entity.EntityKind == DTEntityKind.Interface
                    select entity as DTInterfaceInfo;
                interfaces.AddRange(ifenum);
                foreach (DTInterfaceInfo dtif in interfaces)
                {
                    PrintInterfaceContent(dtif, dtdlOM);
                }
            }
            catch (RequestFailedException ex)
            {
                Console.WriteLine($"Failed due to {ex}");
                throw;
            }
        }
Пример #3
0
        private static async Task <IReadOnlyDictionary <Dtmi, DTEntityInfo> > ParseModelsAsync(Dictionary <string, string> modelTexts)
        {
            IReadOnlyDictionary <Dtmi, DTEntityInfo> entities = null;

            try
            {
                var parser = new ModelParser();
                entities = await parser.ParseAsync(modelTexts.Values);
            }
            catch (ParsingException ex)
            {
                Log.Error("Errors parsing models.");
                foreach (ParsingError error in ex.Errors)
                {
                    Log.Error(error.Message);
                }
            }
            catch (Exception ex)
            {
                Log.Error("Errors parsing models.");
                Log.Error(ex.Message);
            }

            return(entities);
        }
        private async Task ValidateAsync(string input, string resolverName)
        {
            ModelParser parser = new ModelParser();

            parser.Options = new HashSet <ModelParsingOption>()
            {
                ModelParsingOption.StrictPartitionEnforcement
            };
            ConfigureResolver(parser, resolverName);

            try
            {
                var parserResult = await parser.ParseAsync(new string[] { File.ReadAllText(input) });

                Console.WriteLine("Resolution completed");
                foreach (var item in parserResult.Values)
                {
                    this.log.LogTrace(item.Id.AbsoluteUri);
                }
                Console.WriteLine($"\nValidation Passed: {input}");
            }
            catch (Exception ex)
            {
                Environment.ExitCode = 1;
                log.LogError(ex, "DTDL Parser Exception");
            }
        }
Пример #5
0
        static async Task Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("Usage: repo-client <dtmi>");
                return;
            }
            string rootDtmi = args[0];

            GetModel(rootDtmi);

            ModelParser parser = new ModelParser();

            try
            {
                //modelParser.DtmiResolver = LocalDtmiResolver;
                var parsedDtmis = await parser.ParseAsync(allModels.Values);

                var interfaces = parsedDtmis.Where(r => r.Value.EntityKind == DTEntityKind.Interface).ToList();
                foreach (var dt in interfaces)
                {
                    Console.WriteLine(dt.Key.AbsoluteUri + " " + dt.Value.DefinedIn);
                    var ifcs = parsedDtmis.Where(r => r.Value.DefinedIn == dt.Key);
                    foreach (var i in ifcs)
                    {
                        Console.WriteLine(i.Value.Id);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        //https://docs.microsoft.com/en-us/azure/iot-pnp/concepts-model-parser
        public static async Task <Dictionary <string, DTDLContainer> > ParseDTDLAndBuildDynamicContentAsync(JArray dtdlArray)
        {
            if (dtdlArray == null)
            {
                throw new ArgumentNullException(nameof(dtdlArray));
            }

            Dictionary <string, DTDLContainer> globalResult = new Dictionary <string, DTDLContainer>();
            DTDLContainer itemResult = null;

            ModelParser parser = new ModelParser();

            IReadOnlyDictionary <Dtmi, DTEntityInfo> parseResult = await parser.ParseAsync(dtdlArray.Select(i => JsonConvert.SerializeObject(i)));

            foreach (JObject dtdl in dtdlArray)
            {
                try
                {
                    //PROCESS COMPONENTS
                    await ProcessComponentsWithDynamicContent(dtdlArray, dtdl, globalResult);

                    //ALL EXCEPT COMPONENTS
                    itemResult = BuildDynamicContent(dtdl);
                }
                catch (ParsingException pex)
                {
                    if (itemResult == null)
                    {
                        itemResult = new DTDLContainer();
                    }

                    itemResult.ParsingErrors = pex.Errors.Select(i => i.Message);
                }
                catch (Exception ex)
                {
                    itemResult = null;
                }
                finally
                {
                    if (itemResult != null)
                    {
                        if (!globalResult.ContainsKey(dtdl["@id"].Value <string>()))
                        {
                            globalResult.Add(dtdl["@id"].Value <string>(), itemResult);
                        }
                    }

                    itemResult = null;
                }
            }


            return(globalResult);
        }
        public static async Task <IReadOnlyDictionary <Dtmi, DTEntityInfo> > ParseDTDLAsync(JArray dtdlArray)
        {
            if (dtdlArray == null)
            {
                throw new ArgumentNullException(nameof(dtdlArray));
            }

            ModelParser parser = new ModelParser();

            return(await parser.ParseAsync(dtdlArray.Select(i => JsonConvert.SerializeObject(i))));
        }
        private static async Task NotFound()
        {
            string         dtmi   = "dtmi:com:example:NotFound;1";
            ResolverClient rc     = new ResolverClient();
            var            models = await rc.ResolveAsync(dtmi);

            ModelParser parser      = new ModelParser();
            var         parseResult = await parser.ParseAsync(models.Values.ToArray());

            Console.WriteLine($"{dtmi} resolved in {models.Count} interfaces with {parseResult.Count} entities.");
        }
        public static async Task GetModelsAndParseAsync()
        {
            var dtmi   = "dtmi:com:example:TemperatureController;1";
            var client = new ModelsRepositoryClient();
            IDictionary <string, string> models = await client.GetModelsAsync(dtmi).ConfigureAwait(false);

            var parser = new ModelParser();
            IReadOnlyDictionary <Dtmi, DTEntityInfo> parseResult = await parser.ParseAsync(models.Values.ToArray());

            Console.WriteLine($"{dtmi} resolved in {models.Count} interfaces with {parseResult.Count} entities.");
        }
Пример #10
0
        private static async Task ResolveAndParse()
        {
            string         dtmi   = "dtmi:com:example:TemperatureController;1";
            ILogger        logger = LoggerFactory.Create(builder => builder.AddDebug().SetMinimumLevel(LogLevel.Trace)).CreateLogger <Program>();
            ResolverClient rc     = new ResolverClient(logger);
            var            models = await rc.ResolveAsync(dtmi);

            ModelParser parser      = new ModelParser();
            var         parseResult = await parser.ParseAsync(models.Values.ToArray());

            Console.WriteLine($"{dtmi} resolved in {models.Count} interfaces with {parseResult.Count} entities.");
        }
        private static async Task ParseAndResolve()
        {
            string         dtmi   = "dtmi:com:example:TemperatureController;1";
            ResolverClient rc     = new ResolverClient(new ResolverClientOptions(DependencyResolutionOption.Disabled));
            var            models = await rc.ResolveAsync(dtmi);

            ModelParser parser = new ModelParser();

            parser.DtmiResolver = rc.ParserDtmiResolver;
            var parseResult = await parser.ParseAsync(models.Values.Take(1).ToArray());

            Console.WriteLine($"{dtmi} resolved in {models.Count} interfaces with {parseResult.Count} entities.");
        }
Пример #12
0
        public async Task <bool> IsValidDtdlFileAsync(FileInfo modelFile, bool strict)
        {
            _logger.LogInformation($"Using repository: '{_repository}'");
            ModelParser parser = GetParser();

            await parser.ParseAsync(new string[] { File.ReadAllText(modelFile.FullName) });

            if (strict)
            {
                return(await modelFile.Validate());
            }

            return(true);
        }
Пример #13
0
        public static async Task GetModelAndParseAsync()
        {
            #region Snippet:ModelsRepositorySamplesParserIntegrationGetModelsAndParseAsync

            var         client = new ModelsRepositoryClient();
            var         dtmi   = "dtmi:com:example:TemperatureController;1";
            ModelResult result = await client.GetModelAsync(dtmi).ConfigureAwait(false);

            var parser = new ModelParser();
            IReadOnlyDictionary <Dtmi, DTEntityInfo> parseResult = await parser.ParseAsync(result.Content.Values);

            Console.WriteLine($"{dtmi} resolved in {result.Content.Count} interfaces with {parseResult.Count} entities.");

            #endregion Snippet:ModelsRepositorySamplesParserIntegrationGetModelsAndParseAsync
        }
        public static async Task ParseAndGetModelsWithExtensionAsync()
        {
            var dtmi   = "dtmi:com:example:TemperatureController;1";
            var client = new ModelsRepositoryClient(new ModelsRepositoryClientOptions(resolutionOption: DependencyResolutionOption.Disabled));
            IDictionary <string, string> models = await client.GetModelsAsync(dtmi).ConfigureAwait(false);

            var parser = new ModelParser
            {
                // Usage of the ModelsRepositoryClientExtensions.ParserDtmiResolver extension.
                DtmiResolver = client.ParserDtmiResolver
            };
            IReadOnlyDictionary <Dtmi, DTEntityInfo> parseResult = await parser.ParseAsync(models.Values.Take(1).ToArray());

            Console.WriteLine($"{dtmi} resolved in {models.Count} interfaces with {parseResult.Count} entities.");
        }
        public async Task <IReadOnlyDictionary <Dtmi, DTEntityInfo> > ParseModelAsync(string dtmi)
        {
            string modelContent = string.Empty;
            IReadOnlyDictionary <Dtmi, DTEntityInfo> parseResult = null;
            List <string> listModelJson = new List <string>();

            string dtmiPath = DtmiToPath(dtmi);

            if (!string.IsNullOrEmpty(dtmiPath))
            {
                if (!string.IsNullOrEmpty(_modelRepoUrl_Private))
                {
                    modelContent = await GetModelContentAsync(dtmiPath, false);
                }

                if (string.IsNullOrEmpty(modelContent))
                {
                    // try public repo
                    modelContent = await GetModelContentAsync(dtmiPath, true);
                }

                if (!string.IsNullOrEmpty(modelContent))
                {
                    listModelJson.Add(modelContent);
                }

                try
                {
                    ModelParser dtdlModelParser = new ModelParser();
                    dtdlModelParser.DtmiResolver = DtmiResolver;

                    if (!string.IsNullOrEmpty(_modelRepoUrl_Private))
                    {
                        _modelRepoUrl = _modelRepoUrl_Private;
                    }
                    else
                    {
                        _modelRepoUrl = _modelRepoUrl_Public;
                    }
                    parseResult = await dtdlModelParser.ParseAsync(listModelJson);
                }
                catch (Exception e)
                {
                    _logger.LogError($"Error ParseModelAsync(): {e.Message}");
                }
            }
            return(parseResult);
        }
        public async Task ParserValidationResolveFromRemoteRepository()
        {
            ModelParser parser = new ModelParser();

            // TODO: One off model -- need consistent remote model repo for IT's
            string TestRepoPath  = TestHelpers.TestLocalModelRepository;
            string testModelPath = $"{TestRepoPath}/dtmi/company/demodevice-2.json";

            // Shows how to quickly integrate the resolver client with the parser.
            ResolverClient client = new ResolverClient(TestHelpers.TestRemoteModelRepository);

            parser.DtmiResolver = client.ParserDtmiResolver;

            // Parser will throw on validation errors
            await parser.ParseAsync(new string[] { File.ReadAllText(testModelPath) });
        }
        public async Task <IReadOnlyDictionary <Dtmi, DTEntityInfo> > ParseModelAsync(string dtmi)
        {
            string modelContent = string.Empty;
            IReadOnlyDictionary <Dtmi, DTEntityInfo> parseResult = null;
            List <string> listModelJson = new List <string>();

            string dtmiPath = DtmiToPath(dtmi);

            if (!string.IsNullOrEmpty(dtmiPath))
            {
                modelContent = await GetModelContentAsync(dtmiPath, false);

                if (string.IsNullOrEmpty(modelContent))
                {
                    // try public repo
                    modelContent = await GetModelContentAsync(dtmiPath);
                }

                if (!string.IsNullOrEmpty(modelContent))
                {
                    listModelJson.Add(modelContent);
                }

                try
                {
                    ModelParser parser = new ModelParser();
                    parser.DtmiResolver = DtmiResolver;
                    //parser.DtmiResolver = (IReadOnlyCollection<Dtmi> dtmis) =>
                    //{
                    //    foreach (Dtmi d in dtmis)
                    //    {
                    //        _logger.LogInformation($"-------------  {d}");
                    //    }
                    //    return null;
                    //};
                    parseResult = await parser.ParseAsync(listModelJson);
                }
                catch (Exception e)
                {
                    _logger.LogError($"Error ParseModelAsync(): {e.Message}");
                }
            }
            return(parseResult);
        }
Пример #18
0
        static async Task Main(string[] args)
        {
            List <string> modelsContents = new List <string>();

            if (args.Length < 1)
            {
                args = new string[] { "." };
            }
            string input = args[0];

            if (!File.Exists(input) && !Directory.Exists(input))
            {
                Console.WriteLine($"Error: '{input}' not found.");
                return;
            }

            if (File.Exists(input))
            {
                modelsContents.Add(File.ReadAllText(input));
            }
            if (Directory.Exists(input))
            {
                foreach (var file in  Directory.GetFiles(input))
                {
                    modelsContents.Add(File.ReadAllText(file));
                }
            }

            try
            {
                modelParser.DtmiResolver = DtmiResolver;
                var parsedDtmis = await modelParser.ParseAsync(modelsContents);

                var interfaces = parsedDtmis.Where(r => r.Value.EntityKind == DTEntityKind.Interface).ToList();
                foreach (var dt in interfaces)
                {
                    Console.WriteLine(dt.Key.AbsoluteUri + " " + dt.Value.DefinedIn);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
Пример #19
0
        public static async Task ParseAndGetModelWithExtensionAsync()
        {
            #region Snippet:ModelsRepositorySamplesParserIntegrationParseAndGetModelsAsync

            var         client = new ModelsRepositoryClient();
            var         dtmi   = "dtmi:com:example:TemperatureController;1";
            ModelResult result = await client.GetModelAsync(dtmi, ModelDependencyResolution.Disabled).ConfigureAwait(false);

            var parser = new ModelParser
            {
                // Usage of the ModelsRepositoryClientExtensions.ParserDtmiResolver extension.
                DtmiResolver = client.ParserDtmiResolver
            };
            IReadOnlyDictionary <Dtmi, DTEntityInfo> parseResult = await parser.ParseAsync(result.Content.Values);

            Console.WriteLine($"{dtmi} resolved in {result.Content.Count} interfaces with {parseResult.Count} entities.");

            #endregion Snippet:ModelsRepositorySamplesParserIntegrationParseAndGetModelsAsync
        }
        public void ParserValidationResolveFromLocalRepoErrorOnParserCallbackDtmiCasing()
        {
            ModelParser parser           = new ModelParser();
            string      TestRegistryPath = TestHelpers.TestLocalModelRepository;

            // This model references another model with invalid casing.
            string modelPath = $"{TestRegistryPath}/dtmi/company/demodevice-1.json";

            // Shows how to quickly integrate the resolver client with the parser.
            ResolverClient client = new ResolverClient(TestRegistryPath);

            parser.DtmiResolver = client.ParserDtmiResolver;

            // Parser will throw on validation errors

            ResolverException e =
                Assert.ThrowsAsync <ResolverException>(async() => await parser.ParseAsync(new string[] { File.ReadAllText(modelPath) }));

            Assert.AreEqual(e.Message,
                            $"{StandardStrings.GenericResolverError("dtmi:azure:deviceManagement:DeviceInformation;1")}" +
                            $"{StandardStrings.IncorrectDtmiCasing("dtmi:azure:deviceManagement:DeviceInformation;1","dtmi:azure:DeviceManagement:DeviceInformation;1")}");
        }
Пример #21
0
        static async Task Main(string[] args)
        {
            // Target DTMI for resolution.
            string toParseDtmi = args.Length == 0 ? "dtmi:com:example:TemperatureController;1" : args[0];

            // Initiate first Resolve for the target dtmi to pass content to parser
            string dtmiContent = await Resolve(toParseDtmi);

            if (!string.IsNullOrEmpty(dtmiContent))
            {
                // Assign the callback
                ModelParser parser = new ModelParser
                {
                    DtmiResolver = ResolveCallback
                };
                await parser.ParseAsync(new List <string> {
                    dtmiContent
                });

                Console.WriteLine("Parsing success!");
            }
        }
Пример #22
0
        static void RunOptions(Options opts)
        {
            Log.Ok("Simple DTDL Validator");

            if (opts.Interactive == true)
            {
                Log.Alert("Entering interactive mode");
                Interactive.Interactive i = new Interactive.Interactive();
                return;
            }

            DirectoryInfo dinfo = null;

            try
            {
                dinfo = new DirectoryInfo(opts.Directory);
            } catch (Exception e)
            {
                Log.Error($"Error accessing the target directory '{opts.Directory}': \n{e.Message}");
                return;
            }
            Log.Alert($"Validating *.{opts.Extension} files in folder '{dinfo.FullName}'.\nRecursive is set to {opts.Recursive}\n");
            if (dinfo.Exists == false)
            {
                Log.Error($"Specified directory '{opts.Directory}' does not exist: Exiting...");
                return;
            }
            else
            {
                SearchOption searchOpt = opts.Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
                var          files     = dinfo.EnumerateFiles($"*.{opts.Extension}", searchOpt);
                if (files.Count() == 0)
                {
                    Log.Alert("No matching files found. Exiting.");
                    return;
                }
                Dictionary <FileInfo, string> modelDict = new Dictionary <FileInfo, string>();
                int    count    = 0;
                string lastFile = "<none>";
                try
                {
                    foreach (FileInfo fi in files)
                    {
                        StreamReader r    = new StreamReader(fi.FullName);
                        string       dtdl = r.ReadToEnd(); r.Close();
                        modelDict.Add(fi, dtdl);
                        lastFile = fi.FullName;
                        count++;
                    }
                } catch (Exception e)
                {
                    Log.Error($"Could not read files. \nLast file read: {lastFile}\nError: \n{e.Message}");
                    return;
                }
                Log.Ok($"Read {count} files from specified directory");
                int errJson = 0;
                foreach (FileInfo fi in modelDict.Keys)
                {
                    modelDict.TryGetValue(fi, out string dtdl);
                    try
                    {
                        JsonDocument.Parse(dtdl);
                    } catch (Exception e)
                    {
                        Log.Error($"Invalid json found in file {fi.FullName}.\nJson parser error \n{e.Message}");
                        errJson++;
                    }
                }
                if (errJson > 0)
                {
                    Log.Error($"\nFound  {errJson} Json parsing errors");
                    return;
                }
                Log.Ok($"Validated JSON for all files - now validating DTDL");
                List <string> modelList = modelDict.Values.ToList <string>();
                ModelParser   parser    = new ModelParser();
                parser.DtmiResolver = Resolver;
                try
                {
                    IReadOnlyDictionary <Dtmi, DTEntityInfo> om = parser.ParseAsync(modelList).GetAwaiter().GetResult();
                    Log.Out("");
                    Log.Ok($"**********************************************");
                    Log.Ok($"** Validated all files - Your DTDL is valid **");
                    Log.Ok($"**********************************************");
                    Log.Out($"Found a total of {om.Keys.Count()} entities");
                }
                catch (ParsingException pe)
                {
                    Log.Error($"*** Error parsing models");
                    int derrcount = 1;
                    foreach (ParsingError err in pe.Errors)
                    {
                        Log.Error($"Error {derrcount}:");
                        Log.Error($"{err.Message}");
                        Log.Error($"Primary ID: {err.PrimaryID}");
                        Log.Error($"Secondary ID: {err.SecondaryID}");
                        Log.Error($"Property: {err.Property}\n");
                        derrcount++;
                    }
                    return;
                }
                catch (ResolutionException rex)
                {
                    Log.Error("Could not resolve required references");
                }
            }
        }
Пример #23
0
        public static async Task <int> Import(FileInfo modelFile, DirectoryInfo localRepo, bool strict)
        {
            if (localRepo == null)
            {
                localRepo = new DirectoryInfo(Path.GetFullPath("."));
            }

            try
            {
                RepoProvider      repoProvider  = new RepoProvider(localRepo.FullName);
                FileExtractResult extractResult = ParsingUtils.ExtractModels(modelFile);
                List <string>     models        = extractResult.Models;

                if (models.Count == 0)
                {
                    Outputs.WriteError("No models to import.");
                    return(ReturnCodes.ValidationError);
                }

                Outputs.WriteOut($"- Validating models conform to DTDL...");
                ModelParser parser = repoProvider.GetDtdlParser();
                await parser.ParseAsync(models);

                if (strict)
                {
                    foreach (string content in models)
                    {
                        string dtmi = ParsingUtils.GetRootId(content);
                        Outputs.WriteOut($"- Ensuring DTMIs namespace conformance for model \"{dtmi}\"...");
                        List <string> invalidSubDtmis = Validations.EnsureSubDtmiNamespace(content);
                        if (invalidSubDtmis.Count > 0)
                        {
                            Outputs.WriteError(
                                $"The following DTMI's do not start with the root DTMI namespace:{Environment.NewLine}{string.Join($",{Environment.NewLine}", invalidSubDtmis)}");
                            return(ReturnCodes.ValidationError);
                        }
                    }
                }

                foreach (string content in models)
                {
                    ModelImporter.Import(content, localRepo);
                }
            }
            catch (ResolutionException resolutionEx)
            {
                Outputs.WriteError(resolutionEx.Message);
                return(ReturnCodes.ResolutionError);
            }
            catch (RequestFailedException requestEx)
            {
                Outputs.WriteError(requestEx.Message);
                return(ReturnCodes.ResolutionError);
            }
            catch (ParsingException parsingEx)
            {
                IList <ParsingError> errors = parsingEx.Errors;
                string normalizedErrors     = string.Empty;
                foreach (ParsingError error in errors)
                {
                    normalizedErrors += $"{Environment.NewLine}{error.Message}";
                }

                Outputs.WriteError(normalizedErrors);
                return(ReturnCodes.ValidationError);
            }
            catch (IOException ioEx)
            {
                Outputs.WriteError(ioEx.Message);
                return(ReturnCodes.InvalidArguments);
            }
            catch (ArgumentException argEx)
            {
                Outputs.WriteError(argEx.Message);
                return(ReturnCodes.InvalidArguments);
            }
            catch (System.Text.Json.JsonException jsonEx)
            {
                Outputs.WriteError($"Parsing json-ld content. Details: {jsonEx.Message}");
                return(ReturnCodes.InvalidArguments);
            }

            return(ReturnCodes.Success);
        }
Пример #24
0
        /// <summary>
        /// Generates a DTDL JSON file from an OWL-based RDF file.
        /// </summary>
        /// <param name="rdfFile">RDF input file</param>
        /// <param name="dtdlFile">DTDL output file</param>
        private static void GenerateDTDL(FileInfo rdfFile, FileInfo dtdlFile)
        {
            try
            {
                Console.WriteLine("Reading file...");

                FileLoader.Load(_ontologyGraph, rdfFile.FullName);

                // Start looping through for each owl:Class
                foreach (OntologyClass owlClass in _ontologyGraph.OwlClasses)
                {
                    // Generate a DTMI for the owl:Class
                    string Id = GenerateDTMI(owlClass);

                    if (!String.IsNullOrEmpty(Id))
                    {
                        Console.WriteLine($"{owlClass.Resource.ToString()} -> {Id}");

                        // Create Interface
                        DtdlInterface dtdlInterface = new DtdlInterface
                        {
                            Id          = Id,
                            Type        = "Interface",
                            DisplayName = GetInterfaceDisplayName(owlClass),
                            Comment     = GetInterfaceComment(owlClass),
                            Description = "",
                            Contents    = new List <DtdlContents>()
                        };

                        // Use DTDL 'extends' for super classes
                        IEnumerable <OntologyClass> foundSuperClasses = owlClass.DirectSuperClasses;

                        if (foundSuperClasses.Any())
                        {
                            List <string> extendsList = new List <string>();

                            int extendsMax = 0;

                            foreach (var superClass in foundSuperClasses)
                            {
                                // DTDL v2 allows for a maximum of 2 extends. We ignore the other super classes
                                if (extendsMax < 2)
                                {
                                    string superClassId = GenerateDTMI(superClass);

                                    if (superClassId != null)
                                    {
                                        extendsList.Add(superClassId);

                                        extendsMax++;
                                    }
                                }
                            }

                            dtdlInterface.Extends = extendsList;
                        }

                        List <OntologyProperty> properties;

                        // Get list of properties which have this class as a domain
                        properties = owlClass.IsDomainOf.ToList();

                        foreach (var property in properties)
                        {
                            // An owl:ObjectProperty is used to create a DTDL relationship.
                            if (property.Types.First().ToString() == "http://www.w3.org/2002/07/owl#ObjectProperty")
                            {
                                Console.WriteLine($"  Found relationship: {property}");

                                // If IRI, parse out relationship name from IRI
                                if (property.ToString().Contains("#"))
                                {
                                    int index = property.ToString().LastIndexOf("#");
                                    property.AddLabel(property.ToString().Substring(index + 1));
                                }
                                else if (property.ToString().Contains("/"))
                                {
                                    int index = property.ToString().LastIndexOf("/");
                                    property.AddLabel(property.ToString().Substring(index + 1));
                                }

                                // Create relationship
                                DtdlContents dtdlRelationship = new DtdlContents
                                {
                                    Name        = Trim(property.ToString()),
                                    Type        = "Relationship",
                                    DisplayName = GetRelationshipDisplayName(property),
                                    Comment     = GetComment(property)
                                };

                                // DTDL only supports a single target Id.
                                var range = property.Ranges.FirstOrDefault();

                                if (range == null)
                                {
                                    // If no range is found, we omit the DTDL target property.
                                    // This allows any Interface to be the target.
                                    Console.WriteLine("    No target found.");
                                }
                                else
                                {
                                    Console.WriteLine($"    Found target: {range}");

                                    // Convert range to DTMI and add to DTDL relationship target.
                                    string target = GenerateDTMI(range);
                                    dtdlRelationship.Target = target;
                                }

                                // Add relationship to the Interface
                                dtdlInterface.Contents.Add(dtdlRelationship);
                            }

                            // An owl:DatatypeProperty is used to create a DTDL property.
                            if (property.Types.First().ToString() == "http://www.w3.org/2002/07/owl#DatatypeProperty")
                            {
                                Console.WriteLine($"  Found property: {property}");

                                // Create property
                                DtdlContents dtdlProperty = new DtdlContents
                                {
                                    Name     = Trim(property.ToString()),
                                    Type     = "Property",
                                    Schema   = _map[property.Ranges.FirstOrDefault().ToString()],
                                    Comment  = GetComment(property),
                                    Writable = true
                                };

                                // Add the Property to the Interface
                                dtdlInterface.Contents.Add(dtdlProperty);
                            }

                            // An owl:AnnotationProperty is used to create a DTDL property.
                            if (property.Types.First().ToString() == "http://www.w3.org/2002/07/owl#AnnotationProperty")
                            {
                                Console.WriteLine($"  Found property: {property}");

                                // Create property
                                DtdlContents dtdlProperty = new DtdlContents
                                {
                                    Name = Trim(property.ToString()),
                                    Type = "Property",
                                    // TODO: Lookup actual data type and create complex DTDL schema or map to DTDL semantic type
                                    Schema   = "float",
                                    Comment  = GetComment(property),
                                    Writable = true
                                };

                                // Add the Property to the Interface
                                dtdlInterface.Contents.Add(dtdlProperty);
                            }
                        }

                        // Add the DTDL context to the Interface
                        dtdlInterface.Context = _context;

                        // Add interface to the list of interfaces
                        _interfaceList.Add(dtdlInterface);
                    }
                }

                if (_interfaceList.Count == 0)
                {
                    throw new Exception("No OWL:Classes found.");
                }

                // Serialize to JSON
                var json = JsonConvert.SerializeObject(_interfaceList);

                // Save to file
                System.IO.File.WriteAllText(dtdlFile.ToString(), json);
                Console.WriteLine($"DTDL written to: {dtdlFile}");

                // Run DTDL validation
                Console.WriteLine("Validating DTDL...");

                ModelParser modelParser = new ModelParser();

                List <string> modelJson = new List <string>();

                modelJson.Add(json);

                IReadOnlyDictionary <Dtmi, DTEntityInfo> parseTask = modelParser.ParseAsync(modelJson).GetAwaiter().GetResult();
            }
            catch (ParsingException pe)
            {
                Console.WriteLine($"*** Error parsing models");

                int errCount = 1;

                foreach (ParsingError err in pe.Errors)
                {
                    Console.WriteLine($"Error {errCount}:");
                    Console.WriteLine($"{err.Message}");
                    Console.WriteLine($"Primary ID: {err.PrimaryID}");
                    Console.WriteLine($"Secondary ID: {err.SecondaryID}");
                    Console.WriteLine($"Property: {err.Property}\n");
                    errCount++;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine($"{e.Message}");
            }

            Console.WriteLine($"Finished!");
        }
Пример #25
0
        async Task RunAsync()
        {
            var httpClient         = new HttpClient();
            var digitalTwinsClient = new DigitalTwinsClient(_digitalTwinsInstanceUrl, _credential,
                                                            new DigitalTwinsClientOptions {
                Transport = new HttpClientTransport(httpClient)
            });

            _log.LogInformation("Reading model file {modelsFile}", _digitalTwinsModelsFile);
            var modelList = new[] { _digitalTwinsModelsFile }.Select(File.ReadAllText).ToList();
            var parser = new ModelParser();
            var parsed = await parser.ParseAsync(modelList);

            _log.LogInformation("Parsed {entityCount} entities", parsed.Keys.Count());

            var models = modelList
                         .SelectMany(JsonConvert.DeserializeObject <List <JObject> >)
                         .ToList();

            var(successCount, conflictCount) = (0, 0);
            foreach (var model in models)
            {
                var modelString = JsonConvert.SerializeObject(model);
                try
                {
                    await digitalTwinsClient.CreateModelsAsync(new[] { modelString });

                    successCount++;
                }
                catch (RequestFailedException e) when(e.Status == 409)  // Conflict
                {
                    // ignore
                    conflictCount++;
                }
            }

            _log.LogInformation("Uploaded {successCount} entities, skipped {conflictCount} entities", successCount,
                                conflictCount);

            var f = models.FirstOrDefault()?.GetValue("@id");

            if (f is null)
            {
                _log.LogInformation("Not creating twins");
                return;
            }

            DigitalTwinMetadata twinMetadata = new DigitalTwinMetadata
            {
                ModelId = f.ToString()
            };

            _log.LogInformation("Creating {numTwins} device twins of type {twinType}", NumTwins, twinMetadata.ModelId);

            var num = 0;

            Parallel.For(0, NumTwins, new ParallelOptions
            {
                MaxDegreeOfParallelism = 50
            }, i =>
            {
                var deviceId = $"contoso-device-id-{i.ToString("000000")}";
                digitalTwinsClient.CreateOrReplaceDigitalTwin(deviceId, new BasicDigitalTwin
                {
                    Metadata = twinMetadata
                });

                _log.LogDebug("Created twin {deviceId}", deviceId);
                var n = Interlocked.Increment(ref num);
                if (n % 100 == 0)
                {
                    _log.LogInformation("Created twin {n} of {numTwins}", n, NumTwins);
                }
            });
            _log.LogInformation("Created {numTwins} twins", NumTwins);
        }
Пример #26
0
        public DTDLParser(string root, string ext)
        {
            Log.Ok("Simple DTDL Validator");

            DirectoryInfo dinfo = null;

            try
            {
                dinfo = new DirectoryInfo(root);
            }
            catch (Exception e)
            {
                Log.Error($"Error accessing the target directory '{root}': \n{e.Message}");
                return;
            }
            Log.Alert($"Validating *.{ext} files in folder '{dinfo.FullName}'.");
            if (dinfo.Exists == false)
            {
                Log.Error($"Specified directory '{root}' does not exist: Exiting...");
                return;
            }
            else
            {
                SearchOption searchOpt = SearchOption.AllDirectories;
                var          files     = dinfo.EnumerateFiles($"*.{ext}", searchOpt);
                if (files.Count() == 0)
                {
                    Log.Alert("No matching files found. Exiting.");
                    return;
                }
                Dictionary <FileInfo, string> modelDict = new Dictionary <FileInfo, string>();
                int    count    = 0;
                string lastFile = "<none>";
                try
                {
                    foreach (FileInfo fi in files)
                    {
                        StreamReader r    = new StreamReader(fi.FullName);
                        string       dtdl = r.ReadToEnd(); r.Close();
                        modelDict.Add(fi, dtdl);
                        lastFile = fi.FullName;
                        count++;
                    }
                }
                catch (Exception e)
                {
                    Log.Error($"Could not read files. \nLast file read: {lastFile}\nError: \n{e.Message}");
                    return;
                }
                Log.Ok($"Read {count} files from specified directory");
                int errJson = 0;
                foreach (FileInfo fi in modelDict.Keys)
                {
                    modelDict.TryGetValue(fi, out string dtdl);
                    try
                    {
                        JsonDocument.Parse(dtdl);
                    }
                    catch (Exception e)
                    {
                        Log.Error($"Invalid json found in file {fi.FullName}.\nJson parser error \n{e.Message}");
                        errJson++;
                    }
                }
                if (errJson > 0)
                {
                    Log.Error($"\nFound  {errJson} Json parsing errors");
                    return;
                }
                Log.Ok($"Validated JSON for all files - now validating DTDL");
                List <string> modelList = modelDict.Values.ToList <string>();
                ModelParser   parser    = new ModelParser();
                parser.DtmiResolver = Resolver;
                try
                {
                    Stopwatch s = Stopwatch.StartNew();
                    DTDLObjectModel = parser.ParseAsync(modelList).GetAwaiter().GetResult();
                    s.Stop();
                    Log.Out("");
                    Log.Ok($"**********************************************");
                    Log.Ok($"** Validated all files - Your DTDL is valid **");
                    Log.Ok($"**********************************************");
                    Log.Out($"Found a total of {DTDLObjectModel.Keys.Count()} entities");
                    Log.Out($"Parsing took {s.ElapsedMilliseconds}ms");

                    DTDLInterfaces = new List <DTInterfaceInfo>();
                    IEnumerable <DTInterfaceInfo> ifenum = from entity in DTDLObjectModel.Values
                                                           where entity.EntityKind == DTEntityKind.Interface
                                                           select entity as DTInterfaceInfo;
                    DTDLInterfaces.AddRange(ifenum);
                }
                catch (ParsingException pe)
                {
                    Log.Error($"*** Error parsing models");
                    int derrcount = 1;
                    foreach (ParsingError err in pe.Errors)
                    {
                        Log.Error($"Error {derrcount}:");
                        Log.Error($"{err.Message}");
                        Log.Error($"Primary ID: {err.PrimaryID}");
                        Log.Error($"Secondary ID: {err.SecondaryID}");
                        Log.Error($"Property: {err.Property}\n");
                        derrcount++;
                    }
                    return;
                }
                catch (ResolutionException rex)
                {
                    Log.Error("Could not resolve required references");
                }
            }
        }
        public static async Task <Dictionary <string, DTDLCommandContainer> > ParseDTDLAndGetCommandsAsync(JArray dtdlArray)
        {
            if (dtdlArray == null)
            {
                throw new ArgumentNullException(nameof(dtdlArray));
            }

            Dictionary <string, DTDLCommandContainer> globalResult = new Dictionary <string, DTDLCommandContainer>();
            DTDLCommandContainer itemResult = null;

            ModelParser parser   = new ModelParser();
            JArray      contents = null;

            IReadOnlyDictionary <Dtmi, DTEntityInfo> parseResult = await parser.ParseAsync(dtdlArray.Select(i => JsonConvert.SerializeObject(i)));

            foreach (JObject dtdl in dtdlArray)
            {
                try
                {
                    //PROCESS COMPONENTS
                    await ProcessComponentsWithCommands(dtdlArray, dtdl, globalResult);

                    //CONTENT
                    if (!dtdl.ContainsKey("contents"))
                    {
                        throw new Exception("The DTDL model does not contain any 'content' property.");
                    }

                    contents = (JArray)dtdl["contents"];

                    itemResult = new DTDLCommandContainer {
                        ModelId = dtdl["@id"].Value <string>(), DTDL = dtdl
                    };
                    itemResult.Commands = ExtractCommands(contents);
                }
                catch (ParsingException pex)
                {
                    if (itemResult == null)
                    {
                        itemResult = new DTDLCommandContainer();
                    }

                    itemResult.ParsingErrors = pex.Errors.Select(i => i.Message);
                }
                catch (Exception ex)
                {
                    itemResult = null;
                }
                finally
                {
                    if (itemResult != null && itemResult.Commands != null)
                    {
                        if (!globalResult.ContainsKey(dtdl["@id"].Value <string>()))
                        {
                            globalResult.Add(dtdl["@id"].Value <string>(), itemResult);
                        }
                    }

                    itemResult = null;
                }
            }


            return(globalResult);
        }
Пример #28
0
        public async Task MT3620StarterKit_DTDL_With_Semantics_And_Units_OK()
        {
            string dtdlModelPath = @"./Tests/Avnet/mt3620starterkit-1.json";
            string modelId       = "dtmi:avnet:mt3620Starterkit;1";

            Assert.IsTrue(File.Exists(dtdlModelPath));

            var modelContainer = await DTDLHelper.GetModelsAndBuildDynamicContentAsync(modelId, dtdlModelPath);

            Assert.IsNotNull(modelContainer);

            var readablePropertiesGenerated = modelContainer.Where(i => i.Value != null && i.Value.DTDLGeneratedData != null && i.Value.DTDLGeneratedData.ReadableProperties != null);

            Assert.IsTrue(readablePropertiesGenerated.Any());

            var telemetriesGenerated = modelContainer.Where(i => i.Value != null && i.Value.DTDLGeneratedData != null && i.Value.DTDLGeneratedData.Telemetries != null);

            Assert.IsTrue(telemetriesGenerated.Any());

            var commandsGenerated = modelContainer.Where(i => i.Value != null && i.Value.DTDLGeneratedData != null && i.Value.DTDLGeneratedData.Commands != null);

            Assert.IsTrue(commandsGenerated.Any());

            var writablePropertiesGenerated = modelContainer.Where(i => i.Value != null && i.Value.DTDLGeneratedData != null && i.Value.DTDLGeneratedData.WritableProperties != null);

            Assert.IsTrue(writablePropertiesGenerated.Any());

            //Additional assets
            string stringModel = await File.ReadAllTextAsync(dtdlModelPath);

            Assert.IsTrue(!string.IsNullOrEmpty(stringModel));

            ModelParser modelParser = new ModelParser();
            IReadOnlyDictionary <Dtmi, DTEntityInfo> dtdl = await modelParser.ParseAsync(new List <string> {
                stringModel
            });

            Assert.IsNotNull(dtdl);
            Assert.IsNotNull(dtdl.Values);

            var interfaces = dtdl.Values.Where(i => i.EntityKind == DTEntityKind.Interface);

            Assert.IsNotNull(interfaces);

            //Telemetries
            var telemetriesParsed = dtdl.Values.Where(i => i.EntityKind == DTEntityKind.Telemetry);

            Assert.IsNotNull(telemetriesParsed);

            var generatedTelemetriesContainer = telemetriesGenerated.SingleOrDefault();

            Assert.IsNotNull(generatedTelemetriesContainer.Value);
            Assert.IsNotNull(generatedTelemetriesContainer.Value.DTDLGeneratedData);

            var generatedTelemetriesContent = generatedTelemetriesContainer.Value.DTDLGeneratedData.Telemetries;

            Assert.IsNotNull(generatedTelemetriesContent);
            Assert.IsTrue(generatedTelemetriesContent.Count() == telemetriesParsed.Count());

            //Commands
            var commandsParsed = dtdl.Values.Where(i => i.EntityKind == DTEntityKind.Command);

            Assert.IsNotNull(commandsParsed);

            var generatedCommandContainer = commandsGenerated.SingleOrDefault();

            Assert.IsNotNull(generatedCommandContainer.Value);
            Assert.IsNotNull(generatedCommandContainer.Value.DTDLGeneratedData);

            var generatedCommandsContent = generatedCommandContainer.Value.DTDLGeneratedData.Commands;

            Assert.IsNotNull(generatedCommandsContent);
            Assert.IsTrue(generatedCommandsContent.Count() == commandsParsed.Count());

            //Properties
            var propertiesParsed = dtdl.Values.Where(i => i.EntityKind == DTEntityKind.Property);

            Assert.IsNotNull(propertiesParsed);

            var generatedWritablePropertiesContainer = writablePropertiesGenerated.SingleOrDefault();

            Assert.IsNotNull(generatedWritablePropertiesContainer.Value);
            Assert.IsNotNull(generatedWritablePropertiesContainer.Value.DTDLGeneratedData);
            var generatedWritableContent = generatedWritablePropertiesContainer.Value.DTDLGeneratedData.WritableProperties;

            int propertiesCounter = generatedWritableContent != null ? generatedWritableContent.Count : 0;

            var generatedReadablePropertiesContainer = readablePropertiesGenerated.SingleOrDefault();

            Assert.IsNotNull(generatedReadablePropertiesContainer.Value);
            Assert.IsNotNull(generatedReadablePropertiesContainer.Value.DTDLGeneratedData);
            var generatedReadableContent = generatedReadablePropertiesContainer.Value.DTDLGeneratedData.ReadableProperties;

            propertiesCounter = propertiesCounter + ((generatedReadableContent != null) ? generatedReadableContent.Count : 0);

            Assert.IsTrue(propertiesCounter == propertiesParsed.Count());
        }