|
@@ -1,976 +0,0 @@
|
|
-/**
|
|
|
|
- * Licensed to the Apache Software Foundation (ASF) under one
|
|
|
|
- * or more contributor license agreements. See the NOTICE file
|
|
|
|
- * distributed with this work for additional information
|
|
|
|
- * regarding copyright ownership. The ASF licenses this file
|
|
|
|
- * to you under the Apache License, Version 2.0 ("License");
|
|
|
|
- * you may not use this file except in compliance with the License.
|
|
|
|
- * You may obtain a copy of the License at
|
|
|
|
- * <p>
|
|
|
|
- * http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
- * <p>
|
|
|
|
- * Unless required by applicable law or agreed to in writing, software
|
|
|
|
- * distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
- * See the License for the specific language governing permissions and
|
|
|
|
- * limitations under the License.
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
-package org.apache.hadoop.fs.azurebfs;
|
|
|
|
-
|
|
|
|
-import java.io.FileNotFoundException;
|
|
|
|
-import java.io.IOException;
|
|
|
|
-import java.nio.CharBuffer;
|
|
|
|
-import java.nio.charset.CharacterCodingException;
|
|
|
|
-import java.nio.charset.Charset;
|
|
|
|
-import java.nio.charset.CharsetEncoder;
|
|
|
|
-import java.nio.charset.StandardCharsets;
|
|
|
|
-import java.security.MessageDigest;
|
|
|
|
-import java.security.NoSuchAlgorithmException;
|
|
|
|
-import java.util.EnumSet;
|
|
|
|
-import java.util.Hashtable;
|
|
|
|
-import java.util.List;
|
|
|
|
-import java.util.Map;
|
|
|
|
-import java.util.Optional;
|
|
|
|
-import java.util.Random;
|
|
|
|
-import java.util.UUID;
|
|
|
|
-
|
|
|
|
-import org.apache.hadoop.fs.azurebfs.utils.TracingContext;
|
|
|
|
-import org.apache.hadoop.fs.contract.ContractTestUtils;
|
|
|
|
-import org.apache.hadoop.util.Preconditions;
|
|
|
|
-import org.apache.hadoop.util.Lists;
|
|
|
|
-import org.assertj.core.api.Assertions;
|
|
|
|
-import org.junit.Assume;
|
|
|
|
-import org.junit.Test;
|
|
|
|
-import org.slf4j.Logger;
|
|
|
|
-import org.slf4j.LoggerFactory;
|
|
|
|
-
|
|
|
|
-import org.apache.hadoop.conf.Configuration;
|
|
|
|
-import org.apache.hadoop.fs.FSDataInputStream;
|
|
|
|
-import org.apache.hadoop.fs.FSDataOutputStream;
|
|
|
|
-import org.apache.hadoop.fs.FileStatus;
|
|
|
|
-import org.apache.hadoop.fs.FileSystem;
|
|
|
|
-import org.apache.hadoop.fs.Path;
|
|
|
|
-import org.apache.hadoop.fs.XAttrSetFlag;
|
|
|
|
-import org.apache.hadoop.fs.azurebfs.constants.AbfsHttpConstants;
|
|
|
|
-import org.apache.hadoop.fs.azurebfs.constants.HttpHeaderConfigurations;
|
|
|
|
-import org.apache.hadoop.fs.azurebfs.contracts.services.AppendRequestParameters;
|
|
|
|
-import org.apache.hadoop.fs.azurebfs.contracts.services.AppendRequestParameters.Mode;
|
|
|
|
-import org.apache.hadoop.fs.azurebfs.services.AbfsAclHelper;
|
|
|
|
-import org.apache.hadoop.fs.azurebfs.services.AbfsClient;
|
|
|
|
-import org.apache.hadoop.fs.azurebfs.services.AbfsHttpHeader;
|
|
|
|
-import org.apache.hadoop.fs.azurebfs.services.AbfsHttpOperation;
|
|
|
|
-import org.apache.hadoop.fs.azurebfs.services.AbfsRestOperation;
|
|
|
|
-import org.apache.hadoop.fs.azurebfs.services.AuthType;
|
|
|
|
-import org.apache.hadoop.fs.azurebfs.utils.Base64;
|
|
|
|
-import org.apache.hadoop.fs.permission.AclEntry;
|
|
|
|
-import org.apache.hadoop.fs.permission.FsAction;
|
|
|
|
-import org.apache.hadoop.fs.permission.FsPermission;
|
|
|
|
-import org.apache.hadoop.test.LambdaTestUtils;
|
|
|
|
-
|
|
|
|
-import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.AZURE_CREATE_REMOTE_FILESYSTEM_DURING_INITIALIZATION;
|
|
|
|
-import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.FS_AZURE_CLIENT_PROVIDED_ENCRYPTION_KEY;
|
|
|
|
-import static org.apache.hadoop.fs.azurebfs.constants.FileSystemConfigurations.ONE_MB;
|
|
|
|
-import static org.apache.hadoop.fs.azurebfs.constants.HttpHeaderConfigurations.X_MS_ENCRYPTION_ALGORITHM;
|
|
|
|
-import static org.apache.hadoop.fs.azurebfs.constants.HttpHeaderConfigurations.X_MS_ENCRYPTION_KEY;
|
|
|
|
-import static org.apache.hadoop.fs.azurebfs.constants.HttpHeaderConfigurations.X_MS_ENCRYPTION_KEY_SHA256;
|
|
|
|
-import static org.apache.hadoop.fs.azurebfs.constants.HttpHeaderConfigurations.X_MS_REQUEST_SERVER_ENCRYPTED;
|
|
|
|
-import static org.apache.hadoop.fs.azurebfs.constants.HttpHeaderConfigurations.X_MS_SERVER_ENCRYPTED;
|
|
|
|
-import static org.apache.hadoop.fs.azurebfs.constants.TestConfigurationKeys.FS_AZURE_ABFS_ACCOUNT_NAME;
|
|
|
|
-import static org.apache.hadoop.fs.azurebfs.constants.TestConfigurationKeys.FS_AZURE_ACCOUNT_KEY;
|
|
|
|
-import static org.apache.hadoop.fs.azurebfs.constants.TestConfigurationKeys.FS_AZURE_TEST_CPK_ENABLED;
|
|
|
|
-import static org.apache.hadoop.fs.azurebfs.constants.TestConfigurationKeys.FS_AZURE_TEST_CPK_ENABLED_SECONDARY_ACCOUNT;
|
|
|
|
-import static org.apache.hadoop.fs.azurebfs.constants.TestConfigurationKeys.FS_AZURE_TEST_CPK_ENABLED_SECONDARY_ACCOUNT_KEY;
|
|
|
|
-import static org.apache.hadoop.fs.azurebfs.constants.TestConfigurationKeys.FS_AZURE_TEST_NAMESPACE_ENABLED_ACCOUNT;
|
|
|
|
-import static org.apache.hadoop.fs.azurebfs.constants.TestConfigurationKeys.TEST_CONFIGURATION_FILE_NAME;
|
|
|
|
-import static org.apache.hadoop.fs.azurebfs.utils.AclTestHelpers.aclEntry;
|
|
|
|
-import static org.apache.hadoop.fs.permission.AclEntryScope.ACCESS;
|
|
|
|
-import static org.apache.hadoop.fs.permission.AclEntryType.USER;
|
|
|
|
-import static org.apache.hadoop.fs.permission.FsAction.ALL;
|
|
|
|
-
|
|
|
|
-public class ITestCustomerProvidedKey extends AbstractAbfsIntegrationTest {
|
|
|
|
- private static final Logger LOG = LoggerFactory
|
|
|
|
- .getLogger(ITestCustomerProvidedKey.class);
|
|
|
|
-
|
|
|
|
- private static final String XMS_PROPERTIES_ENCODING = "ISO-8859-1";
|
|
|
|
- private static final int INT_512 = 512;
|
|
|
|
- private static final int INT_50 = 50;
|
|
|
|
- private static final int ENCRYPTION_KEY_LEN = 32;
|
|
|
|
- private static final int FILE_SIZE = 10 * ONE_MB;
|
|
|
|
- private static final int FILE_SIZE_FOR_COPY_BETWEEN_ACCOUNTS = 24 * ONE_MB;
|
|
|
|
-
|
|
|
|
- private boolean isNamespaceEnabled;
|
|
|
|
-
|
|
|
|
- public ITestCustomerProvidedKey() throws Exception {
|
|
|
|
- boolean isCPKTestsEnabled = getConfiguration()
|
|
|
|
- .getBoolean(FS_AZURE_TEST_CPK_ENABLED, false);
|
|
|
|
- Assume.assumeTrue(isCPKTestsEnabled);
|
|
|
|
- isNamespaceEnabled = getConfiguration()
|
|
|
|
- .getBoolean(FS_AZURE_TEST_NAMESPACE_ENABLED_ACCOUNT, false);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private String getFileName() throws IOException {
|
|
|
|
- return path("/" + methodName.getMethodName()).toUri().getPath();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testReadWithCPK() throws Exception {
|
|
|
|
- final AzureBlobFileSystem fs = getAbfs(true);
|
|
|
|
- String fileName = getFileName();
|
|
|
|
- createFileAndGetContent(fs, fileName, FILE_SIZE);
|
|
|
|
-
|
|
|
|
- AbfsClient abfsClient = fs.getAbfsClient();
|
|
|
|
- int length = FILE_SIZE;
|
|
|
|
- byte[] buffer = new byte[length];
|
|
|
|
- TracingContext tracingContext = getTestTracingContext(fs, false);
|
|
|
|
- final AbfsRestOperation op = abfsClient.getPathStatus(fileName, false,
|
|
|
|
- tracingContext);
|
|
|
|
- final String eTag = op.getResult()
|
|
|
|
- .getResponseHeader(HttpHeaderConfigurations.ETAG);
|
|
|
|
- AbfsRestOperation abfsRestOperation = abfsClient
|
|
|
|
- .read(fileName, 0, buffer, 0, length, eTag, null, tracingContext);
|
|
|
|
- assertCPKHeaders(abfsRestOperation, true);
|
|
|
|
- assertResponseHeader(abfsRestOperation, true, X_MS_ENCRYPTION_KEY_SHA256,
|
|
|
|
- getCPKSha(fs));
|
|
|
|
- assertResponseHeader(abfsRestOperation, true, X_MS_SERVER_ENCRYPTED,
|
|
|
|
- "true");
|
|
|
|
- assertResponseHeader(abfsRestOperation, false,
|
|
|
|
- X_MS_REQUEST_SERVER_ENCRYPTED, "");
|
|
|
|
-
|
|
|
|
- // Trying to read with different CPK headers
|
|
|
|
- Configuration conf = fs.getConf();
|
|
|
|
- String accountName = conf.get(FS_AZURE_ABFS_ACCOUNT_NAME);
|
|
|
|
- conf.set(FS_AZURE_CLIENT_PROVIDED_ENCRYPTION_KEY + "." + accountName,
|
|
|
|
- "different-1234567890123456789012");
|
|
|
|
- try (AzureBlobFileSystem fs2 = (AzureBlobFileSystem) FileSystem.newInstance(conf);
|
|
|
|
- FSDataInputStream iStream = fs2.open(new Path(fileName))) {
|
|
|
|
- int len = 8 * ONE_MB;
|
|
|
|
- byte[] b = new byte[len];
|
|
|
|
- LambdaTestUtils.intercept(IOException.class, () -> {
|
|
|
|
- iStream.read(b, 0, len);
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Trying to read with no CPK headers
|
|
|
|
- conf.unset(FS_AZURE_CLIENT_PROVIDED_ENCRYPTION_KEY + "." + accountName);
|
|
|
|
- try (AzureBlobFileSystem fs3 = (AzureBlobFileSystem) FileSystem
|
|
|
|
- .get(conf); FSDataInputStream iStream = fs3.open(new Path(fileName))) {
|
|
|
|
- int len = 8 * ONE_MB;
|
|
|
|
- byte[] b = new byte[len];
|
|
|
|
- LambdaTestUtils.intercept(IOException.class, () -> {
|
|
|
|
- iStream.read(b, 0, len);
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testReadWithoutCPK() throws Exception {
|
|
|
|
- final AzureBlobFileSystem fs = getAbfs(false);
|
|
|
|
- String fileName = getFileName();
|
|
|
|
- createFileAndGetContent(fs, fileName, FILE_SIZE);
|
|
|
|
-
|
|
|
|
- AbfsClient abfsClient = fs.getAbfsClient();
|
|
|
|
- int length = INT_512;
|
|
|
|
- byte[] buffer = new byte[length * 4];
|
|
|
|
- TracingContext tracingContext = getTestTracingContext(fs, false);
|
|
|
|
- final AbfsRestOperation op = abfsClient
|
|
|
|
- .getPathStatus(fileName, false, tracingContext);
|
|
|
|
- final String eTag = op.getResult()
|
|
|
|
- .getResponseHeader(HttpHeaderConfigurations.ETAG);
|
|
|
|
- AbfsRestOperation abfsRestOperation = abfsClient
|
|
|
|
- .read(fileName, 0, buffer, 0, length, eTag, null, tracingContext);
|
|
|
|
- assertCPKHeaders(abfsRestOperation, false);
|
|
|
|
- assertResponseHeader(abfsRestOperation, false, X_MS_ENCRYPTION_KEY_SHA256,
|
|
|
|
- getCPKSha(fs));
|
|
|
|
- assertResponseHeader(abfsRestOperation, true, X_MS_SERVER_ENCRYPTED,
|
|
|
|
- "true");
|
|
|
|
- assertResponseHeader(abfsRestOperation, false,
|
|
|
|
- X_MS_REQUEST_SERVER_ENCRYPTED, "");
|
|
|
|
-
|
|
|
|
- // Trying to read with CPK headers
|
|
|
|
- Configuration conf = fs.getConf();
|
|
|
|
- String accountName = conf.get(FS_AZURE_ABFS_ACCOUNT_NAME);
|
|
|
|
- conf.set(FS_AZURE_CLIENT_PROVIDED_ENCRYPTION_KEY + "." + accountName,
|
|
|
|
- "12345678901234567890123456789012");
|
|
|
|
-
|
|
|
|
- try (AzureBlobFileSystem fs2 = (AzureBlobFileSystem) FileSystem.newInstance(conf);
|
|
|
|
- AbfsClient abfsClient2 = fs2.getAbfsClient()) {
|
|
|
|
- LambdaTestUtils.intercept(IOException.class, () -> {
|
|
|
|
- abfsClient2.read(fileName, 0, buffer, 0, length, eTag, null,
|
|
|
|
- getTestTracingContext(fs, false));
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testAppendWithCPK() throws Exception {
|
|
|
|
- final AzureBlobFileSystem fs = getAbfs(true);
|
|
|
|
- final String fileName = getFileName();
|
|
|
|
- createFileAndGetContent(fs, fileName, FILE_SIZE);
|
|
|
|
-
|
|
|
|
- // Trying to append with correct CPK headers
|
|
|
|
- AppendRequestParameters appendRequestParameters =
|
|
|
|
- new AppendRequestParameters(
|
|
|
|
- 0, 0, 5, Mode.APPEND_MODE, false, null, true);
|
|
|
|
- byte[] buffer = getRandomBytesArray(5);
|
|
|
|
- AbfsClient abfsClient = fs.getAbfsClient();
|
|
|
|
- AbfsRestOperation abfsRestOperation = abfsClient
|
|
|
|
- .append(fileName, buffer, appendRequestParameters, null, getTestTracingContext(fs, false));
|
|
|
|
- assertCPKHeaders(abfsRestOperation, true);
|
|
|
|
- assertResponseHeader(abfsRestOperation, true, X_MS_ENCRYPTION_KEY_SHA256,
|
|
|
|
- getCPKSha(fs));
|
|
|
|
- assertResponseHeader(abfsRestOperation, false, X_MS_SERVER_ENCRYPTED, "");
|
|
|
|
- assertResponseHeader(abfsRestOperation, true, X_MS_REQUEST_SERVER_ENCRYPTED,
|
|
|
|
- "true");
|
|
|
|
-
|
|
|
|
- // Trying to append with different CPK headers
|
|
|
|
- Configuration conf = fs.getConf();
|
|
|
|
- String accountName = conf.get(FS_AZURE_ABFS_ACCOUNT_NAME);
|
|
|
|
- conf.set(FS_AZURE_CLIENT_PROVIDED_ENCRYPTION_KEY + "." + accountName,
|
|
|
|
- "different-1234567890123456789012");
|
|
|
|
- try (AzureBlobFileSystem fs2 = (AzureBlobFileSystem) FileSystem.newInstance(conf);
|
|
|
|
- AbfsClient abfsClient2 = fs2.getAbfsClient()) {
|
|
|
|
- LambdaTestUtils.intercept(IOException.class, () -> {
|
|
|
|
- abfsClient2.append(fileName, buffer, appendRequestParameters, null,
|
|
|
|
- getTestTracingContext(fs, false));
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Trying to append with no CPK headers
|
|
|
|
- conf.unset(FS_AZURE_CLIENT_PROVIDED_ENCRYPTION_KEY + "." + accountName);
|
|
|
|
- try (AzureBlobFileSystem fs3 = (AzureBlobFileSystem) FileSystem
|
|
|
|
- .get(conf); AbfsClient abfsClient3 = fs3.getAbfsClient()) {
|
|
|
|
- LambdaTestUtils.intercept(IOException.class, () -> {
|
|
|
|
- abfsClient3.append(fileName, buffer, appendRequestParameters, null,
|
|
|
|
- getTestTracingContext(fs, false));
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testAppendWithoutCPK() throws Exception {
|
|
|
|
- final AzureBlobFileSystem fs = getAbfs(false);
|
|
|
|
- final String fileName = getFileName();
|
|
|
|
- createFileAndGetContent(fs, fileName, FILE_SIZE);
|
|
|
|
-
|
|
|
|
- // Trying to append without CPK headers
|
|
|
|
- AppendRequestParameters appendRequestParameters =
|
|
|
|
- new AppendRequestParameters(
|
|
|
|
- 0, 0, 5, Mode.APPEND_MODE, false, null, true);
|
|
|
|
- byte[] buffer = getRandomBytesArray(5);
|
|
|
|
- AbfsClient abfsClient = fs.getAbfsClient();
|
|
|
|
- AbfsRestOperation abfsRestOperation = abfsClient
|
|
|
|
- .append(fileName, buffer, appendRequestParameters, null,
|
|
|
|
- getTestTracingContext(fs, false));
|
|
|
|
- assertCPKHeaders(abfsRestOperation, false);
|
|
|
|
- assertResponseHeader(abfsRestOperation, false, X_MS_ENCRYPTION_KEY_SHA256,
|
|
|
|
- "");
|
|
|
|
- assertResponseHeader(abfsRestOperation, false, X_MS_SERVER_ENCRYPTED, "");
|
|
|
|
- assertResponseHeader(abfsRestOperation, true, X_MS_REQUEST_SERVER_ENCRYPTED,
|
|
|
|
- "true");
|
|
|
|
-
|
|
|
|
- // Trying to append with CPK headers
|
|
|
|
- Configuration conf = fs.getConf();
|
|
|
|
- String accountName = conf.get(FS_AZURE_ABFS_ACCOUNT_NAME);
|
|
|
|
- conf.set(FS_AZURE_CLIENT_PROVIDED_ENCRYPTION_KEY + "." + accountName,
|
|
|
|
- "12345678901234567890123456789012");
|
|
|
|
- try (AzureBlobFileSystem fs2 = (AzureBlobFileSystem) FileSystem.newInstance(conf);
|
|
|
|
- AbfsClient abfsClient2 = fs2.getAbfsClient()) {
|
|
|
|
- LambdaTestUtils.intercept(IOException.class, () -> {
|
|
|
|
- abfsClient2.append(fileName, buffer, appendRequestParameters, null,
|
|
|
|
- getTestTracingContext(fs, false));
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testSetGetXAttr() throws Exception {
|
|
|
|
- final AzureBlobFileSystem fs = getAbfs(true);
|
|
|
|
- final String fileName = getFileName();
|
|
|
|
- createFileAndGetContent(fs, fileName, FILE_SIZE);
|
|
|
|
-
|
|
|
|
- String valSent = "testValue";
|
|
|
|
- String attrName = "testXAttr";
|
|
|
|
-
|
|
|
|
- // set get and verify
|
|
|
|
- fs.setXAttr(new Path(fileName), attrName,
|
|
|
|
- valSent.getBytes(StandardCharsets.UTF_8),
|
|
|
|
- EnumSet.of(XAttrSetFlag.CREATE));
|
|
|
|
- byte[] valBytes = fs.getXAttr(new Path(fileName), attrName);
|
|
|
|
- String valRecieved = new String(valBytes);
|
|
|
|
- assertEquals(valSent, valRecieved);
|
|
|
|
-
|
|
|
|
- // set new value get and verify
|
|
|
|
- valSent = "new value";
|
|
|
|
- fs.setXAttr(new Path(fileName), attrName,
|
|
|
|
- valSent.getBytes(StandardCharsets.UTF_8),
|
|
|
|
- EnumSet.of(XAttrSetFlag.REPLACE));
|
|
|
|
- valBytes = fs.getXAttr(new Path(fileName), attrName);
|
|
|
|
- valRecieved = new String(valBytes);
|
|
|
|
- assertEquals(valSent, valRecieved);
|
|
|
|
-
|
|
|
|
- // Read without CPK header
|
|
|
|
- LambdaTestUtils.intercept(IOException.class, () -> {
|
|
|
|
- getAbfs(false).getXAttr(new Path(fileName), attrName);
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- // Wrong CPK
|
|
|
|
- LambdaTestUtils.intercept(IOException.class, () -> {
|
|
|
|
- getSameFSWithWrongCPK(fs).getXAttr(new Path(fileName), attrName);
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testCopyBetweenAccounts() throws Exception {
|
|
|
|
- String accountName = getRawConfiguration()
|
|
|
|
- .get(FS_AZURE_TEST_CPK_ENABLED_SECONDARY_ACCOUNT);
|
|
|
|
- String accountKey = getRawConfiguration()
|
|
|
|
- .get(FS_AZURE_TEST_CPK_ENABLED_SECONDARY_ACCOUNT_KEY);
|
|
|
|
- Assume.assumeTrue(accountName != null && !accountName.isEmpty());
|
|
|
|
- Assume.assumeTrue(accountKey != null && !accountKey.isEmpty());
|
|
|
|
- String fileSystemName = "cpkfs";
|
|
|
|
-
|
|
|
|
- // Create fs1 and a file with CPK
|
|
|
|
- AzureBlobFileSystem fs1 = getAbfs(true);
|
|
|
|
- int fileSize = FILE_SIZE_FOR_COPY_BETWEEN_ACCOUNTS;
|
|
|
|
- byte[] fileContent = getRandomBytesArray(fileSize);
|
|
|
|
- Path testFilePath = createFileWithContent(fs1,
|
|
|
|
- String.format("fs1-file%s.txt", UUID.randomUUID()), fileContent);
|
|
|
|
-
|
|
|
|
- // Create fs2 with different CPK
|
|
|
|
- Configuration conf = new Configuration();
|
|
|
|
- conf.addResource(TEST_CONFIGURATION_FILE_NAME);
|
|
|
|
- conf.setBoolean(AZURE_CREATE_REMOTE_FILESYSTEM_DURING_INITIALIZATION, true);
|
|
|
|
- conf.unset(FS_AZURE_ABFS_ACCOUNT_NAME);
|
|
|
|
- conf.set(FS_AZURE_ABFS_ACCOUNT_NAME, accountName);
|
|
|
|
- conf.set(FS_AZURE_ACCOUNT_KEY + "." + accountName, accountKey);
|
|
|
|
- conf.set(FS_AZURE_CLIENT_PROVIDED_ENCRYPTION_KEY + "." + accountName,
|
|
|
|
- "123456789012345678901234567890ab");
|
|
|
|
- conf.set("fs.defaultFS", "abfs://" + fileSystemName + "@" + accountName);
|
|
|
|
- AzureBlobFileSystem fs2 = (AzureBlobFileSystem) FileSystem.newInstance(conf);
|
|
|
|
-
|
|
|
|
- // Read from fs1 and write to fs2, fs1 and fs2 are having different CPK
|
|
|
|
- Path fs2DestFilePath = new Path(
|
|
|
|
- String.format("fs2-dest-file%s.txt", UUID.randomUUID()));
|
|
|
|
- FSDataOutputStream ops = fs2.create(fs2DestFilePath);
|
|
|
|
- try (FSDataInputStream iStream = fs1.open(testFilePath)) {
|
|
|
|
- long totalBytesRead = 0;
|
|
|
|
- do {
|
|
|
|
- int length = 8 * ONE_MB;
|
|
|
|
- byte[] buffer = new byte[length];
|
|
|
|
- int bytesRead = iStream.read(buffer, 0, length);
|
|
|
|
- totalBytesRead += bytesRead;
|
|
|
|
- ops.write(buffer);
|
|
|
|
- } while (totalBytesRead < fileContent.length);
|
|
|
|
- ops.close();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Trying to read fs2DestFilePath with different CPK headers
|
|
|
|
- conf.unset(FS_AZURE_CLIENT_PROVIDED_ENCRYPTION_KEY + "." + accountName);
|
|
|
|
- conf.set(FS_AZURE_CLIENT_PROVIDED_ENCRYPTION_KEY + "." + accountName,
|
|
|
|
- "different-1234567890123456789012");
|
|
|
|
- try (AzureBlobFileSystem fs3 = (AzureBlobFileSystem) FileSystem
|
|
|
|
- .get(conf); FSDataInputStream iStream = fs3.open(fs2DestFilePath)) {
|
|
|
|
- int length = 8 * ONE_MB;
|
|
|
|
- byte[] buffer = new byte[length];
|
|
|
|
- LambdaTestUtils.intercept(IOException.class, () -> {
|
|
|
|
- iStream.read(buffer, 0, length);
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Trying to read fs2DestFilePath with no CPK headers
|
|
|
|
- conf.unset(FS_AZURE_CLIENT_PROVIDED_ENCRYPTION_KEY + "." + accountName);
|
|
|
|
- try (AzureBlobFileSystem fs4 = (AzureBlobFileSystem) FileSystem
|
|
|
|
- .get(conf); FSDataInputStream iStream = fs4.open(fs2DestFilePath)) {
|
|
|
|
- int length = 8 * ONE_MB;
|
|
|
|
- byte[] buffer = new byte[length];
|
|
|
|
- LambdaTestUtils.intercept(IOException.class, () -> {
|
|
|
|
- iStream.read(buffer, 0, length);
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Read fs2DestFilePath and verify the content with the initial random
|
|
|
|
- // bytes created and wrote into the source file at fs1
|
|
|
|
- try (FSDataInputStream iStream = fs2.open(fs2DestFilePath)) {
|
|
|
|
- long totalBytesRead = 0;
|
|
|
|
- int pos = 0;
|
|
|
|
- do {
|
|
|
|
- int length = 8 * ONE_MB;
|
|
|
|
- byte[] buffer = new byte[length];
|
|
|
|
- int bytesRead = iStream.read(buffer, 0, length);
|
|
|
|
- totalBytesRead += bytesRead;
|
|
|
|
- for (int i = 0; i < bytesRead; i++) {
|
|
|
|
- assertEquals(fileContent[pos + i], buffer[i]);
|
|
|
|
- }
|
|
|
|
- pos = pos + bytesRead;
|
|
|
|
- } while (totalBytesRead < fileContent.length);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testListPathWithCPK() throws Exception {
|
|
|
|
- testListPath(true);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testListPathWithoutCPK() throws Exception {
|
|
|
|
- testListPath(false);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void testListPath(final boolean isWithCPK) throws Exception {
|
|
|
|
- final AzureBlobFileSystem fs = getAbfs(isWithCPK);
|
|
|
|
- final Path testPath = path("/" + methodName.getMethodName());
|
|
|
|
- String testDirName = testPath.toUri().getPath();
|
|
|
|
- fs.mkdirs(testPath);
|
|
|
|
- createFileAndGetContent(fs, testDirName + "/aaa", FILE_SIZE);
|
|
|
|
- createFileAndGetContent(fs, testDirName + "/bbb", FILE_SIZE);
|
|
|
|
- AbfsClient abfsClient = fs.getAbfsClient();
|
|
|
|
- AbfsRestOperation abfsRestOperation = abfsClient
|
|
|
|
- .listPath(testDirName, false, INT_50, null,
|
|
|
|
- getTestTracingContext(fs, false));
|
|
|
|
- assertListstatus(fs, abfsRestOperation, testPath);
|
|
|
|
-
|
|
|
|
- // Trying with different CPK headers
|
|
|
|
- Configuration conf = fs.getConf();
|
|
|
|
- String accountName = conf.get(FS_AZURE_ABFS_ACCOUNT_NAME);
|
|
|
|
- conf.set(FS_AZURE_CLIENT_PROVIDED_ENCRYPTION_KEY + "." + accountName,
|
|
|
|
- "different-1234567890123456789012");
|
|
|
|
- AzureBlobFileSystem fs2 = (AzureBlobFileSystem) FileSystem.newInstance(conf);
|
|
|
|
- AbfsClient abfsClient2 = fs2.getAbfsClient();
|
|
|
|
- TracingContext tracingContext = getTestTracingContext(fs, false);
|
|
|
|
- abfsRestOperation = abfsClient2.listPath(testDirName, false, INT_50,
|
|
|
|
- null, tracingContext);
|
|
|
|
- assertListstatus(fs, abfsRestOperation, testPath);
|
|
|
|
-
|
|
|
|
- if (isWithCPK) {
|
|
|
|
- // Trying with no CPK headers
|
|
|
|
- conf.unset(FS_AZURE_CLIENT_PROVIDED_ENCRYPTION_KEY + "." + accountName);
|
|
|
|
- AzureBlobFileSystem fs3 = (AzureBlobFileSystem) FileSystem.get(conf);
|
|
|
|
- AbfsClient abfsClient3 = fs3.getAbfsClient();
|
|
|
|
- abfsRestOperation = abfsClient3
|
|
|
|
- .listPath(testDirName, false, INT_50, null, tracingContext);
|
|
|
|
- assertListstatus(fs, abfsRestOperation, testPath);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void assertListstatus(AzureBlobFileSystem fs,
|
|
|
|
- AbfsRestOperation abfsRestOperation, Path testPath) throws IOException {
|
|
|
|
- assertCPKHeaders(abfsRestOperation, false);
|
|
|
|
- assertNoCPKResponseHeadersPresent(abfsRestOperation);
|
|
|
|
-
|
|
|
|
- FileStatus[] listStatuses = fs.listStatus(testPath);
|
|
|
|
- Assertions.assertThat(listStatuses.length)
|
|
|
|
- .describedAs("listStatuses should have 2 entries").isEqualTo(2);
|
|
|
|
-
|
|
|
|
- listStatuses = getSameFSWithWrongCPK(fs).listStatus(testPath);
|
|
|
|
- Assertions.assertThat(listStatuses.length)
|
|
|
|
- .describedAs("listStatuses should have 2 entries").isEqualTo(2);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testCreatePathWithCPK() throws Exception {
|
|
|
|
- testCreatePath(true);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testCreatePathWithoutCPK() throws Exception {
|
|
|
|
- testCreatePath(false);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void testCreatePath(final boolean isWithCPK) throws Exception {
|
|
|
|
- final AzureBlobFileSystem fs = getAbfs(isWithCPK);
|
|
|
|
- final String testFileName = getFileName();
|
|
|
|
- createFileAndGetContent(fs, testFileName, FILE_SIZE);
|
|
|
|
-
|
|
|
|
- AbfsClient abfsClient = fs.getAbfsClient();
|
|
|
|
- FsPermission permission = new FsPermission(FsAction.EXECUTE,
|
|
|
|
- FsAction.EXECUTE, FsAction.EXECUTE);
|
|
|
|
- FsPermission umask = new FsPermission(FsAction.NONE, FsAction.NONE,
|
|
|
|
- FsAction.NONE);
|
|
|
|
- TracingContext tracingContext = getTestTracingContext(fs, false);
|
|
|
|
- boolean isNamespaceEnabled = fs.getIsNamespaceEnabled(tracingContext);
|
|
|
|
- AbfsRestOperation abfsRestOperation = abfsClient
|
|
|
|
- .createPath(testFileName, true, true,
|
|
|
|
- isNamespaceEnabled ? getOctalNotation(permission) : null,
|
|
|
|
- isNamespaceEnabled ? getOctalNotation(umask) : null, false, null,
|
|
|
|
- tracingContext);
|
|
|
|
- assertCPKHeaders(abfsRestOperation, isWithCPK);
|
|
|
|
- assertResponseHeader(abfsRestOperation, isWithCPK,
|
|
|
|
- X_MS_ENCRYPTION_KEY_SHA256, getCPKSha(fs));
|
|
|
|
- assertResponseHeader(abfsRestOperation, false, X_MS_SERVER_ENCRYPTED, "");
|
|
|
|
- assertResponseHeader(abfsRestOperation, true, X_MS_REQUEST_SERVER_ENCRYPTED,
|
|
|
|
- "true");
|
|
|
|
-
|
|
|
|
- FileStatus[] listStatuses = fs.listStatus(new Path(testFileName));
|
|
|
|
- Assertions.assertThat(listStatuses.length)
|
|
|
|
- .describedAs("listStatuses should have 1 entry").isEqualTo(1);
|
|
|
|
-
|
|
|
|
- listStatuses = getSameFSWithWrongCPK(fs).listStatus(new Path(testFileName));
|
|
|
|
- Assertions.assertThat(listStatuses.length)
|
|
|
|
- .describedAs("listStatuses should have 1 entry").isEqualTo(1);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testRenamePathWithCPK() throws Exception {
|
|
|
|
- testRenamePath(true);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testRenamePathWithoutCPK() throws Exception {
|
|
|
|
- testRenamePath(false);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void testRenamePath(final boolean isWithCPK) throws Exception {
|
|
|
|
- final AzureBlobFileSystem fs = getAbfs(isWithCPK);
|
|
|
|
- final String testFileName = getFileName();
|
|
|
|
- createFileAndGetContent(fs, testFileName, FILE_SIZE);
|
|
|
|
-
|
|
|
|
- FileStatus fileStatusBeforeRename = fs
|
|
|
|
- .getFileStatus(new Path(testFileName));
|
|
|
|
-
|
|
|
|
- String newName = "/newName";
|
|
|
|
- AbfsClient abfsClient = fs.getAbfsClient();
|
|
|
|
- AbfsRestOperation abfsRestOperation = abfsClient
|
|
|
|
- .renamePath(testFileName, newName, null,
|
|
|
|
- getTestTracingContext(fs, false), null, false, isNamespaceEnabled)
|
|
|
|
- .getOp();
|
|
|
|
- assertCPKHeaders(abfsRestOperation, false);
|
|
|
|
- assertNoCPKResponseHeadersPresent(abfsRestOperation);
|
|
|
|
-
|
|
|
|
- LambdaTestUtils.intercept(FileNotFoundException.class,
|
|
|
|
- (() -> fs.getFileStatus(new Path(testFileName))));
|
|
|
|
-
|
|
|
|
- FileStatus fileStatusAfterRename = fs.getFileStatus(new Path(newName));
|
|
|
|
- Assertions.assertThat(fileStatusAfterRename.getLen())
|
|
|
|
- .describedAs("File size has to be same before and after rename")
|
|
|
|
- .isEqualTo(fileStatusBeforeRename.getLen());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testFlushWithCPK() throws Exception {
|
|
|
|
- testFlush(true);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testFlushWithoutCPK() throws Exception {
|
|
|
|
- testFlush(false);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void testFlush(final boolean isWithCPK) throws Exception {
|
|
|
|
- final AzureBlobFileSystem fs = getAbfs(isWithCPK);
|
|
|
|
- final String testFileName = getFileName();
|
|
|
|
- fs.create(new Path(testFileName)).close();
|
|
|
|
- AbfsClient abfsClient = fs.getAbfsClient();
|
|
|
|
- String expectedCPKSha = getCPKSha(fs);
|
|
|
|
-
|
|
|
|
- byte[] fileContent = getRandomBytesArray(FILE_SIZE);
|
|
|
|
- Path testFilePath = new Path(testFileName + "1");
|
|
|
|
- try (FSDataOutputStream oStream = fs.create(testFilePath)) {
|
|
|
|
- oStream.write(fileContent);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Trying to read with different CPK headers
|
|
|
|
- Configuration conf = fs.getConf();
|
|
|
|
- String accountName = conf.get(FS_AZURE_ABFS_ACCOUNT_NAME);
|
|
|
|
- conf.set(FS_AZURE_CLIENT_PROVIDED_ENCRYPTION_KEY + "." + accountName,
|
|
|
|
- "different-1234567890123456789012");
|
|
|
|
- try (AzureBlobFileSystem fs2 = (AzureBlobFileSystem) FileSystem.newInstance(conf);
|
|
|
|
- AbfsClient abfsClient2 = fs2.getAbfsClient()) {
|
|
|
|
- LambdaTestUtils.intercept(IOException.class, () -> {
|
|
|
|
- abfsClient2.flush(testFileName, 0, false, false, null, null,
|
|
|
|
- getTestTracingContext(fs, false));
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Trying to read with no CPK headers
|
|
|
|
- if (isWithCPK) {
|
|
|
|
- conf.unset(FS_AZURE_CLIENT_PROVIDED_ENCRYPTION_KEY + "." + accountName);
|
|
|
|
- try (AzureBlobFileSystem fs3 = (AzureBlobFileSystem) FileSystem
|
|
|
|
- .get(conf); AbfsClient abfsClient3 = fs3.getAbfsClient()) {
|
|
|
|
- LambdaTestUtils.intercept(IOException.class, () -> {
|
|
|
|
- abfsClient3.flush(testFileName, 0, false, false, null, null,
|
|
|
|
- getTestTracingContext(fs, false));
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // With correct CPK
|
|
|
|
- AbfsRestOperation abfsRestOperation = abfsClient
|
|
|
|
- .flush(testFileName, 0, false, false, null, null,
|
|
|
|
- getTestTracingContext(fs, false));
|
|
|
|
- assertCPKHeaders(abfsRestOperation, isWithCPK);
|
|
|
|
- assertResponseHeader(abfsRestOperation, isWithCPK,
|
|
|
|
- X_MS_ENCRYPTION_KEY_SHA256, expectedCPKSha);
|
|
|
|
- assertResponseHeader(abfsRestOperation, false, X_MS_SERVER_ENCRYPTED, "");
|
|
|
|
- assertResponseHeader(abfsRestOperation, true, X_MS_REQUEST_SERVER_ENCRYPTED,
|
|
|
|
- isWithCPK + "");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testSetPathPropertiesWithCPK() throws Exception {
|
|
|
|
- testSetPathProperties(true);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testSetPathPropertiesWithoutCPK() throws Exception {
|
|
|
|
- testSetPathProperties(false);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void testSetPathProperties(final boolean isWithCPK) throws Exception {
|
|
|
|
- final AzureBlobFileSystem fs = getAbfs(isWithCPK);
|
|
|
|
- final String testFileName = getFileName();
|
|
|
|
- createFileAndGetContent(fs, testFileName, FILE_SIZE);
|
|
|
|
-
|
|
|
|
- AbfsClient abfsClient = fs.getAbfsClient();
|
|
|
|
- final Hashtable<String, String> properties = new Hashtable<>();
|
|
|
|
- properties.put("key", "val");
|
|
|
|
- AbfsRestOperation abfsRestOperation = abfsClient
|
|
|
|
- .setPathProperties(testFileName,
|
|
|
|
- convertXmsPropertiesToCommaSeparatedString(properties),
|
|
|
|
- getTestTracingContext(fs, false));
|
|
|
|
- assertCPKHeaders(abfsRestOperation, isWithCPK);
|
|
|
|
- assertResponseHeader(abfsRestOperation, isWithCPK,
|
|
|
|
- X_MS_ENCRYPTION_KEY_SHA256, getCPKSha(fs));
|
|
|
|
- assertResponseHeader(abfsRestOperation, false, X_MS_SERVER_ENCRYPTED, "");
|
|
|
|
- assertResponseHeader(abfsRestOperation, true, X_MS_REQUEST_SERVER_ENCRYPTED,
|
|
|
|
- "true");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testGetPathStatusFileWithCPK() throws Exception {
|
|
|
|
- testGetPathStatusFile(true);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testGetPathStatusFileWithoutCPK() throws Exception {
|
|
|
|
- testGetPathStatusFile(false);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void testGetPathStatusFile(final boolean isWithCPK) throws Exception {
|
|
|
|
- final AzureBlobFileSystem fs = getAbfs(isWithCPK);
|
|
|
|
- final String testFileName = getFileName();
|
|
|
|
- createFileAndGetContent(fs, testFileName, FILE_SIZE);
|
|
|
|
-
|
|
|
|
- AbfsClient abfsClient = fs.getAbfsClient();
|
|
|
|
- TracingContext tracingContext = getTestTracingContext(fs, false);
|
|
|
|
- AbfsRestOperation abfsRestOperation = abfsClient
|
|
|
|
- .getPathStatus(testFileName, false, tracingContext);
|
|
|
|
- assertCPKHeaders(abfsRestOperation, false);
|
|
|
|
- assertResponseHeader(abfsRestOperation, isWithCPK,
|
|
|
|
- X_MS_ENCRYPTION_KEY_SHA256, getCPKSha(fs));
|
|
|
|
- assertResponseHeader(abfsRestOperation, true, X_MS_SERVER_ENCRYPTED,
|
|
|
|
- "true");
|
|
|
|
- assertResponseHeader(abfsRestOperation, false,
|
|
|
|
- X_MS_REQUEST_SERVER_ENCRYPTED, "");
|
|
|
|
-
|
|
|
|
- abfsRestOperation = abfsClient.getPathStatus(testFileName, true, tracingContext);
|
|
|
|
- assertCPKHeaders(abfsRestOperation, isWithCPK);
|
|
|
|
- assertResponseHeader(abfsRestOperation, isWithCPK,
|
|
|
|
- X_MS_ENCRYPTION_KEY_SHA256, getCPKSha(fs));
|
|
|
|
- assertResponseHeader(abfsRestOperation, true, X_MS_SERVER_ENCRYPTED,
|
|
|
|
- "true");
|
|
|
|
- assertResponseHeader(abfsRestOperation, false,
|
|
|
|
- X_MS_REQUEST_SERVER_ENCRYPTED, "");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testDeletePathWithCPK() throws Exception {
|
|
|
|
- testDeletePath(false);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testDeletePathWithoutCPK() throws Exception {
|
|
|
|
- testDeletePath(false);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void testDeletePath(final boolean isWithCPK) throws Exception {
|
|
|
|
- final AzureBlobFileSystem fs = getAbfs(isWithCPK);
|
|
|
|
- final String testFileName = getFileName();
|
|
|
|
- createFileAndGetContent(fs, testFileName, FILE_SIZE);
|
|
|
|
-
|
|
|
|
- FileStatus[] listStatuses = fs.listStatus(new Path(testFileName));
|
|
|
|
- Assertions.assertThat(listStatuses.length)
|
|
|
|
- .describedAs("listStatuses should have 1 entry").isEqualTo(1);
|
|
|
|
-
|
|
|
|
- AbfsClient abfsClient = fs.getAbfsClient();
|
|
|
|
- AbfsRestOperation abfsRestOperation = abfsClient
|
|
|
|
- .deletePath(testFileName, false, null,
|
|
|
|
- getTestTracingContext(fs, false));
|
|
|
|
- assertCPKHeaders(abfsRestOperation, false);
|
|
|
|
- assertNoCPKResponseHeadersPresent(abfsRestOperation);
|
|
|
|
-
|
|
|
|
- Assertions.assertThatThrownBy(() -> fs.listStatus(new Path(testFileName)))
|
|
|
|
- .isInstanceOf(FileNotFoundException.class);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testSetPermissionWithCPK() throws Exception {
|
|
|
|
- testSetPermission(true);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testSetPermissionWithoutCPK() throws Exception {
|
|
|
|
- testSetPermission(false);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void testSetPermission(final boolean isWithCPK) throws Exception {
|
|
|
|
- final AzureBlobFileSystem fs = getAbfs(isWithCPK);
|
|
|
|
- final String testFileName = getFileName();
|
|
|
|
- Assume.assumeTrue(fs.getIsNamespaceEnabled(getTestTracingContext(fs, false)));
|
|
|
|
- createFileAndGetContent(fs, testFileName, FILE_SIZE);
|
|
|
|
- AbfsClient abfsClient = fs.getAbfsClient();
|
|
|
|
- FsPermission permission = new FsPermission(FsAction.EXECUTE,
|
|
|
|
- FsAction.EXECUTE, FsAction.EXECUTE);
|
|
|
|
- AbfsRestOperation abfsRestOperation = abfsClient
|
|
|
|
- .setPermission(testFileName, permission.toString(),
|
|
|
|
- getTestTracingContext(fs, false));
|
|
|
|
- assertCPKHeaders(abfsRestOperation, false);
|
|
|
|
- assertNoCPKResponseHeadersPresent(abfsRestOperation);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testSetAclWithCPK() throws Exception {
|
|
|
|
- testSetAcl(true);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testSetAclWithoutCPK() throws Exception {
|
|
|
|
- testSetAcl(false);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void testSetAcl(final boolean isWithCPK) throws Exception {
|
|
|
|
- final AzureBlobFileSystem fs = getAbfs(isWithCPK);
|
|
|
|
- final String testFileName = getFileName();
|
|
|
|
- TracingContext tracingContext = getTestTracingContext(fs, false);
|
|
|
|
- Assume.assumeTrue(fs.getIsNamespaceEnabled(tracingContext));
|
|
|
|
- createFileAndGetContent(fs, testFileName, FILE_SIZE);
|
|
|
|
- AbfsClient abfsClient = fs.getAbfsClient();
|
|
|
|
-
|
|
|
|
- List<AclEntry> aclSpec = Lists.newArrayList(aclEntry(ACCESS, USER, ALL));
|
|
|
|
- final Map<String, String> aclEntries = AbfsAclHelper
|
|
|
|
- .deserializeAclSpec(AclEntry.aclSpecToString(aclSpec));
|
|
|
|
-
|
|
|
|
- AbfsRestOperation abfsRestOperation = abfsClient
|
|
|
|
- .setAcl(testFileName, AbfsAclHelper.serializeAclSpec(aclEntries),
|
|
|
|
- tracingContext);
|
|
|
|
- assertCPKHeaders(abfsRestOperation, false);
|
|
|
|
- assertNoCPKResponseHeadersPresent(abfsRestOperation);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testGetAclWithCPK() throws Exception {
|
|
|
|
- testGetAcl(true);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testGetAclWithoutCPK() throws Exception {
|
|
|
|
- testGetAcl(false);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void testGetAcl(final boolean isWithCPK) throws Exception {
|
|
|
|
- final AzureBlobFileSystem fs = getAbfs(isWithCPK);
|
|
|
|
- final String testFileName = getFileName();
|
|
|
|
- TracingContext tracingContext = getTestTracingContext(fs, false);
|
|
|
|
- Assume.assumeTrue(fs.getIsNamespaceEnabled(tracingContext));
|
|
|
|
- createFileAndGetContent(fs, testFileName, FILE_SIZE);
|
|
|
|
- AbfsClient abfsClient = fs.getAbfsClient();
|
|
|
|
- AbfsRestOperation abfsRestOperation =
|
|
|
|
- abfsClient.getAclStatus(testFileName, tracingContext);
|
|
|
|
- assertCPKHeaders(abfsRestOperation, false);
|
|
|
|
- assertNoCPKResponseHeadersPresent(abfsRestOperation);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testCheckAccessWithCPK() throws Exception {
|
|
|
|
- testCheckAccess(true);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Test
|
|
|
|
- public void testCheckAccessWithoutCPK() throws Exception {
|
|
|
|
- testCheckAccess(false);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void testCheckAccess(final boolean isWithCPK) throws Exception {
|
|
|
|
- boolean isHNSEnabled = getConfiguration()
|
|
|
|
- .getBoolean(FS_AZURE_TEST_NAMESPACE_ENABLED_ACCOUNT, false);
|
|
|
|
- Assume.assumeTrue(FS_AZURE_TEST_NAMESPACE_ENABLED_ACCOUNT + " is false",
|
|
|
|
- isHNSEnabled);
|
|
|
|
- Assume.assumeTrue("AuthType has to be OAuth",
|
|
|
|
- getAuthType() == AuthType.OAuth);
|
|
|
|
-
|
|
|
|
- final AzureBlobFileSystem fs = getAbfs(isWithCPK);
|
|
|
|
- final String testFileName = getFileName();
|
|
|
|
- fs.create(new Path(testFileName)).close();
|
|
|
|
- AbfsClient abfsClient = fs.getAbfsClient();
|
|
|
|
- AbfsRestOperation abfsRestOperation = abfsClient
|
|
|
|
- .checkAccess(testFileName, "rwx", getTestTracingContext(fs, false));
|
|
|
|
- assertCPKHeaders(abfsRestOperation, false);
|
|
|
|
- assertNoCPKResponseHeadersPresent(abfsRestOperation);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private byte[] createFileAndGetContent(AzureBlobFileSystem fs,
|
|
|
|
- String fileName, int fileSize) throws IOException {
|
|
|
|
- byte[] fileContent = getRandomBytesArray(fileSize);
|
|
|
|
- Path testFilePath = createFileWithContent(fs, fileName, fileContent);
|
|
|
|
- ContractTestUtils.verifyFileContents(fs, testFilePath, fileContent);
|
|
|
|
- return fileContent;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void assertCPKHeaders(AbfsRestOperation abfsRestOperation,
|
|
|
|
- boolean isCPKHeaderExpected) {
|
|
|
|
- assertHeader(abfsRestOperation, X_MS_ENCRYPTION_KEY, isCPKHeaderExpected);
|
|
|
|
- assertHeader(abfsRestOperation, X_MS_ENCRYPTION_KEY_SHA256,
|
|
|
|
- isCPKHeaderExpected);
|
|
|
|
- assertHeader(abfsRestOperation, X_MS_ENCRYPTION_ALGORITHM,
|
|
|
|
- isCPKHeaderExpected);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void assertNoCPKResponseHeadersPresent(
|
|
|
|
- AbfsRestOperation abfsRestOperation) {
|
|
|
|
- assertResponseHeader(abfsRestOperation, false, X_MS_SERVER_ENCRYPTED, "");
|
|
|
|
- assertResponseHeader(abfsRestOperation, false,
|
|
|
|
- X_MS_REQUEST_SERVER_ENCRYPTED, "");
|
|
|
|
- assertResponseHeader(abfsRestOperation, false, X_MS_ENCRYPTION_KEY_SHA256,
|
|
|
|
- "");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void assertResponseHeader(AbfsRestOperation abfsRestOperation,
|
|
|
|
- boolean isHeaderExpected, String headerName, String expectedValue) {
|
|
|
|
- final AbfsHttpOperation result = abfsRestOperation.getResult();
|
|
|
|
- final String value = result.getResponseHeader(headerName);
|
|
|
|
- if (isHeaderExpected) {
|
|
|
|
- Assertions.assertThat(value).isEqualTo(expectedValue);
|
|
|
|
- } else {
|
|
|
|
- Assertions.assertThat(value).isNull();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void assertHeader(AbfsRestOperation abfsRestOperation,
|
|
|
|
- String headerName, boolean isCPKHeaderExpected) {
|
|
|
|
- assertTrue(abfsRestOperation != null);
|
|
|
|
- Optional<AbfsHttpHeader> header = abfsRestOperation.getRequestHeaders()
|
|
|
|
- .stream().filter(abfsHttpHeader -> abfsHttpHeader.getName()
|
|
|
|
- .equalsIgnoreCase(headerName)).findFirst();
|
|
|
|
- String desc;
|
|
|
|
- if (isCPKHeaderExpected) {
|
|
|
|
- desc =
|
|
|
|
- "CPK header " + headerName + " is expected, but the same is absent.";
|
|
|
|
- } else {
|
|
|
|
- desc = "CPK header " + headerName
|
|
|
|
- + " is not expected, but the same is present.";
|
|
|
|
- }
|
|
|
|
- Assertions.assertThat(header.isPresent()).describedAs(desc)
|
|
|
|
- .isEqualTo(isCPKHeaderExpected);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private byte[] getSHA256Hash(String key) throws IOException {
|
|
|
|
- try {
|
|
|
|
- final MessageDigest digester = MessageDigest.getInstance("SHA-256");
|
|
|
|
- return digester.digest(key.getBytes(StandardCharsets.UTF_8));
|
|
|
|
- } catch (NoSuchAlgorithmException e) {
|
|
|
|
- throw new IOException(e);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private String getCPKSha(final AzureBlobFileSystem abfs) throws IOException {
|
|
|
|
- Configuration conf = abfs.getConf();
|
|
|
|
- String accountName = conf.get(FS_AZURE_ABFS_ACCOUNT_NAME);
|
|
|
|
- String encryptionKey = conf
|
|
|
|
- .get(FS_AZURE_CLIENT_PROVIDED_ENCRYPTION_KEY + "." + accountName);
|
|
|
|
- if (encryptionKey == null || encryptionKey.isEmpty()) {
|
|
|
|
- return "";
|
|
|
|
- }
|
|
|
|
- return getBase64EncodedString(getSHA256Hash(encryptionKey));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private String getBase64EncodedString(byte[] bytes) {
|
|
|
|
- return java.util.Base64.getEncoder().encodeToString(bytes);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private Path createFileWithContent(FileSystem fs, String fileName,
|
|
|
|
- byte[] fileContent) throws IOException {
|
|
|
|
- Path testFilePath = new Path(fileName);
|
|
|
|
- try (FSDataOutputStream oStream = fs.create(testFilePath)) {
|
|
|
|
- oStream.write(fileContent);
|
|
|
|
- oStream.flush();
|
|
|
|
- }
|
|
|
|
- return testFilePath;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private String convertXmsPropertiesToCommaSeparatedString(
|
|
|
|
- final Hashtable<String, String> properties)
|
|
|
|
- throws CharacterCodingException {
|
|
|
|
- StringBuilder commaSeparatedProperties = new StringBuilder();
|
|
|
|
- final CharsetEncoder encoder = Charset.forName(XMS_PROPERTIES_ENCODING)
|
|
|
|
- .newEncoder();
|
|
|
|
- for (Map.Entry<String, String> propertyEntry : properties.entrySet()) {
|
|
|
|
- String key = propertyEntry.getKey();
|
|
|
|
- String value = propertyEntry.getValue();
|
|
|
|
- Boolean canEncodeValue = encoder.canEncode(value);
|
|
|
|
- if (!canEncodeValue) {
|
|
|
|
- throw new CharacterCodingException();
|
|
|
|
- }
|
|
|
|
- String encodedPropertyValue = Base64
|
|
|
|
- .encode(encoder.encode(CharBuffer.wrap(value)).array());
|
|
|
|
- commaSeparatedProperties.append(key).append(AbfsHttpConstants.EQUAL)
|
|
|
|
- .append(encodedPropertyValue);
|
|
|
|
- commaSeparatedProperties.append(AbfsHttpConstants.COMMA);
|
|
|
|
- }
|
|
|
|
- if (commaSeparatedProperties.length() != 0) {
|
|
|
|
- commaSeparatedProperties
|
|
|
|
- .deleteCharAt(commaSeparatedProperties.length() - 1);
|
|
|
|
- }
|
|
|
|
- return commaSeparatedProperties.toString();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private String getOctalNotation(FsPermission fsPermission) {
|
|
|
|
- Preconditions.checkNotNull(fsPermission, "fsPermission");
|
|
|
|
- return String
|
|
|
|
- .format(AbfsHttpConstants.PERMISSION_FORMAT, fsPermission.toOctal());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private byte[] getRandomBytesArray(int length) {
|
|
|
|
- final byte[] b = new byte[length];
|
|
|
|
- new Random().nextBytes(b);
|
|
|
|
- return b;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private AzureBlobFileSystem getAbfs(boolean withCPK) throws IOException {
|
|
|
|
- return getAbfs(withCPK, "12345678901234567890123456789012");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private AzureBlobFileSystem getAbfs(boolean withCPK, String cpk)
|
|
|
|
- throws IOException {
|
|
|
|
- Configuration conf = getRawConfiguration();
|
|
|
|
- if (withCPK) {
|
|
|
|
- conf.set(FS_AZURE_CLIENT_PROVIDED_ENCRYPTION_KEY + "." + getAccountName(),
|
|
|
|
- cpk);
|
|
|
|
- } else {
|
|
|
|
- conf.unset(
|
|
|
|
- FS_AZURE_CLIENT_PROVIDED_ENCRYPTION_KEY + "." + getAccountName());
|
|
|
|
- }
|
|
|
|
- return (AzureBlobFileSystem) FileSystem.newInstance(conf);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private AzureBlobFileSystem getSameFSWithWrongCPK(
|
|
|
|
- final AzureBlobFileSystem fs) throws IOException {
|
|
|
|
- AbfsConfiguration abfsConf = fs.getAbfsStore().getAbfsConfiguration();
|
|
|
|
- Configuration conf = abfsConf.getRawConfiguration();
|
|
|
|
- String accountName = conf.get(FS_AZURE_ABFS_ACCOUNT_NAME);
|
|
|
|
- String cpk = conf
|
|
|
|
- .get(FS_AZURE_CLIENT_PROVIDED_ENCRYPTION_KEY + "." + accountName);
|
|
|
|
- if (cpk == null || cpk.isEmpty()) {
|
|
|
|
- cpk = "01234567890123456789012345678912";
|
|
|
|
- }
|
|
|
|
- cpk = "different-" + cpk;
|
|
|
|
- String differentCpk = cpk.substring(0, ENCRYPTION_KEY_LEN - 1);
|
|
|
|
- conf.set(FS_AZURE_CLIENT_PROVIDED_ENCRYPTION_KEY + "." + accountName,
|
|
|
|
- differentCpk);
|
|
|
|
- conf.set("fs.defaultFS",
|
|
|
|
- "abfs://" + getFileSystemName() + "@" + accountName);
|
|
|
|
- AzureBlobFileSystem sameFSWithDifferentCPK =
|
|
|
|
- (AzureBlobFileSystem) FileSystem.newInstance(conf);
|
|
|
|
- return sameFSWithDifferentCPK;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-}
|
|
|