/// <summary>
 /// Initializes a new instance of the <see cref="ModelsRepositoryClientOptions"/> class.
 /// </summary>
 /// <param name="version">
 /// The <see cref="ServiceVersion"/> of the service API used when
 /// making requests.
 /// </param>
 /// <param name="dependencyResolution">The model dependency resolution options.</param>
 public ModelsRepositoryClientOptions(
     ServiceVersion version = LatestVersion,
     ModelDependencyResolution dependencyResolution = ModelDependencyResolution.Enabled)
 {
     DependencyResolution = dependencyResolution;
     Version = version;
 }
        public RepoProvider(string repoLocationUri,
                            ModelDependencyResolution dependencyResolution = ModelDependencyResolution.Enabled)
        {
            if (IsRelativePath(repoLocationUri))
            {
                repoLocationUri = Path.GetFullPath(repoLocationUri);
            }

            _repositoryClient = new ModelsRepositoryClient(new Uri(repoLocationUri),
                                                           new ModelsRepositoryClientOptions(dependencyResolution: dependencyResolution));
        }
Пример #3
0
 public virtual async Task <ModelResult> GetModelAsync(
     string dtmi, ModelDependencyResolution dependencyResolution = ModelDependencyResolution.Enabled, CancellationToken cancellationToken = default)
 {
     using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(ModelsRepositoryClient)}.{nameof(GetModel)}");
     scope.Start();
     try
     {
         return(await _repositoryHandler.ProcessAsync(dtmi, dependencyResolution, cancellationToken).ConfigureAwait(false));
     }
     catch (Exception ex)
     {
         scope.Failed(ex);
         throw;
     }
 }
Пример #4
0
        public virtual IDictionary <string, string> GetModels(
            IEnumerable <string> dtmis, ModelDependencyResolution dependencyResolution = ModelDependencyResolution.Enabled, CancellationToken cancellationToken = default)
        {
            using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(ModelsRepositoryClient)}.{nameof(GetModels)}");
            scope.Start();

            try
            {
                return(_repositoryHandler.Process(dtmis, dependencyResolution, cancellationToken));
            }
            catch (Exception ex)
            {
                scope.Failed(ex);
                throw;
            }
        }
Пример #5
0
        public FetchResult Fetch(string dtmi, Uri repositoryUri, ModelDependencyResolution dependencyResolution, CancellationToken cancellationToken = default)
        {
            using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(FileModelFetcher)}.{nameof(Fetch)}");
            scope.Start();

            try
            {
                var work = new Queue <string>();
                if (dependencyResolution == ModelDependencyResolution.TryFromExpanded)
                {
                    work.Enqueue(GetPath(dtmi, repositoryUri, true));
                }

                work.Enqueue(GetPath(dtmi, repositoryUri, false));

                string fnfError = string.Empty;
                while (work.Count != 0)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    string tryContentPath = work.Dequeue();
                    ModelsRepositoryEventSource.Instance.FetchingModelContent(tryContentPath);

                    if (File.Exists(tryContentPath))
                    {
                        return(new FetchResult
                        {
                            Definition = File.ReadAllText(tryContentPath, Encoding.UTF8),
                            Path = tryContentPath
                        });
                    }

                    ModelsRepositoryEventSource.Instance.ErrorFetchingModelContent(tryContentPath);
                    fnfError = string.Format(CultureInfo.InvariantCulture, StandardStrings.ErrorFetchingModelContent, tryContentPath);
                }

                throw new RequestFailedException(
                          $"{string.Format(CultureInfo.InvariantCulture, StandardStrings.GenericGetModelsError, dtmi)} {fnfError}",
                          new FileNotFoundException(fnfError));
            }
            catch (Exception ex)
            {
                scope.Failed(ex);
                throw;
            }
        }
        public FetchResult Fetch(
            string dtmi, Uri repositoryUri, ModelDependencyResolution dependencyResolution, CancellationToken cancellationToken = default)
        {
            using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(HttpModelFetcher)}.{nameof(Fetch)}");
            scope.Start();
            try
            {
                Queue <string> work = PrepareWork(dtmi, repositoryUri, dependencyResolution == ModelDependencyResolution.TryFromExpanded);

                string remoteFetchError = string.Empty;

                while (work.Count != 0)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    string tryContentPath = work.Dequeue();
                    ModelsRepositoryEventSource.Instance.FetchingModelContent(tryContentPath);

                    try
                    {
                        string content = EvaluatePath(tryContentPath, cancellationToken);
                        return(new FetchResult
                        {
                            Definition = content,
                            Path = tryContentPath
                        });
                    }
                    catch (Exception)
                    {
                        remoteFetchError =
                            $"{string.Format(CultureInfo.InvariantCulture, StandardStrings.GenericGetModelsError, dtmi)} " +
                            string.Format(CultureInfo.InvariantCulture, StandardStrings.ErrorFetchingModelContent, tryContentPath);
                    }
                }

                throw new RequestFailedException(remoteFetchError);
            }
            catch (Exception ex)
            {
                scope.Failed(ex);
                throw;
            }
        }
