Skip to content

Commit

Permalink
inherit from DirectMethodRequest
Browse files Browse the repository at this point in the history
  • Loading branch information
abhipsaMisra committed May 2, 2023
1 parent 9733d3f commit 620b7c6
Show file tree
Hide file tree
Showing 13 changed files with 48 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ namespace Microsoft.Azure.Devices.Client.Samples
public class EdgeModuleMethodSample
{
private readonly IotHubModuleClient _moduleClient;
private string _deviceId;
private string _moduleId;
private readonly string _deviceId;
private readonly string _moduleId;
private readonly TimeSpan? _maxRunTime;

public EdgeModuleMethodSample(IotHubModuleClient moduleClient, string deviceId, string moduleId, TimeSpan? maxRunTime)
Expand Down Expand Up @@ -54,7 +54,7 @@ public async Task RunSampleAsync()
}

// Invoking a direct method request to the module itself.
var directMethodRequest = new DirectMethodRequest("ModuleToModule");
var directMethodRequest = new EdgeModuleDirectMethodRequest("ModuleToModule");
await _moduleClient.InvokeMethodAsync(_deviceId, _moduleId, directMethodRequest, cts.Token);

// You can unsubscribe from receiving a callback for direct methods by setting a null callback handler.
Expand Down
13 changes: 4 additions & 9 deletions iothub/device/src/DirectMethod/DirectMethodRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@ internal DirectMethodRequest()
/// <summary>
/// Initialize an instance of this class.
/// </summary>
/// <param name="methodName">The method name to invoke.</param>
/// <remarks>
/// A direct method request can only be made by the service or a module;
/// a device client app will not need to instantiate this class.
/// This class can be inherited from and set by unit tests for mocking purposes.
/// </remarks>
public DirectMethodRequest(string methodName)
/// <param name="methodName">The method name to invoke.</param>
protected internal DirectMethodRequest(string methodName)
{
MethodName = methodName;
}
Expand Down Expand Up @@ -84,12 +83,8 @@ public DirectMethodRequest(string methodName)
/// <summary>
/// The direct method payload.
/// </summary>
/// <remarks>
/// The direct method request payload is to be set by the client application only when using <see cref="IotHubModuleClient"/>
/// to invoke a direct method on an edge device or on an edge module.
/// </remarks>
[JsonProperty("payload", NullValueHandling = NullValueHandling.Include)]
public byte[] Payload { get; set; }
protected internal byte[] Payload { get; set; }

