Search in sources :

Example 1 with IotHubServiceException

use of com.microsoft.azure.sdk.iot.device.exceptions.IotHubServiceException in project azure-iot-sdk-java by Azure.

the class HttpsIotHubConnection method sendMessageResult.

/**
 * Sends the message result for the previously received
 * message.
 *
 * @param message the message that was received from the service to send the result of
 * @param result the message result (one of {@link IotHubMessageResult#COMPLETE},
 *               {@link IotHubMessageResult#ABANDON}, or {@link IotHubMessageResult#REJECT}).
 *
 * @throws TransportException if {@code sendMessageResult} is called before
 * {@link #receiveMessage()} is called.
 * @throws TransportException if the IoT Hub could not be reached.
 */
@Override
public boolean sendMessageResult(IotHubTransportMessage message, IotHubMessageResult result) throws TransportException {
    synchronized (HTTPS_CONNECTION_LOCK) {
        log.trace("Checking if http layer can correlate the received iot hub message to a received etag {}", message);
        String messageEtag = this.messageToETagMap.get(message);
        // Codes_SRS_HTTPSIOTHUBCONNECTION_11_039: [If the function is called before receiveMessage() returns a message, the function shall throw an IllegalStateException.]
        if (messageEtag == null) {
            throw new IllegalStateException("Cannot send a message " + "result before a message is received or if the result was already sent");
        }
        log.trace("Http layer correlated the received iot hub message ({}) to etag {}", message, messageEtag);
        log.trace("Sending ACK with result {} for etag {}", result, messageEtag);
        String iotHubHostname = getHostName();
        String deviceId = this.config.getDeviceId();
        String resultUri = HTTPS_HEAD_TAG;
        String resultPath;
        URL resultUrl;
        HttpsRequest request;
        switch(result) {
            case COMPLETE:
                // Codes_SRS_HTTPSIOTHUBCONNECTION_11_024: [If the result is COMPLETE, the function shall send a request to the URL 'https://[iotHubHostname]/devices/[deviceId]/messages/devicebound/[eTag]?api-version=2016-02-03'.]
                IotHubCompleteUri completeUri = new IotHubCompleteUri(iotHubHostname, deviceId, messageEtag, this.config.getModuleId());
                resultUri += completeUri.toString();
                // Codes_SRS_HTTPSIOTHUBCONNECTION_11_026: [If the result is COMPLETE, the function shall set the header field 'iothub-to' to be '/devices/[deviceId]/messages/devicebound/[eTag]'.]
                resultPath = completeUri.getPath();
                resultUrl = this.buildUrlFromString(resultUri);
                // Codes_SRS_HTTPSIOTHUBCONNECTION_11_025: [If the result is COMPLETE, the function shall send a DELETE request.]
                request = new HttpsRequest(resultUrl, HttpsMethod.DELETE, new byte[0], this.config.getProductInfo().getUserAgentString(), config.getProxySettings());
                break;
            case ABANDON:
                // Codes_SRS_HTTPSIOTHUBCONNECTION_11_027: [If the result is ABANDON, the function shall send a request to the URL 'https://[iotHubHostname]/devices/[deviceId]/messages/devicebound/[eTag]/abandon?api-version=2016-02-03'.]
                IotHubAbandonUri abandonUri = new IotHubAbandonUri(iotHubHostname, deviceId, messageEtag, this.config.getModuleId());
                resultUri += abandonUri.toString();
                // Codes_SRS_HTTPSIOTHUBCONNECTION_11_029: [If the result is ABANDON, the function shall set the header field 'iothub-to' to be '/devices/[deviceId]/messages/devicebound/[eTag]/abandon'.]
                resultPath = abandonUri.getPath();
                resultUrl = this.buildUrlFromString(resultUri);
                // Codes_SRS_HTTPSIOTHUBCONNECTION_11_028: [If the result is ABANDON, the function shall send a POST request.]
                // The IoT Hub service requires the content-length header to be
                // set but the Java SE connection omits content-length
                // if content-length == 0. We include a placeholder body to
                // make the connection include a content-length.
                request = new HttpsRequest(resultUrl, HttpsMethod.POST, new byte[1], this.config.getProductInfo().getUserAgentString(), config.getProxySettings());
                break;
            case REJECT:
                // Codes_SRS_HTTPSIOTHUBCONNECTION_11_030: [If the result is REJECT, the function shall send a request to the URL 'https://[iotHubHostname]/devices/[deviceId]/messages/devicebound/[eTag]??reject=true&api-version=2016-02-03' (the query parameters can be in any order).]
                IotHubRejectUri rejectUri = new IotHubRejectUri(iotHubHostname, deviceId, messageEtag, this.config.getModuleId());
                resultUri += rejectUri.toString();
                // Codes_SRS_HTTPSIOTHUBCONNECTION_11_032: [If the result is REJECT, the function shall set the header field 'iothub-to' to be '/devices/[deviceId]/messages/devicebound/[eTag]'.]
                resultPath = rejectUri.getPath();
                resultUrl = this.buildUrlFromString(resultUri);
                // Codes_SRS_HTTPSIOTHUBCONNECTION_11_031: [If the result is REJECT, the function shall send a DELETE request.]
                request = new HttpsRequest(resultUrl, HttpsMethod.DELETE, new byte[0], this.config.getProductInfo().getUserAgentString(), config.getProxySettings());
                break;
            default:
                // should never happen.
                throw new IllegalStateException("Invalid message result specified.");
        }
        request.setHeaderField(HTTPS_PROPERTY_IOTHUB_TO_TAG, resultPath).setHeaderField(HTTPS_PROPERTY_IF_MATCH_TAG, messageEtag);
        // Codes_SRS_HTTPSIOTHUBCONNECTION_34_062: [If this config is using x509 authentication, this function shall retrieve its sslcontext from its x509 Authentication object.]
        // Codes_SRS_HTTPSIOTHUBCONNECTION_25_042: [The function shall set the IotHub SSL context by calling setSSLContext on the request.]
        // Codes_SRS_HTTPSIOTHUBCONNECTION_11_034: [The function shall set the header field 'authorization' to be a valid SAS token generated from the configuration parameters.]
        // Codes_SRS_HTTPSIOTHUBCONNECTION_11_033: [The function shall set the request read timeout to be the configuration parameter readTimeoutMillis.]
        // Codes_SRS_HTTPSIOTHUBCONNECTION_11_037: [If the IoT Hub could not be reached, the function shall throw a ProtocolException.]
        HttpsResponse response = this.sendRequest(request);
        IotHubStatusCode resultStatus = IotHubStatusCode.getIotHubStatusCode(response.getStatus());
        if (resultStatus != IotHubStatusCode.OK_EMPTY && resultStatus != IotHubStatusCode.OK) {
            String errMsg = String.format("Sending message result failed with status %s.%n", resultStatus.name());
            // Codes_SRS_HTTPSIOTHUBCONNECTION_11_038: [If the IoT Hub status code in the response is not OK_EMPTY, the function shall throw an IotHubServiceException.]
            throw new IotHubServiceException(errMsg);
        } else {
            // Codes_SRS_HTTPSIOTHUBCONNECTION_34_069: [If the IoT Hub status code in the response is OK_EMPTY or OK, the function shall remove the sent eTag from its map and return true.]
            log.trace("Successfully sent ack for http message with etag {}. Removing it from saved list of outstanding messages to acknowledge", messageEtag);
            this.messageToETagMap.remove(message);
            return true;
        }
    }
}
Also used : IotHubServiceException(com.microsoft.azure.sdk.iot.device.exceptions.IotHubServiceException) URL(java.net.URL)

