Azure / azure-iot-sdk-java

A Java SDK for connecting devices to Microsoft Azure IoT services
https://azure.github.io/azure-iot-sdk-java/
Other
199 stars 236 forks source link

Unable to upload to Azure Blob Storage using version 12.11.1 #1224

Closed kjakubison closed 3 years ago

kjakubison commented 3 years ago

Description of the issue:

I will start by saying this issue is fixed if I downgrade 'azure-storage-blob' back to version 12.0.0. Provided below is the sample code in this sdk for a file upload example to blob storage. With the gradle setup below and code to follow, I am unable to upload an image to blob storage. The 3 errors for io.nettle appear immediately upon calling ' blobClient.uploadFromFile(file.absolutePath)'. Once the call times out, I will receive the UnknownHostError. I converted the sample code to kotlin and removed some unneeded code to further simplify the process for testing purposes and is called by button press on the main activity once the client is created & provisioned.

https://github.com/Azure/azure-iot-sdk-java/blob/master/device/iot-device-samples/file-upload-sample/src/main/java/samples/com/microsoft/azure/sdk/iot/FileUploadSample.java

Code sample exhibiting the issue:

Gradle File apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions'

android { compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } compileSdkVersion 29 buildToolsVersion "29.0.3" defaultConfig { applicationId "x" minSdkVersion 21 targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } }

dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'org.jetbrains.anko:anko-common:0.8.3' implementation 'com.github.felHR85:UsbSerial:6.1.0' implementation 'com.github.mik3y:usb-serial-for-android:2.1.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' implementation 'com.google.code.gson:gson:2.8.6'

implementation 'com.microsoft.azure.sdk.iot:iot-device-client:1.30.2'
implementation 'com.microsoft.azure.sdk.iot.provisioning:provisioning-device-client:1.8.7'
implementation group: 'com.microsoft.azure.sdk.iot', name: 'iot-deps', version: '0.13.0'
implementation group: 'com.azure', name: 'azure-storage-blob', version: '12.11.1'
implementation group: 'javax.xml.stream', name: 'stax-api', version: '1.0-2'

}

package appname

import android.util.Log import com.azure.storage.blob.BlobClient import com.azure.storage.blob.BlobClientBuilder import com.microsoft.azure.sdk.iot.deps.serializer.FileUploadCompletionNotification import com.microsoft.azure.sdk.iot.deps.serializer.FileUploadSasUriRequest import com.microsoft.azure.sdk.iot.device.DeviceClient import java.io.File

Modified version of the example provided, effectively the same as what is originally provided.

public fun uploadFileToBlobStorage(client: DeviceClient, baseDirectory: String, relativeFileName: String) {

    var relativeFileName = relativeFileName
    val file = File(baseDirectory)
    try {
        if (relativeFileName.startsWith("\\")) {
            relativeFileName = relativeFileName.substring(1)
        }
        val sasUriResponse = client.getFileUploadSasUri(FileUploadSasUriRequest(file.getName()))
        try {
            val blobClient: BlobClient = BlobClientBuilder()
                .endpoint(sasUriResponse.blobUri.toString())
                .buildClient()
            blobClient.uploadFromFile(file.absolutePath)
        } catch (e: Exception) {
            // Note that this is done even when the file upload fails. IoT Hub has a fixed number of SAS URIs allowed active
            // at any given time. Once you are done with the file upload, you should free your SAS URI so that other
            // SAS URIs can be generated. If a SAS URI is not freed through this API, then it will free itself eventually
            // based on how long SAS URIs are configured to live on your IoT Hub.
            val completionNotification =
                FileUploadCompletionNotification(sasUriResponse.correlationId, false)
            client.completeFileUpload(completionNotification)
            e.printStackTrace()
            return
        }
        val completionNotification =
            FileUploadCompletionNotification(sasUriResponse.correlationId, true)
        client.completeFileUpload(completionNotification)
    }catch (e : Exception){
        Log.e("AzureIot-FileUpload", e.message)
    } finally {
        //client.closeNow()
    }
}

Console log of the issue:

reactor.core.Exceptions$ReactiveException: java.net.UnknownHostException: failed to resolve 'blobstorage_id.blob.core.windows.net' after 2 queries

2021-05-28 10:42:38.827 27633-31988/com.example.app_nameE/e.app_name: No implementation found for int io.netty.internal.tcnative.Library.aprMajorVersion() (tried Java_io_netty_internal_tcnative_Library_aprMajorVersion and Java_io_netty_internal_tcnative_Library_aprMajorVersion__)

2021-05-28 10:42:38.849 27633-31988/com.example.app_nameE/e.app_name: No implementation found for int io.netty.channel.epoll.Native.offsetofEpollData() (tried Java_io_netty_channel_epoll_Native_offsetofEpollData and Java_io_netty_channel_epoll_Native_offsetofEpollData__)

2021-05-28 10:42:38.861 27633-31988/com.example.app_nameE/e.app_name: No implementation found for int io.netty.channel.kqueue.Native.sizeofKEvent() (tried Java_io_netty_channel_kqueue_Native_sizeofKEvent and Java_io_netty_channel_kqueue_Native_sizeofKEvent__)

azabbasi commented 3 years ago

@kjakubison Thank you for reaching out to us. It appears that the Azure Storage Blob client is the origin of the issue. Can you run the sample code and confirm that the FileUploadSasUri conforms to the following format? https://someblobstorage.blob.core.windows.net/fileupload/somedevice%2Fsomefilename.jpg?sv=2018-03-28&sr=b&sig=SoeKey4%3D&se=2021-06-02T00%3A47%3A07Z&sp=rw

If your blob uri endpoint is formatted correctly, and you are getting timed out, then the issue is originating from the storage SDK and we will help you get in touch with them since the hub sdk client is not involved in the stack trace.

azabbasi commented 3 years ago

BTW, since you are already following the sample code for file upload, you might have noticed that the upload APIs are directly invoking the storage client. So you can just use the storage SDK version that works best for you.

azabbasi commented 3 years ago

We will be closing this since the issue sees to be the storage client and you can use any flavor of the storage blob SDK to make the file upload as we have decoupled the IoT Hub Device SDK from the Storage SDK for File Upload Operations.

abhipsaMisra commented 3 years ago

Re-opening and closing to work around dashboard issue.

abhipsaMisra commented 3 years ago

Closing the issue.