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