Example 2 with IotHubServiceException

use of com.microsoft.azure.sdk.iot.device.exceptions.IotHubServiceException in project azure-iot-sdk-java by Azure.

the class FileUploadTask method validateServiceStatusCode.

private String validateServiceStatusCode(ResponseMessage responseMessage, String errorMessage) throws IOException {
    String responseMessagePayload = null;
    if (responseMessage.getBytes() != null && responseMessage.getBytes().length > 0) {
        responseMessagePayload = new String(responseMessage.getBytes(), DEFAULT_IOTHUB_MESSAGE_CHARSET);
    }
    IotHubServiceException serviceException = IotHubStatusCode.getConnectionStatusException(responseMessage.getStatus(), responseMessagePayload);
    // serviceException is only not null if the provided status code was a non-successful status code like 400, 429, 500, etc.
    if (serviceException != null) {
        throw new IOException(errorMessage, serviceException);
    }
    return responseMessagePayload;
}
Also used : IotHubServiceException(com.microsoft.azure.sdk.iot.device.exceptions.IotHubServiceException) IOException(java.io.IOException)

Example 3 with IotHubServiceException

use of com.microsoft.azure.sdk.iot.device.exceptions.IotHubServiceException in project azure-iot-sdk-java by Azure.

the class MqttDeviceTwin method receive.

