in iothub/device/iot-device-client/src/main/java/com/microsoft/azure/sdk/iot/device/transport/mqtt/MqttIotHubConnection.java [77:240]
public MqttIotHubConnection(ClientConfiguration config) throws TransportException
{
if (config == null)
{
throw new IllegalArgumentException("The ClientConfiguration cannot be null.");
}
if (config.getIotHubHostname() == null || config.getIotHubHostname().length() == 0)
{
throw new IllegalArgumentException("hostName cannot be null or empty.");
}
if (config.getDeviceId() == null || config.getDeviceId().length() == 0)
{
throw new IllegalArgumentException("deviceID cannot be null or empty.");
}
this.config = config;
SSLContext sslContext;
try
{
sslContext = this.config.getAuthenticationProvider().getSSLContext();
}
catch (IOException e)
{
throw new TransportException("Failed to get SSLContext", e);
}
if (this.config.getAuthenticationType() == ClientConfiguration.AuthType.SAS_TOKEN)
{
log.trace("MQTT connection will use sas token based auth");
this.webSocketQueryString = NO_CLIENT_CERT_QUERY_STRING;
}
else if (this.config.getAuthenticationType() == ClientConfiguration.AuthType.X509_CERTIFICATE)
{
log.trace("MQTT connection will use X509 certificate based auth");
}
// URLEncoder follows HTML spec for encoding urls, which includes substituting space characters with '+'
// We want "%20" for spaces, not '+', however, so replace them manually after utf-8 encoding.
String userAgentString = this.config.getProductInfo().getUserAgentString();
String clientUserAgentIdentifier;
try
{
clientUserAgentIdentifier = "DeviceClientType=" + URLEncoder.encode(userAgentString, StandardCharsets.UTF_8.name()).replaceAll("\\+", "%20");
}
catch (UnsupportedEncodingException e)
{
throw new TransportException("Failed to URLEncode the user agent string", e);
}
String deviceId = this.config.getDeviceId();
String moduleId = this.config.getModuleId();
if (moduleId != null && !moduleId.isEmpty())
{
this.clientId = deviceId + "/" + moduleId;
}
else
{
this.clientId = deviceId;
}
String serviceParams;
String modelId = this.config.getModelId();
if (modelId == null || modelId.isEmpty())
{
serviceParams = TransportUtils.IOTHUB_API_VERSION;
}
else
{
try
{
// URLEncoder follows HTML spec for encoding urls, which includes substituting space characters with '+'
// We want "%20" for spaces, not '+', however, so replace them manually after utf-8 encoding.
serviceParams = TransportUtils.IOTHUB_API_VERSION + "&" + MODEL_ID + "=" + URLEncoder.encode(modelId, StandardCharsets.UTF_8.name()).replaceAll("\\+", "%20");
}
catch (UnsupportedEncodingException e)
{
throw new TransportException("Failed to URLEncode the modelId string", e);
}
}
String iotHubUserName = this.config.getIotHubHostname() + "/" + clientId + "/?api-version=" + serviceParams + "&" + clientUserAgentIdentifier;
String host = this.config.getGatewayHostname();
if (host == null || host.isEmpty())
{
host = this.config.getIotHubHostname();
}
if (this.config.isUsingWebsocket())
{
if (this.webSocketQueryString == null)
{
this.serverUri = WS_SSL_PREFIX + host + WEBSOCKET_RAW_PATH;
}
else
{
this.serverUri = WS_SSL_PREFIX + host + WEBSOCKET_RAW_PATH + this.webSocketQueryString;
}
}
else
{
this.serverUri = SSL_PREFIX + host + SSL_PORT_SUFFIX;
}
MqttConnectOptions connectOptions = new MqttConnectOptions();
connectOptions.setKeepAliveInterval(config.getKeepAliveInterval());
connectOptions.setCleanSession(SET_CLEAN_SESSION);
connectOptions.setMqttVersion(MQTT_VERSION);
connectOptions.setUserName(iotHubUserName);
connectOptions.setMaxInflight(MAX_IN_FLIGHT_COUNT);
ProxySettings proxySettings = config.getProxySettings();
if (proxySettings != null)
{
if (proxySettings.getProxy().type() == Proxy.Type.SOCKS)
{
try
{
connectOptions.setSocketFactory(new Socks5SocketFactory(proxySettings.getHostname(), proxySettings.getPort()));
}
catch (UnknownHostException e)
{
throw new TransportException("Failed to build the Socks5SocketFactory", e);
}
}
else if (proxySettings.getProxy().type() == Proxy.Type.HTTP)
{
connectOptions.setSocketFactory(new HttpProxySocketFactory(sslContext.getSocketFactory(), proxySettings));
}
else
{
throw new IllegalArgumentException("Proxy settings must be configured to use either SOCKS or HTTP");
}
}
else
{
connectOptions.setSocketFactory(sslContext.getSocketFactory());
}
// these variables are shared between the messaging, twin and method subclients
Map<Integer, Message> unacknowledgedSentMessages = new ConcurrentHashMap<>();
Queue<Pair<String, MqttMessage>> receivedMessages = new ConcurrentLinkedQueue<>();
this.deviceMessaging = new MqttMessaging(
deviceId,
this,
moduleId,
this.config.getGatewayHostname() != null && !this.config.getGatewayHostname().isEmpty(),
connectOptions,
unacknowledgedSentMessages,
receivedMessages);
this.directMethod = new MqttDirectMethod(
deviceId,
connectOptions,
unacknowledgedSentMessages,
receivedMessages);
this.deviceTwin = new MqttTwin(
deviceId,
connectOptions,
unacknowledgedSentMessages,
receivedMessages);
}