Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename Repo to Repository and minor changes / Import samples project #18986

Merged
merged 7 commits into from
Feb 24, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Iot.ModelsRepository.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Core.TestFramework", "..\..\core\Azure.Core.TestFramework\src\Azure.Core.TestFramework.csproj", "{1FC8A3EA-3C0D-4DDF-B710-A7091F2CEBB1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModelsRepositoryClientSamples", "samples\ModelsRepositoryClientSamples\ModelsRepositoryClientSamples.csproj", "{51E4AB9E-46F3-450C-B52A-C4C6378E8BA3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -27,6 +29,10 @@ Global
{1FC8A3EA-3C0D-4DDF-B710-A7091F2CEBB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1FC8A3EA-3C0D-4DDF-B710-A7091F2CEBB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1FC8A3EA-3C0D-4DDF-B710-A7091F2CEBB1}.Release|Any CPU.Build.0 = Release|Any CPU
{51E4AB9E-46F3-450C-B52A-C4C6378E8BA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{51E4AB9E-46F3-450C-B52A-C4C6378E8BA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{51E4AB9E-46F3-450C-B52A-C4C6378E8BA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{51E4AB9E-46F3-450C-B52A-C4C6378E8BA3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net5.0</TargetFrameworks>
</PropertyGroup>

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1;net5.0</TargetFramework>
<RootNamespace>Azure.Iot.ModelsRepository.Samples</RootNamespace>
</PropertyGroup>

<ItemGroup>
<AdditionalFiles Include="..\readme.md" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Azure.Iot.ModelsRepository.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Azure.Core.Diagnostics;
using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Net;
using System.Threading.Tasks;

namespace Azure.Iot.ModelsRepository.Samples
{
public class Program
{
public static async Task Main(string[] args)
{
using AzureEventSourceListener listener = AzureEventSourceListener.CreateTraceLogger(EventLevel.Verbose);
azabbasi marked this conversation as resolved.
Show resolved Hide resolved

await ResolveExistingAsync();
await TryResolveButNotFoundAsync();
}

private static async Task ResolveExistingAsync()
{
var dtmi = "dtmi:com:example:TemperatureController;1";
var client = new ModelsRepositoryClient();

IDictionary<string, string> models = await client.ResolveAsync(dtmi).ConfigureAwait(false);

Console.WriteLine($"{dtmi} resolved in {models.Count} interfaces.");
}

private static async Task TryResolveButNotFoundAsync()
{
var dtmi = "dtmi:com:example:NotFound;1";
var client = new ModelsRepositoryClient();

try
{
IDictionary<string, string> models = await client.ResolveAsync(dtmi).ConfigureAwait(false);
Console.WriteLine($"{dtmi} resolved in {models.Count} interfaces.");
}
catch (RequestFailedException ex) when (ex.Status == (int)HttpStatusCode.NotFound)
{
Console.WriteLine($"{dtmi} was not found in the default public models repository: {ex.Message}");
}
}
}
}
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal class LocalModelFetcher : IModelFetcher
private readonly bool _tryExpanded;
private readonly ClientDiagnostics _clientDiagnostics;

public LocalModelFetcher(ClientDiagnostics clientDiagnostics, ModelsRepoClientOptions clientOptions)
public LocalModelFetcher(ClientDiagnostics clientDiagnostics, ModelsRepositoryClientOptions clientOptions)
{
_clientDiagnostics = clientDiagnostics;
_tryExpanded = clientOptions.DependencyResolution == DependencyResolutionOption.TryFromExpanded;
Expand Down Expand Up @@ -54,7 +54,7 @@ public FetchResult Fetch(string dtmi, Uri repositoryUri, CancellationToken cance
cancellationToken.ThrowIfCancellationRequested();

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

if (File.Exists(tryContentPath))
{
Expand All @@ -65,7 +65,7 @@ public FetchResult Fetch(string dtmi, Uri repositoryUri, CancellationToken cance
};
}

ModelsRepoEventSource.Instance.ErrorFetchingModelContent(tryContentPath);
ModelsRepositoryEventSource.Instance.ErrorFetchingModelContent(tryContentPath);
fnfError = string.Format(CultureInfo.CurrentCulture, ServiceStrings.ErrorFetchingModelContent, tryContentPath);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -23,7 +24,7 @@ internal class RemoteModelFetcher : IModelFetcher
private readonly ClientDiagnostics _clientDiagnostics;
private readonly bool _tryExpanded;

public RemoteModelFetcher(ClientDiagnostics clientDiagnostics, ModelsRepoClientOptions clientOptions)
public RemoteModelFetcher(ClientDiagnostics clientDiagnostics, ModelsRepositoryClientOptions clientOptions)
{
_pipeline = CreatePipeline(clientOptions);
_tryExpanded = clientOptions.DependencyResolution == DependencyResolutionOption.TryFromExpanded;
Expand All @@ -45,7 +46,7 @@ public FetchResult Fetch(string dtmi, Uri repositoryUri, CancellationToken cance
cancellationToken.ThrowIfCancellationRequested();

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

try
{
Expand Down Expand Up @@ -82,13 +83,15 @@ public async Task<FetchResult> FetchAsync(string dtmi, Uri repositoryUri, Cancel
Queue<string> work = PrepareWork(dtmi, repositoryUri);

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

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

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

try
{
Expand All @@ -99,15 +102,39 @@ public async Task<FetchResult> FetchAsync(string dtmi, Uri repositoryUri, Cancel
Path = tryContentPath
};
}
catch (Exception)
catch (RequestFailedException ex)
{
requestFailedExceptionThrown = ex;
}
catch (Exception ex)
{
genericExceptionThrown = ex;
}

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

throw new RequestFailedException(remoteFetchError);
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)
{
Expand Down Expand Up @@ -219,7 +246,7 @@ private static async Task<string> GetContentAsync(Stream content, CancellationTo
return root.GetRawText();
}

private static HttpPipeline CreatePipeline(ModelsRepoClientOptions options)
private static HttpPipeline CreatePipeline(ModelsRepositoryClientOptions options)
{
return HttpPipelineBuilder.Build(options);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,84 +6,56 @@
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using Azure.Core;
using Azure.Core.Pipeline;

namespace Azure.Iot.ModelsRepository
{
/// <summary>
/// The ModelsRepoClient class supports operations against DTDL model repositories following the
/// The ModelsRepositoryClient class supports operations against DTDL model repositories following the
/// conventions of the Azure IoT Plug and Play Models repository.
/// </summary>
public class ModelsRepoClient
public class ModelsRepositoryClient
{
private readonly RepositoryHandler _repositoryHandler;
private readonly ClientDiagnostics _clientDiagnostics;
private readonly ModelsRepositoryClientOptions _clientOptions;

/// <summary>
/// Initializes the ModelsRepoClient with default client options while pointing to
/// Initializes the ModelsRepositoryClient with default client options while pointing to
/// the Azure IoT Plug and Play Models repository https://devicemodels.azure.com for resolution.
/// </summary>
public ModelsRepoClient() : this(new Uri(DefaultModelsRepository), new ModelsRepoClientOptions()) { }
public ModelsRepositoryClient() : this(DefaultModelsRepository, new ModelsRepositoryClientOptions()) { }

/// <summary>
/// Initializes the ModelsRepoClient with default client options while pointing to
/// a custom <paramref name="repositoryUri"/> for resolution.
/// </summary>
/// <param name="repositoryUri">
/// The model repository Uri value. This can be a remote endpoint or local directory.
/// </param>
public ModelsRepoClient(Uri repositoryUri) : this(repositoryUri, new ModelsRepoClientOptions()) { }

/// <summary>
/// Initializes the ModelsRepoClient with custom client <paramref name="options"/> while pointing to
/// Initializes the ModelsRepositoryClient with custom client <paramref name="options"/> while pointing to
/// the Azure IoT Plug and Play Model repository https://devicemodels.azure.com for resolution.
/// </summary>
/// <param name="options">
/// ModelsRepoClientOptions to configure resolution and client behavior.
/// ModelsRepositoryClientOptions to configure resolution and client behavior.
/// </param>
public ModelsRepoClient(ModelsRepoClientOptions options) : this(new Uri(DefaultModelsRepository), options) { }
public ModelsRepositoryClient(ModelsRepositoryClientOptions options) : this(DefaultModelsRepository, options) { }

/// <summary>
/// Initializes the ModelsRepoClient with default client options while pointing to
/// a custom <paramref name="repositoryUriStr"/> for resolution.
/// </summary>
/// <param name="repositoryUriStr">
/// The model repository Uri in string format. This can be a remote endpoint or local directory.
/// </param>
public ModelsRepoClient(string repositoryUriStr) : this(repositoryUriStr, new ModelsRepoClientOptions()) { }

/// <summary>
/// Initializes the ModelsRepoClient with custom client <paramref name="options"/> while pointing to
/// a custom <paramref name="repositoryUriStr"/> for resolution.
/// </summary>
/// <param name="repositoryUriStr">
/// The model repository Uri in string format. This can be a remote endpoint or local directory.
/// </param>
/// <param name="options">
/// ModelsRepoClientOptions to configure resolution and client behavior.
/// </param>
public ModelsRepoClient(string repositoryUriStr, ModelsRepoClientOptions options)
: this(new Uri(repositoryUriStr), options) { }

/// <summary>
/// Initializes the ModelsRepoClient with custom client <paramref name="options"/> while pointing to
/// Initializes the ModelsRepositoryClient with custom client <paramref name="options"/> while pointing to
/// a custom <paramref name="repositoryUri"/> for resolution.
/// </summary>
/// <param name="repositoryUri">
/// The model repository Uri. This can be a remote endpoint or local directory.
/// </param>
/// <param name="options">
/// ModelsRepoClientOptions to configure resolution and client behavior.
/// ModelsRepositoryClientOptions to configure resolution and client behavior.
/// </param>
public ModelsRepoClient(Uri repositoryUri, ModelsRepoClientOptions options)
public ModelsRepositoryClient(Uri repositoryUri, ModelsRepositoryClientOptions options = default)
{
Argument.AssertNotNull(options, nameof(options));
if (options == null)
{
options = new ModelsRepositoryClientOptions();
}

ClientOptions = options;
RepositoryUri = repositoryUri;
_clientOptions = options;
_clientDiagnostics = new ClientDiagnostics(options);
_repositoryHandler = new RepositoryHandler(RepositoryUri, _clientDiagnostics, ClientOptions);
_repositoryHandler = new RepositoryHandler(RepositoryUri, _clientDiagnostics, _clientOptions);
}

/// <summary>
Expand All @@ -102,7 +74,7 @@ public ModelsRepoClient(Uri repositoryUri, ModelsRepoClientOptions options)
Justification = "<Pending>")]
public virtual async Task<IDictionary<string, string>> ResolveAsync(string dtmi, CancellationToken cancellationToken = default)
{
using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(ModelsRepoClient)}.{nameof(Resolve)}");
using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(ModelsRepositoryClient)}.{nameof(Resolve)}");
scope.Start();
try
{
Expand Down Expand Up @@ -131,7 +103,7 @@ public virtual async Task<IDictionary<string, string>> ResolveAsync(string dtmi,
Justification = "<Pending>")]
public virtual IDictionary<string, string> Resolve(string dtmi, CancellationToken cancellationToken = default)
{
using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(ModelsRepoClient)}.{nameof(Resolve)}");
using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(ModelsRepositoryClient)}.{nameof(Resolve)}");
scope.Start();

try
Expand All @@ -158,7 +130,7 @@ public virtual IDictionary<string, string> Resolve(string dtmi, CancellationToke
[SuppressMessage("Usage", "AZC0015:Unexpected client method return type.", Justification = "<Pending>")]
public virtual async Task<IDictionary<string, string>> ResolveAsync(IEnumerable<string> dtmis, CancellationToken cancellationToken = default)
{
using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(ModelsRepoClient)}.{nameof(Resolve)}");
using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(ModelsRepositoryClient)}.{nameof(Resolve)}");
scope.Start();

try
Expand All @@ -185,7 +157,7 @@ public virtual async Task<IDictionary<string, string>> ResolveAsync(IEnumerable<
[SuppressMessage("Usage", "AZC0015:Unexpected client method return type.", Justification = "<Pending>")]
public virtual IDictionary<string, string> Resolve(IEnumerable<string> dtmis, CancellationToken cancellationToken = default)
{
using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(ModelsRepoClient)}.{nameof(Resolve)}");
using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(ModelsRepositoryClient)}.{nameof(Resolve)}");
scope.Start();

try
Expand All @@ -205,18 +177,13 @@ public virtual IDictionary<string, string> Resolve(IEnumerable<string> dtmis, Ca
public static bool IsValidDtmi(string dtmi) => DtmiConventions.IsDtmi(dtmi);

/// <summary>
/// Gets the Uri associated with the ModelsRepoClient instance.
/// Gets the Uri associated with the ModelsRepositoryClient instance.
/// </summary>
public Uri RepositoryUri { get; }

/// <summary>
/// Gets the ModelsRepoClientOptions associated with the ModelsRepoClient instance.
/// </summary>
public ModelsRepoClientOptions ClientOptions { get; }

/// <summary>
/// The global Azure IoT Models Repository endpoint used by default.
/// </summary>
public static string DefaultModelsRepository => ModelRepositoryConstants.DefaultModelsRepository;
public static Uri DefaultModelsRepository => new Uri(ModelRepositoryConstants.DefaultModelsRepository);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Azure.Iot.ModelsRepository
/// <summary>
/// Options that allow configuration of requests sent to the ModelRepositoryService.
/// </summary>
public class ModelsRepoClientOptions : ClientOptions
public class ModelsRepositoryClientOptions : ClientOptions
{
internal const ServiceVersion LatestVersion = ServiceVersion.V2021_02_11;

Expand All @@ -33,14 +33,14 @@ public enum ServiceVersion
public ServiceVersion Version { get; }

/// <summary>
/// Initializes a new instance of the <see cref="ModelsRepoClientOptions"/> class.
/// 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="resolutionOption">The dependency processing options.</param>
public ModelsRepoClientOptions(
public ModelsRepositoryClientOptions(
ServiceVersion version = LatestVersion,
DependencyResolutionOption resolutionOption = DependencyResolutionOption.Enabled)
{
Expand Down
Loading