@Override
public IotHubTransportMessage receive() throws TransportException {
    synchronized (this.receivedMessagesLock) {
        IotHubTransportMessage message = null;
        Pair<String, byte[]> messagePair = this.receivedMessages.peek();
        if (messagePair != null) {
            String topic = messagePair.getKey();
            if (topic != null && topic.length() > 0) {
                if (topic.length() > TWIN.length() && topic.startsWith(TWIN)) {
                    byte[] data = messagePair.getValue();
                    // remove this message from the queue as this is the correct handler
                    this.receivedMessages.poll();
                    if (topic.length() > RES.length() && topic.startsWith(RES)) {
                        // Tokenize on backslash
                        String[] topicTokens = topic.split(Pattern.quote("/"));
                        if (data != null && data.length > 0) {
                            message = new IotHubTransportMessage(data, MessageType.DEVICE_TWIN);
                        } else {
                            // Case for $iothub/twin/res/{status}/?$rid={request id}
                            // empty body
                            message = new IotHubTransportMessage(new byte[0], MessageType.DEVICE_TWIN);
                        }
                        message.setDeviceOperationType(DeviceOperations.DEVICE_OPERATION_UNKNOWN);
                        // Case for $iothub/twin/res/{status}/?$rid={request id}&$version={new version}
                        if (topicTokens.length > STATUS_TOKEN) {
                            message.setStatus(getStatus(topicTokens[STATUS_TOKEN]));
                        } else {
                            this.throwDeviceTwinTransportException(new IotHubServiceException("Message received without status"));
                        }
                        if (topicTokens.length > REQID_TOKEN) {
                            String requestId = getRequestId(topicTokens[REQID_TOKEN]);
                            // MQTT does not have the concept of correlationId for request/response handling but it does have a requestId
                            // To handle this we are setting the correlationId to the requestId to better handle correlation
                            // whether we use MQTT or AMQP.
                            message.setRequestId(requestId);
                            message.setCorrelationId(requestId);
                            if (requestMap.containsKey(requestId)) {
                                switch(requestMap.remove(requestId)) {
                                    case DEVICE_OPERATION_TWIN_GET_REQUEST:
                                        message.setDeviceOperationType(DeviceOperations.DEVICE_OPERATION_TWIN_GET_RESPONSE);
                                        break;
                                    case DEVICE_OPERATION_TWIN_UPDATE_REPORTED_PROPERTIES_REQUEST:
                                        message.setDeviceOperationType(DeviceOperations.DEVICE_OPERATION_TWIN_UPDATE_REPORTED_PROPERTIES_RESPONSE);
                                        break;
                                    default:
                                        message.setDeviceOperationType(DeviceOperations.DEVICE_OPERATION_UNKNOWN);
                                }
                            } else {
                                this.throwDeviceTwinTransportException(new UnsupportedOperationException("Request Id is mandatory"));
                            }
                        }
                        if (topicTokens.length > VERSION_TOKEN) {
                            message.setVersion(getVersion(topicTokens[VERSION_TOKEN]));
                        }
                    } else if (topic.length() > PATCH.length() && topic.startsWith(PATCH)) {
                        if (topic.startsWith(PATCH + BACKSLASH + PROPERTIES + BACKSLASH + DESIRED)) {
                            if (data != null) {
                                message = new IotHubTransportMessage(data, MessageType.DEVICE_TWIN);
                                message.setDeviceOperationType(DeviceOperations.DEVICE_OPERATION_TWIN_SUBSCRIBE_DESIRED_PROPERTIES_RESPONSE);
                            } else {
                                this.throwDeviceTwinTransportException(new UnsupportedOperationException());
                            }
                            // Case for $iothub/twin/PATCH/properties/desired/?$version={new version}
                            // Tokenize on backslash
                            String[] topicTokens = topic.split(Pattern.quote("/"));
                            if (topicTokens.length > PATCH_VERSION_TOKEN) {
                                if (message != null) {
                                    message.setVersion(getVersion(topicTokens[PATCH_VERSION_TOKEN]));
                                }
                            }
                        } else {
                            this.throwDeviceTwinTransportException(new UnsupportedOperationException());
                        }
                    } else {
                        this.throwDeviceTwinTransportException(new UnsupportedOperationException());
                    }
                }
            }
        }
        return message;
    }
}
Also used : IotHubServiceException(com.microsoft.azure.sdk.iot.device.exceptions.IotHubServiceException) IotHubTransportMessage(com.microsoft.azure.sdk.iot.device.transport.IotHubTransportMessage)

Aggregations

IotHubServiceException (com.microsoft.azure.sdk.iot.device.exceptions.IotHubServiceException)3 IotHubTransportMessage (com.microsoft.azure.sdk.iot.device.transport.IotHubTransportMessage)1 IOException (java.io.IOException)1 URL (java.net.URL)1