Skip to content

Commit

Permalink
Fix getting CloudProxy when no identity exists (#548)
Browse files Browse the repository at this point in the history
  • Loading branch information
varunpuranik authored Nov 16, 2018
1 parent 326ef8c commit 75e7968
Show file tree
Hide file tree
Showing 16 changed files with 221 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class ConnectionManager : IConnectionManager
readonly ICloudConnectionProvider cloudConnectionProvider;
readonly int maxClients;
readonly ICredentialsCache credentialsCache;
readonly IIdentityProvider identityProvider;

public event EventHandler<IIdentity> CloudConnectionLost;
public event EventHandler<IIdentity> CloudConnectionEstablished;
Expand All @@ -35,11 +36,13 @@ public class ConnectionManager : IConnectionManager
public ConnectionManager(
ICloudConnectionProvider cloudConnectionProvider,
ICredentialsCache credentialsCache,
IIdentityProvider identityProvider,
int maxClients = DefaultMaxClients)
{
this.cloudConnectionProvider = Preconditions.CheckNotNull(cloudConnectionProvider, nameof(cloudConnectionProvider));
this.maxClients = Preconditions.CheckRange(maxClients, 1, nameof(maxClients));
this.credentialsCache = Preconditions.CheckNotNull(credentialsCache, nameof(credentialsCache));
this.identityProvider = Preconditions.CheckNotNull(identityProvider, nameof(identityProvider));
Util.Metrics.RegisterGaugeCallback(() => Metrics.SetConnectedClientCountGauge(this));
}

Expand Down Expand Up @@ -92,13 +95,11 @@ public Option<IDeviceProxy> GetDeviceConnection(string id)

public async Task<Option<ICloudProxy>> GetCloudConnection(string id)
{
if (!this.devices.TryGetValue(Preconditions.CheckNonWhiteSpace(id, nameof(id)), out ConnectedDevice device))
{
return Option.None<ICloudProxy>();
}
IIdentity identity = this.identityProvider.Create(Preconditions.CheckNonWhiteSpace(id, nameof(id)));
ConnectedDevice device = this.GetOrCreateConnectedDevice(identity);

Try<ICloudConnection> cloudConnectionTry = await device.GetOrCreateCloudConnection(
c => this.cloudConnectionProvider.Connect(c.Identity, (identity, status) => this.CloudConnectionStatusChangedHandler(identity, status)));
c => this.cloudConnectionProvider.Connect(c.Identity, (i, status) => this.CloudConnectionStatusChangedHandler(i, status)));

Events.GetCloudConnection(device.Identity, cloudConnectionTry);
Try<ICloudProxy> cloudProxyTry = GetCloudProxyFromCloudConnection(cloudConnectionTry, device.Identity);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,53 +13,43 @@ namespace Microsoft.Azure.Devices.Edge.Hub.Core.Identity
/// </summary>
public class ClientCredentialsFactory : IClientCredentialsFactory
{
readonly string iotHubHostName;
readonly IIdentityProvider identityProvider;
readonly string callerProductInfo;

public ClientCredentialsFactory(string iotHubHostName)
: this(iotHubHostName, string.Empty)
public ClientCredentialsFactory(IIdentityProvider identityProvider)
: this(identityProvider, string.Empty)
{
}

public ClientCredentialsFactory(string iotHubHostName, string callerProductInfo)
public ClientCredentialsFactory(IIdentityProvider identityProvider, string callerProductInfo)
{
this.iotHubHostName = iotHubHostName;
this.identityProvider = identityProvider;
this.callerProductInfo = callerProductInfo;
}

public IClientCredentials GetWithX509Cert(string deviceId, string moduleId, string deviceClientType)
{
string productInfo = string.Join(" ", this.callerProductInfo, deviceClientType).Trim();
IIdentity identity = this.GetIdentity(deviceId, moduleId);
IIdentity identity = this.identityProvider.Create(deviceId, moduleId);
return new X509CertCredentials(identity, productInfo);
}

public IClientCredentials GetWithSasToken(string deviceId, string moduleId, string deviceClientType, string token, bool updatable)
{
string productInfo = string.Join(" ", this.callerProductInfo, deviceClientType).Trim();
IIdentity identity = this.GetIdentity(deviceId, moduleId);
IIdentity identity = this.identityProvider.Create(deviceId, moduleId);
return new TokenCredentials(identity, token, productInfo, updatable);
}

public IClientCredentials GetWithConnectionString(string connectionString)
{
Preconditions.CheckNonWhiteSpace(connectionString, nameof(connectionString));
IotHubConnectionStringBuilder iotHubConnectionStringBuilder = IotHubConnectionStringBuilder.Create(connectionString);
IIdentity identity = this.GetIdentity(iotHubConnectionStringBuilder.DeviceId, iotHubConnectionStringBuilder.ModuleId);
IIdentity identity = this.identityProvider.Create(iotHubConnectionStringBuilder.DeviceId, iotHubConnectionStringBuilder.ModuleId);
return new SharedKeyCredentials(identity, connectionString, this.callerProductInfo);
}

public IClientCredentials GetWithIotEdged(string deviceId, string moduleId)
{
return new IotEdgedCredentials(this.GetIdentity(deviceId, moduleId), this.callerProductInfo);
}

IIdentity GetIdentity(string deviceId, string moduleId)
{
IIdentity identity = string.IsNullOrWhiteSpace(moduleId)
? new DeviceIdentity(this.iotHubHostName, deviceId)
: new ModuleIdentity(this.iotHubHostName, deviceId, moduleId) as IIdentity;
return identity;
}
public IClientCredentials GetWithIotEdged(string deviceId, string moduleId) =>
new IotEdgedCredentials(this.identityProvider.Create(deviceId, moduleId), this.callerProductInfo);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) Microsoft. All rights reserved.

namespace Microsoft.Azure.Devices.Edge.Hub.Core.Identity
{
public interface IIdentityProvider
{
IIdentity Create(string id);

IIdentity Create(string deviceId, string moduleId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) Microsoft. All rights reserved.

namespace Microsoft.Azure.Devices.Edge.Hub.Core.Identity
{
using Microsoft.Azure.Devices.Edge.Util;

public class IdentityProvider : IIdentityProvider
{
readonly string iothubHostName;

public IdentityProvider(string iothubHostName)
{
this.iothubHostName = Preconditions.CheckNonWhiteSpace(iothubHostName, nameof(iothubHostName));
}

public IIdentity Create(string id)
{
// If it is a module id, it will have the format "deviceId/moduleId"
string[] parts = Preconditions.CheckNotNull(id, nameof(id)).Split('/');
IIdentity identity = parts.Length == 2
? new ModuleIdentity(this.iothubHostName, parts[0], parts[1]) as IIdentity
: new DeviceIdentity(this.iothubHostName, id);
return identity;
}

public IIdentity Create(string deviceId, string moduleId)
{
IIdentity identity = string.IsNullOrWhiteSpace(moduleId)
? new DeviceIdentity(this.iothubHostName, deviceId)
: new ModuleIdentity(this.iothubHostName, deviceId, moduleId) as IIdentity;
return identity;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ protected override void Load(ContainerBuilder builder)
.SingleInstance();

// IClientCredentialsFactory
builder.Register(c => new ClientCredentialsFactory(this.iothubHostName, this.productInfo))
builder.Register(c => new ClientCredentialsFactory(c.Resolve<IIdentityProvider>(), this.productInfo))
.As<IClientCredentialsFactory>()
.SingleInstance();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,17 +190,24 @@ protected override void Load(ContainerBuilder builder)
.As<Task<ICloudConnectionProvider>>()
.SingleInstance();

// IIdentityProvider
builder.Register(_ => new IdentityProvider(this.iotHubName))
.As<IIdentityProvider>()
.SingleInstance();

// Task<IConnectionManager>
builder.Register(
async c =>
{
var cloudConnectionProviderTask = c.Resolve<Task<ICloudConnectionProvider>>();
var credentialsCacheTask = c.Resolve<Task<ICredentialsCache>>();
var identityProvider = c.Resolve<IIdentityProvider>();
ICloudConnectionProvider cloudConnectionProvider = await cloudConnectionProviderTask;
ICredentialsCache credentialsCache = await credentialsCacheTask;
IConnectionManager connectionManager = new ConnectionManager(
cloudConnectionProvider,
credentialsCache,
identityProvider,
this.maxConnectedClients);
return connectionManager;
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ IClient GetMockedDeviceClient()
Mock.Of<IIdentity>(i => i.Id == $"{deviceId}/$edgeHub"),
TimeSpan.FromMinutes(60), true);
cloudConnectionProvider.BindEdgeHub(Mock.Of<IEdgeHub>());
IConnectionManager connectionManager = new ConnectionManager(cloudConnectionProvider, Mock.Of<ICredentialsCache>());
IConnectionManager connectionManager = new ConnectionManager(cloudConnectionProvider, Mock.Of<ICredentialsCache>(), new IdentityProvider(hostname));

ITokenCredentials clientCredentials1 = GetClientCredentials(TimeSpan.FromSeconds(10));
Try<ICloudProxy> cloudProxyTry1 = await connectionManager.CreateCloudConnectionAsync(clientCredentials1);
Expand Down
Loading

0 comments on commit 75e7968

Please sign in to comment.