public MqttIotHubConnection()

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);
    }