Пример #7
0
        private async Task <IDictionary <string, string> > ProcessAsync(
            IEnumerable <string> dtmis, bool async, ModelDependencyResolution dependencyResolution, CancellationToken cancellationToken)
        {
            var            processedModels = new Dictionary <string, string>();
            Queue <string> toProcessModels = PrepareWork(dtmis);

            while (toProcessModels.Count != 0)
            {
                cancellationToken.ThrowIfCancellationRequested();

                string targetDtmi = toProcessModels.Dequeue();
                if (processedModels.ContainsKey(targetDtmi))
                {
                    ModelsRepositoryEventSource.Instance.SkippingPreprocessedDtmi(targetDtmi);
                    continue;
                }

                ModelsRepositoryEventSource.Instance.ProcessingDtmi(targetDtmi);

                FetchResult result = async
                    ? await FetchAsync(targetDtmi, dependencyResolution, cancellationToken).ConfigureAwait(false)
                    : Fetch(targetDtmi, dependencyResolution, cancellationToken);

                if (result.FromExpanded)
                {
                    Dictionary <string, string> expanded = new ModelQuery(result.Definition).ListToDict();

                    foreach (KeyValuePair <string, string> kvp in expanded)
                    {
                        if (!processedModels.ContainsKey(kvp.Key))
                        {
                            processedModels.Add(kvp.Key, kvp.Value);
                        }
                    }

                    continue;
                }

                ModelMetadata metadata = new ModelQuery(result.Definition).ParseModel();

                if (dependencyResolution >= ModelDependencyResolution.Enabled)
                {
                    IList <string> dependencies = metadata.Dependencies;

                    if (dependencies.Count > 0)
                    {
                        ModelsRepositoryEventSource.Instance.DiscoveredDependencies(string.Join("\", \"", dependencies));
                    }

                    foreach (string dep in dependencies)
                    {
                        toProcessModels.Enqueue(dep);
                    }
                }

                string parsedDtmi = metadata.Id;
                if (!parsedDtmi.Equals(targetDtmi, StringComparison.Ordinal))
                {
                    ModelsRepositoryEventSource.Instance.IncorrectDtmiCasing(targetDtmi, parsedDtmi);
                    string formatErrorMsg =
                        $"{string.Format(CultureInfo.InvariantCulture, StandardStrings.GenericGetModelsError, targetDtmi)} " +
                        string.Format(CultureInfo.InvariantCulture, StandardStrings.IncorrectDtmiCasing, targetDtmi, parsedDtmi);

                    throw new RequestFailedException(formatErrorMsg, new FormatException(formatErrorMsg));
                }

                processedModels.Add(targetDtmi, result.Definition);
            }

            return(processedModels);
        }
Пример #8
0
 public IDictionary <string, string> Process(IEnumerable <string> dtmis, ModelDependencyResolution dependencyResolution, CancellationToken cancellationToken)
 {
     return(ProcessAsync(dtmis, false, dependencyResolution, cancellationToken).EnsureCompleted());
 }
