浏览代码

Fix Azure InputStream#read method (#96034)

Francisco Fernández Castaño 2 年之前
父节点
当前提交
63e26ad48e

+ 5 - 0
docs/changelog/96034.yaml

@@ -0,0 +1,5 @@
+pr: 96034
+summary: Fix Azure `InputStream#read` method
+area: Snapshot/Restore
+type: bug
+issues: []

+ 23 - 0
modules/repository-azure/src/internalClusterTest/java/org/elasticsearch/repositories/azure/AzureBlobStoreRepositoryTests.java

@@ -16,6 +16,7 @@ import com.sun.net.httpserver.HttpExchange;
 import com.sun.net.httpserver.HttpHandler;
 
 import org.elasticsearch.common.Randomness;
+import org.elasticsearch.common.UUIDs;
 import org.elasticsearch.common.blobstore.BlobContainer;
 import org.elasticsearch.common.blobstore.BlobPath;
 import org.elasticsearch.common.blobstore.BlobStore;
@@ -30,6 +31,7 @@ import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.repositories.blobstore.ESMockAPIBasedRepositoryIntegTestCase;
 import org.elasticsearch.rest.RestStatus;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.NoSuchFileException;
@@ -44,6 +46,7 @@ import java.util.regex.Pattern;
 
 import static org.hamcrest.Matchers.anEmptyMap;
 import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.is;
 
 @SuppressForbidden(reason = "this test uses a HttpServer to emulate an Azure endpoint")
@@ -268,4 +271,24 @@ public class AzureBlobStoreRepositoryTests extends ESMockAPIBasedRepositoryInteg
             assertThat(exception.getMessage(), containsString("nested/dir/blob] not found"));
         }
     }
+
+    public void testReadByteByByte() throws Exception {
+        try (BlobStore store = newBlobStore()) {
+            BlobContainer container = store.blobContainer(BlobPath.EMPTY.add(UUIDs.randomBase64UUID()));
+            var data = randomBytes(randomIntBetween(128, 512));
+            String blobName = randomName();
+            container.writeBlob(blobName, new ByteArrayInputStream(data), data.length, true);
+
+            var originalDataInputStream = new ByteArrayInputStream(data);
+            try (var azureInputStream = container.readBlob(blobName)) {
+                for (int i = 0; i < data.length; i++) {
+                    assertThat(originalDataInputStream.read(), is(equalTo(azureInputStream.read())));
+                }
+
+                assertThat(azureInputStream.read(), is(equalTo(-1)));
+                assertThat(originalDataInputStream.read(), is(equalTo(-1)));
+            }
+            container.delete();
+        }
+    }
 }

+ 13 - 1
modules/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureBlobStore.java

@@ -714,7 +714,19 @@ public class AzureBlobStore implements BlobStore {
         @Override
         public int read() throws IOException {
             byte[] b = new byte[1];
-            return read(b, 0, 1);
+            var bytesRead = read(b, 0, 1);
+
+            if (bytesRead > 1) {
+                throw new IOException("Stream returned more data than requested");
+            }
+
+            if (bytesRead == 1) {
+                return b[0] & 0xFF;
+            } else if (bytesRead == 0) {
+                throw new IOException("Stream returned unexpected number of bytes");
+            } else {
+                return -1;
+            }
         }
 
         @Override