in iothub/device/src/ClientFactory.cs [410:509]
internal static InternalClient CreateFromConnectionString(
string connectionString,
IAuthenticationMethod authenticationMethod,
ITransportSettings[] transportSettings,
IDeviceClientPipelineBuilder pipelineBuilder,
ClientOptions options = default)
{
if (connectionString == null)
{
throw new ArgumentNullException(nameof(connectionString));
}
if (transportSettings == null)
{
throw new ArgumentNullException(nameof(transportSettings));
}
if (transportSettings.Length == 0)
{
throw new ArgumentOutOfRangeException(nameof(connectionString), "Must specify at least one TransportSettings instance");
}
if (!string.IsNullOrWhiteSpace(options?.ModelId)
&& transportSettings.Any(x => x.GetTransportType() == TransportType.Http1))
{
throw new InvalidOperationException("Plug and Play is not supported over the HTTP transport.");
}
var builder = IotHubConnectionStringBuilder.CreateWithIAuthenticationOverride(
connectionString,
authenticationMethod);
// Clients that derive their authentication method from AuthenticationWithTokenRefresh will need to specify
// the token time to live and renewal buffer values through the corresponding AuthenticationWithTokenRefresh
// implementation constructors instead, and these values are irrelevant for cert-based auth.
if (!(builder.AuthenticationMethod is AuthenticationWithTokenRefresh)
&& !(builder.AuthenticationMethod is DeviceAuthenticationWithX509Certificate))
{
builder.SasTokenTimeToLive = options?.SasTokenTimeToLive ?? default;
builder.SasTokenRenewalBuffer = options?.SasTokenRenewalBuffer ?? default;
}
var iotHubConnectionString = builder.ToIotHubConnectionString();
foreach (ITransportSettings transportSetting in transportSettings)
{
switch (transportSetting.GetTransportType())
{
case TransportType.Amqp_WebSocket_Only:
case TransportType.Amqp_Tcp_Only:
if (!(transportSetting is AmqpTransportSettings))
{
throw new InvalidOperationException("Unknown implementation of ITransportSettings type");
}
break;
case TransportType.Http1:
if (!(transportSetting is Http1TransportSettings))
{
throw new InvalidOperationException("Unknown implementation of ITransportSettings type");
}
break;
case TransportType.Mqtt_WebSocket_Only:
case TransportType.Mqtt_Tcp_Only:
if (!(transportSetting is MqttTransportSettings))
{
throw new InvalidOperationException("Unknown implementation of ITransportSettings type");
}
break;
default:
throw new InvalidOperationException(
$"Unsupported Transport Type {transportSetting.GetTransportType()}");
}
}
if (authenticationMethod is DeviceAuthenticationWithX509Certificate
&& builder.Certificate == null)
{
throw new ArgumentException("No certificate was found. To use certificate authentication certificate must be present.");
}
// Make sure client options is initialized with the correct transport setting.
EnsureOptionsIsSetup(builder.Certificate, ref options);
pipelineBuilder ??= BuildPipeline();
// Defer concrete InternalClient creation to OpenAsync
var client = new InternalClient(iotHubConnectionString, transportSettings, pipelineBuilder, options);
if (Logging.IsEnabled)
Logging.CreateFromConnectionString(
client,
$"HostName={iotHubConnectionString.HostName};DeviceId={iotHubConnectionString.DeviceId};ModuleId={iotHubConnectionString.ModuleId}",
transportSettings,
options);
return client;
}