/// <summary>
/// The convention to use with the direct method payload.
Expand Down
25 changes: 25 additions & 0 deletions iothub/device/src/DirectMethod/EdgeModuleDirectMethodRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.Azure.Devices.Client
{
/// <summary>
/// Parameters to execute a direct method on an edge device or an edge module by an <see cref="IotHubModuleClient"/>.
/// </summary>
public class EdgeModuleDirectMethodRequest : DirectMethodRequest
{
/// <summary>
/// A direct method request to be initialized by the client application when using an <see cref="IotHubModuleClient"/> for invoking
/// a direct method on an edge device or an edge module connected to the same edge hub.
/// </summary>
/// <param name="methodName">The method name to invoke.</param>
/// <param name="payload">The direct method payload.</param>
public EdgeModuleDirectMethodRequest(string methodName, object payload = default)
: base(methodName)
{
Payload = payload == null
? null
: PayloadConvention.GetObjectBytes(payload);
}
}
}
2 changes: 1 addition & 1 deletion iothub/device/src/IotHubClientOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public IotHubClientOptions(IotHubClientTransportSettings transportSettings)
/// <remarks>
/// All <see cref="IotHubDeviceClient"/> file upload operations take place over HTTP regardless of the configured protocol.
/// Additionally, all <see cref="IotHubModuleClient"/> direct method invoking operations (such as
/// <see cref="IotHubModuleClient.InvokeMethodAsync(string, DirectMethodRequest, System.Threading.CancellationToken)"/>)
/// <see cref="IotHubModuleClient.InvokeMethodAsync(string, EdgeModuleDirectMethodRequest, System.Threading.CancellationToken)"/>)
/// take place over HTTP as well. The settings provided in this class will be used for all these operations.
/// </remarks>
public IotHubClientHttpSettings HttpOperationTransportSettings { get; set; } = new IotHubClientHttpSettings();
Expand Down
6 changes: 3 additions & 3 deletions iothub/device/src/IotHubModuleClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ public async Task SendMessagesToRouteAsync(string outputName, IEnumerable<Teleme
/// <exception cref="OperationCanceledException">The operation has been canceled.</exception>
/// <exception cref="IotHubClientException">An error occured when communicating with IoT hub service.</exception>
/// <exception cref="ObjectDisposedException">The client has been disposed.</exception>
public Task<DirectMethodResponse> InvokeMethodAsync(string deviceId, DirectMethodRequest methodRequest, CancellationToken cancellationToken = default)
public Task<DirectMethodResponse> InvokeMethodAsync(string deviceId, EdgeModuleDirectMethodRequest methodRequest, CancellationToken cancellationToken = default)
{
Argument.AssertNotNullOrWhiteSpace(deviceId, nameof(deviceId));
Argument.AssertNotNull(methodRequest, nameof(methodRequest));
Expand Down Expand Up @@ -235,7 +235,7 @@ public Task<DirectMethodResponse> InvokeMethodAsync(string deviceId, DirectMetho
/// <exception cref="OperationCanceledException">The operation has been canceled.</exception>
/// <exception cref="IotHubClientException">An error occured when communicating with IoT hub service.</exception>
/// <exception cref="ObjectDisposedException">The client has been disposed.</exception>
public Task<DirectMethodResponse> InvokeMethodAsync(string deviceId, string moduleId, DirectMethodRequest methodRequest, CancellationToken cancellationToken = default)
public Task<DirectMethodResponse> InvokeMethodAsync(string deviceId, string moduleId, EdgeModuleDirectMethodRequest methodRequest, CancellationToken cancellationToken = default)
{
Argument.AssertNotNullOrWhiteSpace(deviceId, nameof(deviceId));
Argument.AssertNotNullOrWhiteSpace(moduleId, nameof(moduleId));
Expand All @@ -245,7 +245,7 @@ public Task<DirectMethodResponse> InvokeMethodAsync(string deviceId, string modu
return InvokeMethodAsync(GetModuleMethodUri(deviceId, moduleId), methodRequest, cancellationToken);
}

private async Task<DirectMethodResponse> InvokeMethodAsync(Uri uri, DirectMethodRequest methodRequest, CancellationToken cancellationToken = default)
private async Task<DirectMethodResponse> InvokeMethodAsync(Uri uri, EdgeModuleDirectMethodRequest methodRequest, CancellationToken cancellationToken = default)
{
methodRequest.PayloadConvention = _clientOptions.PayloadConvention;
DirectMethodResponse result = await InnerHandler.InvokeMethodAsync(methodRequest, uri, cancellationToken).ConfigureAwait(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ await ValidateStateAndPerformOperationAsync(
}
}

public override async Task<DirectMethodResponse> InvokeMethodAsync(DirectMethodRequest methodInvokeRequest, Uri uri, CancellationToken cancellationToken)
public override async Task<DirectMethodResponse> InvokeMethodAsync(EdgeModuleDirectMethodRequest methodInvokeRequest, Uri uri, CancellationToken cancellationToken)
{
if (Logging.IsEnabled)
Logging.Enter(this, methodInvokeRequest.RequestId, uri, cancellationToken, nameof(InvokeMethodAsync));
Expand Down
2 changes: 1 addition & 1 deletion iothub/device/src/Pipeline/DefaultDelegatingHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public virtual Task CompleteFileUploadAsync(FileUploadCompletionNotification not
return NextHandler?.CompleteFileUploadAsync(notification, cancellationToken) ?? Task.CompletedTask;
}

public virtual Task<DirectMethodResponse> InvokeMethodAsync(DirectMethodRequest methodInvokeRequest, Uri uri, CancellationToken cancellationToken)
public virtual Task<DirectMethodResponse> InvokeMethodAsync(EdgeModuleDirectMethodRequest methodInvokeRequest, Uri uri, CancellationToken cancellationToken)
{
ThrowIfDisposed();
return NextHandler?.InvokeMethodAsync(methodInvokeRequest, uri, cancellationToken) ?? Task.FromResult<DirectMethodResponse>(null);
Expand Down
2 changes: 1 addition & 1 deletion iothub/device/src/Pipeline/ExceptionRemappingHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public override Task CompleteFileUploadAsync(FileUploadCompletionNotification no
return ExecuteWithExceptionRemappingAsync(() => base.CompleteFileUploadAsync(notification, cancellationToken));
}

public override Task<DirectMethodResponse> InvokeMethodAsync(DirectMethodRequest methodInvokeRequest, Uri uri, CancellationToken cancellationToken)
public override Task<DirectMethodResponse> InvokeMethodAsync(EdgeModuleDirectMethodRequest methodInvokeRequest, Uri uri, CancellationToken cancellationToken)
{
return RunWithExceptionRemappingAsync(() => base.InvokeMethodAsync(methodInvokeRequest, uri, cancellationToken));
}
Expand Down
2 changes: 1 addition & 1 deletion iothub/device/src/Pipeline/IDelegatingHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ internal interface IDelegatingHandler : IContinuationProvider<IDelegatingHandler
Task CompleteFileUploadAsync(FileUploadCompletionNotification notification, CancellationToken cancellationToken);

// This is for invoking methods from an edge module to another edge device or edge module.
Task<DirectMethodResponse> InvokeMethodAsync(DirectMethodRequest methodInvokeRequest, Uri uri, CancellationToken cancellationToken);
Task<DirectMethodResponse> InvokeMethodAsync(EdgeModuleDirectMethodRequest methodInvokeRequest, Uri uri, CancellationToken cancellationToken);

// Sas token validity
Task<DateTime> RefreshSasTokenAsync(CancellationToken cancellationToken);
Expand Down
2 changes: 1 addition & 1 deletion iothub/device/src/Pipeline/RetryDelegatingHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ await _internalRetryHandler
}
}

public override async Task<DirectMethodResponse> InvokeMethodAsync(DirectMethodRequest methodInvokeRequest, Uri uri, CancellationToken cancellationToken)
public override async Task<DirectMethodResponse> InvokeMethodAsync(EdgeModuleDirectMethodRequest methodInvokeRequest, Uri uri, CancellationToken cancellationToken)
{
if (Logging.IsEnabled)
Logging.Enter(this, methodInvokeRequest.RequestId, uri, cancellationToken, nameof(InvokeMethodAsync));
Expand Down
4 changes: 2 additions & 2 deletions iothub/device/src/Transport/Http/HttpTransportHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ await _httpClientHelper

// This is for invoking methods from an edge module to another edge device or edge module.
public override async Task<DirectMethodResponse> InvokeMethodAsync(
DirectMethodRequest methodInvokeRequest,
EdgeModuleDirectMethodRequest methodInvokeRequest,
Uri uri,
CancellationToken cancellationToken)
{
Expand All @@ -89,7 +89,7 @@ public override async Task<DirectMethodResponse> InvokeMethodAsync(
};

return await _httpClientHelper
.PostAsync<DirectMethodRequest, DirectMethodResponse>(
.PostAsync<EdgeModuleDirectMethodRequest, DirectMethodResponse>(
uri,
methodInvokeRequest,
customHeaders,
Expand Down
4 changes: 2 additions & 2 deletions iothub/device/tests/IotHubModuleClientDisposeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,15 +143,15 @@ public async Task IotHubModuleClient_SendMessagesToRouteAsync_ThrowsWhenClientIs
public async Task IotHubModuleClient_InvokeMethodAsync_ThrowsWhenClientIsDisposed()
{
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(1));
Func<Task> op = async () => await s_client.InvokeMethodAsync("deviceId", new DirectMethodRequest(), cts.Token).ConfigureAwait(false);
Func<Task> op = async () => await s_client.InvokeMethodAsync("deviceId", new EdgeModuleDirectMethodRequest("fakeMethodName"), cts.Token).ConfigureAwait(false);
await op.Should().ThrowAsync<ObjectDisposedException>().ConfigureAwait(false);
}

[TestMethod]
public async Task IotHubModuleClient_InvokeMethodAsync_ToModule_ThrowsWhenClientIsDisposed()
{
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(1));
Func<Task> op = async () => await s_client.InvokeMethodAsync("deviceId", "moduleId", new DirectMethodRequest(), cts.Token).ConfigureAwait(false);
Func<Task> op = async () => await s_client.InvokeMethodAsync("deviceId", "moduleId", new EdgeModuleDirectMethodRequest("fakeMethodName"), cts.Token).ConfigureAwait(false);
await op.Should().ThrowAsync<ObjectDisposedException>().ConfigureAwait(false);
}
}
Expand Down
6 changes: 3 additions & 3 deletions iothub/device/tests/IotHubModuleClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ public async Task IotHubModuleClient_InvokeMethodAsync_EdgeDevice_NullMethodRequ
{
// arrange
await using var moduleClient = new IotHubModuleClient(s_fakeConnectionString);
var DirectMethodRequest = new DirectMethodRequest("TestMethodName")
var DirectMethodRequest = new EdgeModuleDirectMethodRequest("TestMethodName")
{
PayloadConvention = DefaultPayloadConvention.Instance,
};
Expand All @@ -211,7 +211,7 @@ public async Task IotHubModuleClient_InvokeMethodAsync_EdgeModule_NullMethodRequ
{
// arrange
await using var moduleClient = new IotHubModuleClient(s_fakeConnectionString);
var DirectMethodRequest = new DirectMethodRequest("TestMethodName")
var DirectMethodRequest = new EdgeModuleDirectMethodRequest("TestMethodName")
{
PayloadConvention = DefaultPayloadConvention.Instance,
};
Expand All @@ -228,7 +228,7 @@ public async Task IotHubModuleClient_InvokeMethodAsync_WithoutExplicitOpenAsync_
{
// arrange
await using var moduleClient = new IotHubModuleClient(s_fakeConnectionString);
var DirectMethodRequest = new DirectMethodRequest("TestMethodName")
var DirectMethodRequest = new EdgeModuleDirectMethodRequest("TestMethodName")
{
PayloadConvention = DefaultPayloadConvention.Instance,
};
Expand Down

0 comments on commit 620b7c6

Please sign in to comment.