Пример #9
0
 public Task <IDictionary <string, string> > ProcessAsync(IEnumerable <string> dtmis, ModelDependencyResolution dependencyResolution, CancellationToken cancellationToken)
 {
     return(ProcessAsync(dtmis, true, dependencyResolution, cancellationToken));
 }
Пример #10
0
 public Task <FetchResult> FetchAsync(string dtmi, Uri repositoryUri, ModelDependencyResolution dependencyResolution, CancellationToken cancellationToken = default)
 {
     return(Task.FromResult(Fetch(dtmi, repositoryUri, dependencyResolution, cancellationToken)));
 }
Пример #11
0
 public async Task <IDictionary <string, string> > ProcessAsync(string dtmi, ModelDependencyResolution dependencyResolution, CancellationToken cancellationToken)
 {
     return(await ProcessAsync(new List <string> {
         dtmi
     }, true, dependencyResolution, cancellationToken).ConfigureAwait(false));
 }
Пример #12
0
 private FetchResult Fetch(string dtmi, ModelDependencyResolution dependencyResolution, CancellationToken cancellationToken)
 {
     return(_modelFetcher.Fetch(dtmi, _repositoryUri, dependencyResolution, cancellationToken));
 }
        private async Task <ModelResult> ProcessAsync(
            string dtmi, bool async, ModelDependencyResolution dependencyResolution, CancellationToken cancellationToken)
        {
            Queue <string> toProcessModels = PrepareWork(dtmi);
            var            processedModels = new Dictionary <string, string>();

            // If ModelDependencyResolution.Enabled is requested the client will first attempt to fetch
            // metadata.json content from the target repository. The metadata object includes supported features
            // of the repository.
            // If the metadata indicates expanded models are available. The client will try to fetch pre-computed model
            // dependencies using .expanded.json.
            // If the model expanded form does not exist fall back to computing model dependencies just-in-time.
            if (dependencyResolution == ModelDependencyResolution.Enabled && _metadataScheduler.ShouldFetchMetadata())
            {
                ModelsRepositoryMetadata repositoryMetadata = async
                    ? await FetchMetadataAsync(cancellationToken).ConfigureAwait(false)
                    : FetchMetadata(cancellationToken);

                if (repositoryMetadata != null &&
                    repositoryMetadata.Features != null &&
                    repositoryMetadata.Features.Expanded)
                {
                    _repositorySupportsExpanded = true;
                }
                else
                {
                    _repositorySupportsExpanded = false;
                }

                _metadataScheduler.MarkAsFetched();
            }

            // Covers case when the repository supports expanded but dependency resolution is disabled.
            bool tryFromExpanded = (dependencyResolution == ModelDependencyResolution.Enabled) && _repositorySupportsExpanded;

            while (toProcessModels.Count != 0)
            {
                cancellationToken.ThrowIfCancellationRequested();

                string targetDtmi = toProcessModels.Dequeue();
                if (processedModels.ContainsKey(targetDtmi))
                {
                    ModelsRepositoryEventSource.Instance.SkippingPreprocessedDtmi(targetDtmi);
                    continue;
                }

                ModelsRepositoryEventSource.Instance.ProcessingDtmi(targetDtmi);

                FetchModelResult result = async
                    ? await FetchModelAsync(targetDtmi, tryFromExpanded, cancellationToken).ConfigureAwait(false)
                    : FetchModel(targetDtmi, tryFromExpanded, cancellationToken);

                if (result.FromExpanded)
                {
                    Dictionary <string, string> expanded = new ModelQuery(result.Definition).ListToDict();

                    foreach (KeyValuePair <string, string> kvp in expanded)
                    {
                        if (!processedModels.ContainsKey(kvp.Key))
                        {
                            processedModels.Add(kvp.Key, kvp.Value);
                        }
                    }

                    continue;
                }

                ModelMetadata metadata = new ModelQuery(result.Definition).ParseModel();

                if (dependencyResolution >= ModelDependencyResolution.Enabled)
                {
                    IList <string> dependencies = metadata.Dependencies;

                    if (dependencies.Count > 0)
                    {
                        ModelsRepositoryEventSource.Instance.DiscoveredDependencies(string.Join("\", \"", dependencies));
                    }

                    foreach (string dep in dependencies)
                    {
                        toProcessModels.Enqueue(dep);
                    }
                }

                string parsedDtmi = metadata.Id;
                if (!parsedDtmi.Equals(targetDtmi, StringComparison.Ordinal))
                {
                    ModelsRepositoryEventSource.Instance.IncorrectDtmi(targetDtmi, parsedDtmi);
                    string formatErrorMsg =
                        $"{string.Format(CultureInfo.InvariantCulture, StandardStrings.GenericGetModelsError, targetDtmi)} " +
                        string.Format(CultureInfo.InvariantCulture, StandardStrings.IncorrectDtmi, targetDtmi, parsedDtmi);

                    throw new RequestFailedException(formatErrorMsg, new FormatException(formatErrorMsg));
                }

                processedModels.Add(targetDtmi, result.Definition);
            }

            return(new ModelResult(processedModels));
        }
 public ModelResult Process(string dtmi, ModelDependencyResolution dependencyResolution, CancellationToken cancellationToken)
 {
     return(ProcessAsync(dtmi, false, dependencyResolution, cancellationToken).EnsureCompleted());
 }
 public async Task <ModelResult> ProcessAsync(string dtmi, ModelDependencyResolution dependencyResolution, CancellationToken cancellationToken)
 {
     return(await ProcessAsync(dtmi, true, dependencyResolution, cancellationToken).ConfigureAwait(false));
 }
        public async Task <FetchResult> FetchAsync(
            string dtmi, Uri repositoryUri, ModelDependencyResolution dependencyResolution, CancellationToken cancellationToken = default)
        {
            using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(HttpModelFetcher)}.{nameof(Fetch)}");
            scope.Start();
            try
            {
                Queue <string> work = PrepareWork(dtmi, repositoryUri, dependencyResolution == ModelDependencyResolution.TryFromExpanded);

                string remoteFetchError = string.Empty;
                RequestFailedException requestFailedExceptionThrown = null;
                Exception genericExceptionThrown = null;

                while (work.Count != 0)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    string tryContentPath = work.Dequeue();
                    ModelsRepositoryEventSource.Instance.FetchingModelContent(tryContentPath);

                    try
                    {
                        string content = await EvaluatePathAsync(tryContentPath, cancellationToken).ConfigureAwait(false);

                        return(new FetchResult()
                        {
                            Definition = content,
                            Path = tryContentPath
                        });
                    }
                    catch (RequestFailedException ex)
                    {
                        requestFailedExceptionThrown = ex;
                    }
                    catch (Exception ex)
                    {
                        genericExceptionThrown = ex;
                    }

                    if (genericExceptionThrown != null || requestFailedExceptionThrown != null)
                    {
                        remoteFetchError =
                            $"{string.Format(CultureInfo.InvariantCulture, StandardStrings.GenericGetModelsError, dtmi)} " +
                            string.Format(CultureInfo.InvariantCulture, StandardStrings.ErrorFetchingModelContent, tryContentPath);
                    }
                }

                if (requestFailedExceptionThrown != null)
                {
                    throw new RequestFailedException(
                              requestFailedExceptionThrown.Status,
                              remoteFetchError,
                              requestFailedExceptionThrown.ErrorCode,
                              requestFailedExceptionThrown);
                }
                else
                {
                    throw new RequestFailedException(
                              (int)HttpStatusCode.BadRequest,
                              remoteFetchError,
                              null,
                              genericExceptionThrown);
                }
            }
            catch (Exception ex)
            {
                scope.Failed(ex);
                throw;
            }
        }
Пример #17
0
 public IDictionary <string, string> Process(string dtmi, ModelDependencyResolution dependencyResolution, CancellationToken cancellationToken)
 {
     return(ProcessAsync(new List <string> {
         dtmi
     }, false, dependencyResolution, cancellationToken).EnsureCompleted());
 }