# coding=utf-8
# --------------------------------------------------------------------------
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is
# regenerated.
# --------------------------------------------------------------------------

from msrest.pipeline import ClientRawResponse
from msrest.exceptions import HttpOperationError

from .. import models


class ServiceOperations(object):
    """ServiceOperations operations.

    :param client: Client for service requests.
    :param config: Configuration of service client.
    :param serializer: An object model serializer.
    :param deserializer: An object model deserializer.
    :ivar api_version: Version of the Api. Constant value: "2019-06-30".
    """

    models = models

    def __init__(self, client, config, serializer, deserializer):

        self._client = client
        self._serialize = serializer
        self._deserialize = deserializer

        self.config = config
        self.api_version = "2019-06-30"

    def get_configuration(self, id, custom_headers=None, raw=False, **operation_config):
        """Retrieve a configuration for Iot Hub devices and modules by it
        identifier.

        :param id:
        :type id: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: Configuration or ClientRawResponse if raw=true
        :rtype: ~protocol.models.Configuration or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.get_configuration.metadata["url"]
        path_format_arguments = {"id": self._serialize.url("id", id, "str")}
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct and send request
        request = self._client.get(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("Configuration", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    get_configuration.metadata = {"url": "/configurations/{id}"}

    def create_or_update_configuration(
        self, id, configuration, if_match=None, custom_headers=None, raw=False, **operation_config
    ):
        """Create or update the configuration for devices or modules of an IoT
        hub. An ETag must not be specified for the create operation. An ETag
        must be specified for the update operation. Note that configuration Id
        and Content cannot be updated by the user.

        :param id:
        :type id: str
        :param configuration:
        :type configuration: ~protocol.models.Configuration
        :param if_match:
        :type if_match: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: Configuration or ClientRawResponse if raw=true
        :rtype: ~protocol.models.Configuration or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.create_or_update_configuration.metadata["url"]
        path_format_arguments = {"id": self._serialize.url("id", id, "str")}
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        header_parameters["Content-Type"] = "application/json; charset=utf-8"
        if custom_headers:
            header_parameters.update(custom_headers)
        if if_match is not None:
            header_parameters["If-Match"] = self._serialize.header("if_match", if_match, "str")

        # Construct body
        body_content = self._serialize.body(configuration, "Configuration")

        # Construct and send request
        request = self._client.put(url, query_parameters, header_parameters, body_content)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200, 201]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("Configuration", response)
        if response.status_code == 201:
            deserialized = self._deserialize("Configuration", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    create_or_update_configuration.metadata = {"url": "/configurations/{id}"}

    def delete_configuration(
        self, id, if_match=None, custom_headers=None, raw=False, **operation_config
    ):
        """Delete the configuration for devices or modules of an IoT hub. This
        request requires the If-Match header. The client may specify the ETag
        for the device identity on the request in order to compare to the ETag
        maintained by the service for the purpose of optimistic concurrency.
        The delete operation is performed only if the ETag sent by the client
        matches the value maintained by the server, indicating that the device
        identity has not been modified since it was retrieved by the client. To
        force an unconditional delete, set If-Match to the wildcard character
        (*).

        :param id:
        :type id: str
        :param if_match:
        :type if_match: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: None or ClientRawResponse if raw=true
        :rtype: None or ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.delete_configuration.metadata["url"]
        path_format_arguments = {"id": self._serialize.url("id", id, "str")}
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        if custom_headers:
            header_parameters.update(custom_headers)
        if if_match is not None:
            header_parameters["If-Match"] = self._serialize.header("if_match", if_match, "str")

        # Construct and send request
        request = self._client.delete(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [204]:
            raise HttpOperationError(self._deserialize, response)

        if raw:
            client_raw_response = ClientRawResponse(None, response)
            return client_raw_response

    delete_configuration.metadata = {"url": "/configurations/{id}"}

    def get_configurations(self, top=None, custom_headers=None, raw=False, **operation_config):
        """Get multiple configurations for devices or modules of an IoT Hub.
        Returns the specified number of configurations for Iot Hub. Pagination
        is not supported.

        :param top:
        :type top: int
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: list or ClientRawResponse if raw=true
        :rtype: list[~protocol.models.Configuration] or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.get_configurations.metadata["url"]

        # Construct parameters
        query_parameters = {}
        if top is not None:
            query_parameters["top"] = self._serialize.query("top", top, "int")
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct and send request
        request = self._client.get(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("[Configuration]", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    get_configurations.metadata = {"url": "/configurations"}

    def test_configuration_queries(self, input, custom_headers=None, raw=False, **operation_config):
        """Validates the target condition query and custom metric queries for a
        configuration.

        Validates the target condition query and custom metric queries for a
        configuration.

        :param input:
        :type input: ~protocol.models.ConfigurationQueriesTestInput
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: ConfigurationQueriesTestResponse or ClientRawResponse if
         raw=true
        :rtype: ~protocol.models.ConfigurationQueriesTestResponse or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.test_configuration_queries.metadata["url"]

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        header_parameters["Content-Type"] = "application/json; charset=utf-8"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct body
        body_content = self._serialize.body(input, "ConfigurationQueriesTestInput")

        # Construct and send request
        request = self._client.post(url, query_parameters, header_parameters, body_content)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("ConfigurationQueriesTestResponse", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    test_configuration_queries.metadata = {"url": "/configurations/testQueries"}

    def get_device_registry_statistics(self, custom_headers=None, raw=False, **operation_config):
        """Retrieves statistics about device identities in the IoT hub’s identity
        registry.

        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: RegistryStatistics or ClientRawResponse if raw=true
        :rtype: ~protocol.models.RegistryStatistics or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.get_device_registry_statistics.metadata["url"]

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct and send request
        request = self._client.get(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("RegistryStatistics", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    get_device_registry_statistics.metadata = {"url": "/statistics/devices"}

    def get_service_statistics(self, custom_headers=None, raw=False, **operation_config):
        """Retrieves service statistics for this IoT hub’s identity registry.

        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: ServiceStatistics or ClientRawResponse if raw=true
        :rtype: ~protocol.models.ServiceStatistics or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.get_service_statistics.metadata["url"]

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct and send request
        request = self._client.get(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("ServiceStatistics", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    get_service_statistics.metadata = {"url": "/statistics/service"}

    def get_devices(self, top=None, custom_headers=None, raw=False, **operation_config):
        """Get the identities of multiple devices from the IoT hub identity
        registry. Not recommended. Use the IoT Hub query language to retrieve
        device twin and device identity information. See
        https://docs.microsoft.com/en-us/rest/api/iothub/service/queryiothub
        and
        https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-query-language
        for more information.

        :param top: This parameter when specified, defines the maximum number
         of device identities that are returned. Any value outside the range of
         1-1000 is considered to be 1000.
        :type top: int
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: list or ClientRawResponse if raw=true
        :rtype: list[~protocol.models.Device] or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.get_devices.metadata["url"]

        # Construct parameters
        query_parameters = {}
        if top is not None:
            query_parameters["top"] = self._serialize.query("top", top, "int")
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct and send request
        request = self._client.get(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("[Device]", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    get_devices.metadata = {"url": "/devices"}

    def bulk_create_or_update_devices(
        self, devices, custom_headers=None, raw=False, **operation_config
    ):
        """Create, update, or delete the identities of multiple devices from the
        IoT hub identity registry.

        Create, update, or delete the identiies of multiple devices from the
        IoT hub identity registry. A device identity can be specified only once
        in the list. Different operations (create, update, delete) on different
        devices are allowed. A maximum of 100 devices can be specified per
        invocation. For large scale operations, consider using the import
        feature using blob
        storage(https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-identity-registry#import-and-export-device-identities).

        :param devices:
        :type devices: list[~protocol.models.ExportImportDevice]
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: BulkRegistryOperationResult or ClientRawResponse if raw=true
        :rtype: ~protocol.models.BulkRegistryOperationResult or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.bulk_create_or_update_devices.metadata["url"]

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        header_parameters["Content-Type"] = "application/json; charset=utf-8"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct body
        body_content = self._serialize.body(devices, "[ExportImportDevice]")

        # Construct and send request
        request = self._client.post(url, query_parameters, header_parameters, body_content)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200, 400]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("BulkRegistryOperationResult", response)
        if response.status_code == 400:
            deserialized = self._deserialize("BulkRegistryOperationResult", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    bulk_create_or_update_devices.metadata = {"url": "/devices"}

    def query_iot_hub(
        self, query_specification, custom_headers=None, raw=False, **operation_config
    ):
        """Query an IoT hub to retrieve information regarding device twins using a
        SQL-like language.

        Query an IoT hub to retrieve information regarding device twins using a
        SQL-like language. See
        https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-query-language
        for more information. Pagination of results is supported. This returns
        information about device twins only.

        :param query_specification:
        :type query_specification: ~protocol.models.QuerySpecification
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: QueryResult or ClientRawResponse if raw=true
        :rtype: ~protocol.models.QueryResult or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.query_iot_hub.metadata["url"]

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        header_parameters["Content-Type"] = "application/json; charset=utf-8"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct body
        body_content = self._serialize.body(query_specification, "QuerySpecification")

        # Construct and send request
        request = self._client.post(url, query_parameters, header_parameters, body_content)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("QueryResult", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    query_iot_hub.metadata = {"url": "/devices/query"}

    def get_device(self, id, custom_headers=None, raw=False, **operation_config):
        """Retrieve a device from the identity registry of an IoT hub.

        Retrieve a device from the identity registry of an IoT hub.

        :param id: Device ID.
        :type id: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: Device or ClientRawResponse if raw=true
        :rtype: ~protocol.models.Device or ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.get_device.metadata["url"]
        path_format_arguments = {"id": self._serialize.url("id", id, "str")}
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct and send request
        request = self._client.get(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("Device", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    get_device.metadata = {"url": "/devices/{id}"}

    def create_or_update_device(
        self, id, device, if_match=None, custom_headers=None, raw=False, **operation_config
    ):
        """Create or update the identity of a device in the identity registry of
        an IoT hub.

        Create or update the identity of a device in the identity registry of
        an IoT hub. An ETag must not be specified for the create operation. An
        ETag must be specified for the update operation. Note that generationId
        and deviceId cannot be updated by the user.

        :param id: Device ID.
        :type id: str
        :param device:
        :type device: ~protocol.models.Device
        :param if_match:
        :type if_match: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: Device or ClientRawResponse if raw=true
        :rtype: ~protocol.models.Device or ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.create_or_update_device.metadata["url"]
        path_format_arguments = {"id": self._serialize.url("id", id, "str")}
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        header_parameters["Content-Type"] = "application/json; charset=utf-8"
        if custom_headers:
            header_parameters.update(custom_headers)
        if if_match is not None:
            header_parameters["If-Match"] = self._serialize.header("if_match", if_match, "str")

        # Construct body
        body_content = self._serialize.body(device, "Device")

        # Construct and send request
        request = self._client.put(url, query_parameters, header_parameters, body_content)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("Device", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    create_or_update_device.metadata = {"url": "/devices/{id}"}

    def delete_device(self, id, if_match=None, custom_headers=None, raw=False, **operation_config):
        """Delete the identity of a device from the identity registry of an IoT
        hub.

        Delete the identity of a device from the identity registry of an IoT
        hub. This request requires the If-Match header. The client may specify
        the ETag for the device identity on the request in order to compare to
        the ETag maintained by the service for the purpose of optimistic
        concurrency. The delete operation is performed only if the ETag sent by
        the client matches the value maintained by the server, indicating that
        the device identity has not been modified since it was retrieved by the
        client. To force an unconditional delete, set If-Match to the wildcard
        character (*).

        :param id: Device ID.
        :type id: str
        :param if_match:
        :type if_match: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: None or ClientRawResponse if raw=true
        :rtype: None or ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.delete_device.metadata["url"]
        path_format_arguments = {"id": self._serialize.url("id", id, "str")}
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        if custom_headers:
            header_parameters.update(custom_headers)
        if if_match is not None:
            header_parameters["If-Match"] = self._serialize.header("if_match", if_match, "str")

        # Construct and send request
        request = self._client.delete(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [204]:
            raise HttpOperationError(self._deserialize, response)

        if raw:
            client_raw_response = ClientRawResponse(None, response)
            return client_raw_response

    delete_device.metadata = {"url": "/devices/{id}"}

    def apply_configuration_on_edge_device(
        self, id, content, custom_headers=None, raw=False, **operation_config
    ):
        """Applies the provided configuration content to the specified edge
        device.

        Applies the provided configuration content to the specified edge
        device. Configuration content must have modules content.

        :param id: Device ID.
        :type id: str
        :param content: Configuration Content.
        :type content: ~protocol.models.ConfigurationContent
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: object or ClientRawResponse if raw=true
        :rtype: object or ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.apply_configuration_on_edge_device.metadata["url"]
        path_format_arguments = {"id": self._serialize.url("id", id, "str")}
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        header_parameters["Content-Type"] = "application/json; charset=utf-8"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct body
        body_content = self._serialize.body(content, "ConfigurationContent")

        # Construct and send request
        request = self._client.post(url, query_parameters, header_parameters, body_content)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200, 204]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("object", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    apply_configuration_on_edge_device.metadata = {"url": "/devices/{id}/applyConfigurationContent"}

    def create_import_export_job(
        self, job_properties, custom_headers=None, raw=False, **operation_config
    ):
        """Create a new import/export job on an IoT hub.

        Create a new import/export job on an IoT hub. See
        https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-identity-registry#import-and-export-device-identities
        for more information.

        :param job_properties:
        :type job_properties: ~protocol.models.JobProperties
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: JobProperties or ClientRawResponse if raw=true
        :rtype: ~protocol.models.JobProperties or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.create_import_export_job.metadata["url"]

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        header_parameters["Content-Type"] = "application/json; charset=utf-8"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct body
        body_content = self._serialize.body(job_properties, "JobProperties")

        # Construct and send request
        request = self._client.post(url, query_parameters, header_parameters, body_content)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("JobProperties", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    create_import_export_job.metadata = {"url": "/jobs/create"}

    def get_import_export_jobs(self, custom_headers=None, raw=False, **operation_config):
        """Gets the status of all import/export jobs in an iot hub.

        Gets the status of all import/export jobs in an iot hub. See
        https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-identity-registry#import-and-export-device-identities
        for more information.

        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: list or ClientRawResponse if raw=true
        :rtype: list[~protocol.models.JobProperties] or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.get_import_export_jobs.metadata["url"]

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct and send request
        request = self._client.get(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("[JobProperties]", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    get_import_export_jobs.metadata = {"url": "/jobs"}

    def get_import_export_job(self, id, custom_headers=None, raw=False, **operation_config):
        """Gets the status of an import or export job in an iot hub.

        Gets the status of an import or export job in an iot hub. See
        https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-identity-registry#import-and-export-device-identities
        for more information.

        :param id: Job ID.
        :type id: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: JobProperties or ClientRawResponse if raw=true
        :rtype: ~protocol.models.JobProperties or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.get_import_export_job.metadata["url"]
        path_format_arguments = {"id": self._serialize.url("id", id, "str")}
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct and send request
        request = self._client.get(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("JobProperties", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    get_import_export_job.metadata = {"url": "/jobs/{id}"}

    def cancel_import_export_job(self, id, custom_headers=None, raw=False, **operation_config):
        """Cancels an import or export job in an IoT hub.

        Cancels an import or export job in an IoT hub. See
        https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-identity-registry#import-and-export-device-identities
        for more information.

        :param id: Job ID.
        :type id: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: object or ClientRawResponse if raw=true
        :rtype: object or ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.cancel_import_export_job.metadata["url"]
        path_format_arguments = {"id": self._serialize.url("id", id, "str")}
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct and send request
        request = self._client.delete(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200, 204]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("object", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    cancel_import_export_job.metadata = {"url": "/jobs/{id}"}

    def purge_command_queue(self, id, custom_headers=None, raw=False, **operation_config):
        """Deletes all the pending commands for this device from the IoT hub.

        Deletes all the pending commands for this device from the IoT hub.

        :param id: Device ID.
        :type id: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: PurgeMessageQueueResult or ClientRawResponse if raw=true
        :rtype: ~protocol.models.PurgeMessageQueueResult or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.purge_command_queue.metadata["url"]
        path_format_arguments = {"id": self._serialize.url("id", id, "str")}
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct and send request
        request = self._client.delete(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("PurgeMessageQueueResult", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    purge_command_queue.metadata = {"url": "/devices/{id}/commands"}

    def get_twin(self, id, custom_headers=None, raw=False, **operation_config):
        """Gets a device twin.

        Gets a device twin. See
        https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-device-twins
        for more information.

        :param id: Device ID.
        :type id: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: Twin or ClientRawResponse if raw=true
        :rtype: ~protocol.models.Twin or ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.get_twin.metadata["url"]
        path_format_arguments = {"id": self._serialize.url("id", id, "str")}
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct and send request
        request = self._client.get(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("Twin", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    get_twin.metadata = {"url": "/twins/{id}"}

    def replace_twin(
        self,
        id,
        device_twin_info,
        if_match=None,
        custom_headers=None,
        raw=False,
        **operation_config
    ):
        """Replaces tags and desired properties of a device twin.

        Replaces a device twin. See
        https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-device-twins
        for more information.

        :param id: Device ID.
        :type id: str
        :param device_twin_info: Device twin info
        :type device_twin_info: ~protocol.models.Twin
        :param if_match:
        :type if_match: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: Twin or ClientRawResponse if raw=true
        :rtype: ~protocol.models.Twin or ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.replace_twin.metadata["url"]
        path_format_arguments = {"id": self._serialize.url("id", id, "str")}
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        header_parameters["Content-Type"] = "application/json; charset=utf-8"
        if custom_headers:
            header_parameters.update(custom_headers)
        if if_match is not None:
            header_parameters["If-Match"] = self._serialize.header("if_match", if_match, "str")

        # Construct body
        body_content = self._serialize.body(device_twin_info, "Twin")

        # Construct and send request
        request = self._client.put(url, query_parameters, header_parameters, body_content)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("Twin", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    replace_twin.metadata = {"url": "/twins/{id}"}

    def update_twin(
        self,
        id,
        device_twin_info,
        if_match=None,
        custom_headers=None,
        raw=False,
        **operation_config
    ):
        """Updates tags and desired properties of a device twin.

        Updates a device twin. See
        https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-device-twins
        for more information.

        :param id: Device ID.
        :type id: str
        :param device_twin_info: Device twin info
        :type device_twin_info: ~protocol.models.Twin
        :param if_match:
        :type if_match: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: Twin or ClientRawResponse if raw=true
        :rtype: ~protocol.models.Twin or ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.update_twin.metadata["url"]
        path_format_arguments = {"id": self._serialize.url("id", id, "str")}
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        header_parameters["Content-Type"] = "application/json; charset=utf-8"
        if custom_headers:
            header_parameters.update(custom_headers)
        if if_match is not None:
            header_parameters["If-Match"] = self._serialize.header("if_match", if_match, "str")

        # Construct body
        body_content = self._serialize.body(device_twin_info, "Twin")

        # Construct and send request
        request = self._client.patch(url, query_parameters, header_parameters, body_content)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("Twin", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    update_twin.metadata = {"url": "/twins/{id}"}

    def get_module_twin(self, id, mid, custom_headers=None, raw=False, **operation_config):
        """Gets a module twin.

        Gets a module twin. See
        https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-device-twins
        for more information.

        :param id: Device ID.
        :type id: str
        :param mid: Module ID.
        :type mid: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: Twin or ClientRawResponse if raw=true
        :rtype: ~protocol.models.Twin or ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.get_module_twin.metadata["url"]
        path_format_arguments = {
            "id": self._serialize.url("id", id, "str"),
            "mid": self._serialize.url("mid", mid, "str"),
        }
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct and send request
        request = self._client.get(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("Twin", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    get_module_twin.metadata = {"url": "/twins/{id}/modules/{mid}"}

    def replace_module_twin(
        self,
        id,
        mid,
        device_twin_info,
        if_match=None,
        custom_headers=None,
        raw=False,
        **operation_config
    ):
        """Replaces tags and desired properties of a module twin.

        Replaces a module twin. See
        https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-device-twins
        for more information.

        :param id: Device ID.
        :type id: str
        :param mid: Module ID.
        :type mid: str
        :param device_twin_info: Device twin info
        :type device_twin_info: ~protocol.models.Twin
        :param if_match:
        :type if_match: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: Twin or ClientRawResponse if raw=true
        :rtype: ~protocol.models.Twin or ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.replace_module_twin.metadata["url"]
        path_format_arguments = {
            "id": self._serialize.url("id", id, "str"),
            "mid": self._serialize.url("mid", mid, "str"),
        }
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        header_parameters["Content-Type"] = "application/json; charset=utf-8"
        if custom_headers:
            header_parameters.update(custom_headers)
        if if_match is not None:
            header_parameters["If-Match"] = self._serialize.header("if_match", if_match, "str")

        # Construct body
        body_content = self._serialize.body(device_twin_info, "Twin")

        # Construct and send request
        request = self._client.put(url, query_parameters, header_parameters, body_content)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("Twin", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    replace_module_twin.metadata = {"url": "/twins/{id}/modules/{mid}"}

    def update_module_twin(
        self,
        id,
        mid,
        device_twin_info,
        if_match=None,
        custom_headers=None,
        raw=False,
        **operation_config
    ):
        """Updates tags and desired properties of a module twin.

        Updates a module twin. See
        https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-device-twins
        for more information.

        :param id: Device ID.
        :type id: str
        :param mid: Module ID.
        :type mid: str
        :param device_twin_info: Device twin information
        :type device_twin_info: ~protocol.models.Twin
        :param if_match:
        :type if_match: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: Twin or ClientRawResponse if raw=true
        :rtype: ~protocol.models.Twin or ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.update_module_twin.metadata["url"]
        path_format_arguments = {
            "id": self._serialize.url("id", id, "str"),
            "mid": self._serialize.url("mid", mid, "str"),
        }
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        header_parameters["Content-Type"] = "application/json; charset=utf-8"
        if custom_headers:
            header_parameters.update(custom_headers)
        if if_match is not None:
            header_parameters["If-Match"] = self._serialize.header("if_match", if_match, "str")

        # Construct body
        body_content = self._serialize.body(device_twin_info, "Twin")

        # Construct and send request
        request = self._client.patch(url, query_parameters, header_parameters, body_content)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("Twin", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    update_module_twin.metadata = {"url": "/twins/{id}/modules/{mid}"}

    def get_job(self, id, custom_headers=None, raw=False, **operation_config):
        """Retrieves details of a scheduled job from an IoT hub.

        Retrieves details of a scheduled job from an IoT hub. See
        https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-jobs
        for more information.

        :param id: Job ID.
        :type id: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: JobResponse or ClientRawResponse if raw=true
        :rtype: ~protocol.models.JobResponse or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.get_job.metadata["url"]
        path_format_arguments = {"id": self._serialize.url("id", id, "str")}
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct and send request
        request = self._client.get(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("JobResponse", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    get_job.metadata = {"url": "/jobs/v2/{id}"}

    def create_job(self, id, job_request, custom_headers=None, raw=False, **operation_config):
        """Creates a new job to schedule update twins or device direct methods on
        an IoT hub at a scheduled time.

        Creates a new job to schedule update twins or device direct methods on
        an IoT hub at a scheduled time. See
        https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-jobs
        for more information.

        :param id: Job ID.
        :type id: str
        :param job_request:
        :type job_request: ~protocol.models.JobRequest
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: JobResponse or ClientRawResponse if raw=true
        :rtype: ~protocol.models.JobResponse or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.create_job.metadata["url"]
        path_format_arguments = {"id": self._serialize.url("id", id, "str")}
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        header_parameters["Content-Type"] = "application/json; charset=utf-8"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct body
        body_content = self._serialize.body(job_request, "JobRequest")

        # Construct and send request
        request = self._client.put(url, query_parameters, header_parameters, body_content)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("JobResponse", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    create_job.metadata = {"url": "/jobs/v2/{id}"}

    def cancel_job(self, id, custom_headers=None, raw=False, **operation_config):
        """Cancels a scheduled job on an IoT hub.

        Cancels a scheduled job on an IoT hub. See
        https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-jobs
        for more information.

        :param id: Job ID.
        :type id: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: JobResponse or ClientRawResponse if raw=true
        :rtype: ~protocol.models.JobResponse or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.cancel_job.metadata["url"]
        path_format_arguments = {"id": self._serialize.url("id", id, "str")}
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct and send request
        request = self._client.post(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("JobResponse", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    cancel_job.metadata = {"url": "/jobs/v2/{id}/cancel"}

    def query_jobs(
        self, job_type=None, job_status=None, custom_headers=None, raw=False, **operation_config
    ):
        """Query an IoT hub to retrieve information regarding jobs using the IoT
        Hub query language.

        Query an IoT hub to retrieve information regarding jobs using the IoT
        Hub query language. See
        https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-query-language
        for more information. Pagination of results is supported. This returns
        information about jobs only.

        :param job_type: Job Type.
        :type job_type: str
        :param job_status: Job Status.
        :type job_status: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: QueryResult or ClientRawResponse if raw=true
        :rtype: ~protocol.models.QueryResult or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.query_jobs.metadata["url"]

        # Construct parameters
        query_parameters = {}
        if job_type is not None:
            query_parameters["jobType"] = self._serialize.query("job_type", job_type, "str")
        if job_status is not None:
            query_parameters["jobStatus"] = self._serialize.query("job_status", job_status, "str")
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct and send request
        request = self._client.get(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("QueryResult", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    query_jobs.metadata = {"url": "/jobs/v2/query"}

    def get_modules_on_device(self, id, custom_headers=None, raw=False, **operation_config):
        """Retrieve all the module identities on the device.

        :param id: Device ID.
        :type id: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: list or ClientRawResponse if raw=true
        :rtype: list[~protocol.models.Module] or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.get_modules_on_device.metadata["url"]
        path_format_arguments = {"id": self._serialize.url("id", id, "str")}
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct and send request
        request = self._client.get(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("[Module]", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    get_modules_on_device.metadata = {"url": "/devices/{id}/modules"}

    def get_module(self, id, mid, custom_headers=None, raw=False, **operation_config):
        """Retrieve the specified module identity on the device.

        :param id: Device ID.
        :type id: str
        :param mid: Module ID.
        :type mid: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: Module or ClientRawResponse if raw=true
        :rtype: ~protocol.models.Module or ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.get_module.metadata["url"]
        path_format_arguments = {
            "id": self._serialize.url("id", id, "str"),
            "mid": self._serialize.url("mid", mid, "str"),
        }
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct and send request
        request = self._client.get(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("Module", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    get_module.metadata = {"url": "/devices/{id}/modules/{mid}"}

    def create_or_update_module(
        self, id, mid, module, if_match=None, custom_headers=None, raw=False, **operation_config
    ):
        """Create or update the module identity for device in IoT hub. An ETag
        must not be specified for the create operation. An ETag must be
        specified for the update operation. Note that moduleId and generation
        cannot be updated by the user.

        :param id: Device ID.
        :type id: str
        :param mid: Module ID.
        :type mid: str
        :param module:
        :type module: ~protocol.models.Module
        :param if_match:
        :type if_match: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: Module or ClientRawResponse if raw=true
        :rtype: ~protocol.models.Module or ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.create_or_update_module.metadata["url"]
        path_format_arguments = {
            "id": self._serialize.url("id", id, "str"),
            "mid": self._serialize.url("mid", mid, "str"),
        }
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        header_parameters["Content-Type"] = "application/json; charset=utf-8"
        if custom_headers:
            header_parameters.update(custom_headers)
        if if_match is not None:
            header_parameters["If-Match"] = self._serialize.header("if_match", if_match, "str")

        # Construct body
        body_content = self._serialize.body(module, "Module")

        # Construct and send request
        request = self._client.put(url, query_parameters, header_parameters, body_content)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200, 201]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("Module", response)
        if response.status_code == 201:
            deserialized = self._deserialize("Module", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    create_or_update_module.metadata = {"url": "/devices/{id}/modules/{mid}"}

    def delete_module(
        self, id, mid, if_match=None, custom_headers=None, raw=False, **operation_config
    ):
        """Delete the module identity for device of an IoT hub. This request
        requires the If-Match header. The client may specify the ETag for the
        device identity on the request in order to compare to the ETag
        maintained by the service for the purpose of optimistic concurrency.
        The delete operation is performed only if the ETag sent by the client
        matches the value maintained by the server, indicating that the device
        identity has not been modified since it was retrieved by the client. To
        force an unconditional delete, set If-Match to the wildcard character
        (*).

        :param id: Device ID.
        :type id: str
        :param mid: Module ID.
        :type mid: str
        :param if_match:
        :type if_match: str
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: None or ClientRawResponse if raw=true
        :rtype: None or ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.delete_module.metadata["url"]
        path_format_arguments = {
            "id": self._serialize.url("id", id, "str"),
            "mid": self._serialize.url("mid", mid, "str"),
        }
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        if custom_headers:
            header_parameters.update(custom_headers)
        if if_match is not None:
            header_parameters["If-Match"] = self._serialize.header("if_match", if_match, "str")

        # Construct and send request
        request = self._client.delete(url, query_parameters, header_parameters)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [204]:
            raise HttpOperationError(self._deserialize, response)

        if raw:
            client_raw_response = ClientRawResponse(None, response)
            return client_raw_response

    delete_module.metadata = {"url": "/devices/{id}/modules/{mid}"}

    def invoke_device_method(
        self, device_id, direct_method_request, custom_headers=None, raw=False, **operation_config
    ):
        """Invoke a direct method on a device.

        Invoke a direct method on a device. See
        https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-direct-methods
        for more information.

        :param device_id:
        :type device_id: str
        :param direct_method_request:
        :type direct_method_request: ~protocol.models.CloudToDeviceMethod
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: CloudToDeviceMethodResult or ClientRawResponse if raw=true
        :rtype: ~protocol.models.CloudToDeviceMethodResult or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.invoke_device_method.metadata["url"]
        path_format_arguments = {"deviceId": self._serialize.url("device_id", device_id, "str")}
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        header_parameters["Content-Type"] = "application/json; charset=utf-8"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct body
        body_content = self._serialize.body(direct_method_request, "CloudToDeviceMethod")

        # Construct and send request
        request = self._client.post(url, query_parameters, header_parameters, body_content)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("CloudToDeviceMethodResult", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    invoke_device_method.metadata = {"url": "/twins/{deviceId}/methods"}

    def invoke_device_module_method(
        self,
        device_id,
        module_id,
        direct_method_request,
        custom_headers=None,
        raw=False,
        **operation_config
    ):
        """Invoke a direct method on a module of a device.

        Invoke a direct method on a module of a device. See
        https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-direct-methods
        for more information.

        :param device_id:
        :type device_id: str
        :param module_id:
        :type module_id: str
        :param direct_method_request:
        :type direct_method_request: ~protocol.models.CloudToDeviceMethod
        :param dict custom_headers: headers that will be added to the request
        :param bool raw: returns the direct response alongside the
         deserialized response
        :param operation_config: :ref:`Operation configuration
         overrides<msrest:optionsforoperations>`.
        :return: CloudToDeviceMethodResult or ClientRawResponse if raw=true
        :rtype: ~protocol.models.CloudToDeviceMethodResult or
         ~msrest.pipeline.ClientRawResponse
        :raises:
         :class:`HttpOperationError<msrest.exceptions.HttpOperationError>`
        """
        # Construct URL
        url = self.invoke_device_module_method.metadata["url"]
        path_format_arguments = {
            "deviceId": self._serialize.url("device_id", device_id, "str"),
            "moduleId": self._serialize.url("module_id", module_id, "str"),
        }
        url = self._client.format_url(url, **path_format_arguments)

        # Construct parameters
        query_parameters = {}
        query_parameters["api-version"] = self._serialize.query(
            "self.api_version", self.api_version, "str"
        )

        # Construct headers
        header_parameters = {}
        header_parameters["Accept"] = "application/json"
        header_parameters["Content-Type"] = "application/json; charset=utf-8"
        if custom_headers:
            header_parameters.update(custom_headers)

        # Construct body
        body_content = self._serialize.body(direct_method_request, "CloudToDeviceMethod")

        # Construct and send request
        request = self._client.post(url, query_parameters, header_parameters, body_content)
        response = self._client.send(request, stream=False, **operation_config)

        if response.status_code not in [200]:
            raise HttpOperationError(self._deserialize, response)

        deserialized = None

        if response.status_code == 200:
            deserialized = self._deserialize("CloudToDeviceMethodResult", response)

        if raw:
            client_raw_response = ClientRawResponse(deserialized, response)
            return client_raw_response

        return deserialized

    invoke_device_module_method.metadata = {"url": "/twins/{deviceId}/modules/{moduleId}/methods"}
