Azure / azure-sdk-for-java

This repository is for active development of the Azure SDK for Java. For consumers of the SDK we recommend visiting our public developer docs at https://docs.microsoft.com/java/azure/ or our versioned developer docs at https://azure.github.io/azure-sdk-for-java.
MIT License
2.32k stars 1.97k forks source link

[BUG] Azure Queue Client Does Not Respect Encoding When Updating Message #40585

Closed tharsanrp closed 2 months ago

tharsanrp commented 3 months ago

Describe the bug When we configure the QueueClient with the message encoding of QueueMessageEncoding.BASE64, the updateMessage call does not encode the message to base64.

Exception or Stack Trace Add the exception log and stack trace if available

Exception in thread "main" java.lang.IllegalArgumentException: Illegal base64 character 2c
    at java.base/java.util.Base64$Decoder.decode0(Base64.java:852)
    at java.base/java.util.Base64$Decoder.decode(Base64.java:570)
    at java.base/java.util.Base64$Decoder.decode(Base64.java:593)
    at com.azure.storage.queue.implementation.util.ModelHelper.decodeMessageBody(ModelHelper.java:31)
    at com.azure.storage.queue.implementation.util.ModelHelper.transformPeekedMessageItemInternal(ModelHelper.java:64)
    at com.azure.storage.queue.QueueClient.transformMessagesPeekResponse(QueueClient.java:1177)
    at com.azure.storage.queue.QueueClient.peekMessagesWithOptionalTimeout(QueueClient.java:1156)
    at com.azure.storage.queue.QueueClient.peekMessages(QueueClient.java:1144)
    at org.example.MessageSamples.main(MessageSamples.java:47)

To Reproduce Steps to reproduce the behavior:

  1. Setup a client with base64 message encoding
  2. Push a message to the queue
  3. Update the content of the message

Code Snippet

package org.example;

import com.azure.core.util.CoreUtils;
import com.azure.storage.queue.QueueClient;
import com.azure.storage.queue.QueueMessageEncoding;
import com.azure.storage.queue.QueueServiceClient;
import com.azure.storage.queue.QueueServiceClientBuilder;
import java.time.Duration;

public class MessageSamples {

    private static final String CONNECTION_STRING = System.getenv("AZURE_STORAGE_CONNECTION_STRING");

    public static void main(String[] args) throws InterruptedException {
        QueueServiceClient queueServiceClient = new QueueServiceClientBuilder().connectionString(CONNECTION_STRING).messageEncoding(QueueMessageEncoding.BASE64).buildClient();

        // Create a queue client
        QueueClient queueClient = queueServiceClient.createQueue(generateRandomName("enqueue", 15));
        for (int i = 0; i < 3; i++) {
            queueClient.sendMessage("Hello World");
        }

        // Get the total count of msg in the queue
        int count = queueClient.getProperties().getApproximateMessagesCount();

        // Peek all messages in queue. It is supposed to print "Hello World" 3 times.
        queueClient.peekMessages(count, null, null).forEach(
            peekedMessage -> System.out.println("Here is the msg: " + peekedMessage.getBody().toString()));

        // Received all messages in queue and update the message "Hello World" to Hello, world!"
        queueClient.receiveMessages(count, Duration.ofSeconds(30), Duration.ofSeconds(50), null).forEach(
            queueMessage -> {
                String msgToReplace = "Hello, world!";
                queueClient.updateMessage(queueMessage.getMessageId(), queueMessage.getPopReceipt(),
                    msgToReplace, Duration.ZERO);
            }
        );

        queueClient.peekMessages(count, null, null).forEach(
            peekedMessage -> System.out.println("Here is the msg a second time: " + peekedMessage.getBody().toString()));

        Thread.sleep(500);
        queueClient.clearMessages();

        // Finally, we delete the queue.
        queueClient.delete();
    }

    static String generateRandomName(String prefix, int length) {
        int len = length > prefix.length() ? length - prefix.length() : 0;
        return prefix + CoreUtils.randomUuid().toString().substring(0, len);
    }
}

Expected behavior The client should encode the message to the configured message encoding in the client. Screenshots If applicable, add screenshots to help explain your problem.

Setup (please complete the following information):

Additional context Add any other context about the problem here.

Information Checklist Kindly make sure that you have added all the following information above and checkoff the required fields otherwise we will treat the issuer as an incomplete report

tharsanrp commented 3 months ago

I have also made a draft PR to fix the bug, but I am not sure how to add the Test Proxy json. https://github.com/Azure/azure-sdk-for-java/pull/40573

joshfree commented 3 months ago

@alzimmermsft could you please assist @tharsanrp in following up with the Storage SDK team?

alzimmermsft commented 3 months ago

Thanks for filing the PR @tharsanrp. It looks good, it'll just need some test updates. @seanmcc-msft could someone from the Storage SDK team help add test recordings for the newly added tests?

ibrahimrabab commented 2 months ago

@tharsanrp thanks for your PR! We were able to get your suggested changes in, will update on the thread once this change gets shipped.