|
22 | 22 | import java.io.File;
|
23 | 23 | import java.io.IOException;
|
24 | 24 | import java.io.InputStream;
|
| 25 | +import java.lang.reflect.Field; |
25 | 26 |
|
| 27 | +import org.apache.hadoop.fs.contract.s3a.S3AContract; |
| 28 | +import org.apache.hadoop.fs.s3a.impl.streams.AnalyticsStream; |
26 | 29 | import org.junit.Before;
|
27 | 30 | import org.junit.Test;
|
28 | 31 | import org.assertj.core.api.Assertions;
|
|
36 | 39 | import org.apache.hadoop.fs.s3a.impl.streams.ObjectInputStream;
|
37 | 40 | import org.apache.hadoop.fs.statistics.IOStatistics;
|
38 | 41 |
|
| 42 | +import software.amazon.s3.analyticsaccelerator.S3SeekableInputStream; |
39 | 43 | import software.amazon.s3.analyticsaccelerator.S3SeekableInputStreamConfiguration;
|
40 | 44 | import software.amazon.s3.analyticsaccelerator.common.ConnectorConfiguration;
|
| 45 | +import software.amazon.s3.analyticsaccelerator.util.OpenStreamInformation; |
41 | 46 |
|
42 | 47 | import static org.apache.hadoop.fs.Options.OpenFileOptions.FS_OPTION_OPENFILE_READ_POLICY;
|
43 | 48 | import static org.apache.hadoop.fs.Options.OpenFileOptions.FS_OPTION_OPENFILE_READ_POLICY_PARQUET;
|
44 | 49 | import static org.apache.hadoop.fs.Options.OpenFileOptions.FS_OPTION_OPENFILE_READ_POLICY_WHOLE_FILE;
|
| 50 | +import static org.apache.hadoop.fs.contract.ContractTestUtils.dataset; |
| 51 | +import static org.apache.hadoop.fs.contract.ContractTestUtils.writeDataset; |
45 | 52 | import static org.apache.hadoop.fs.s3a.Constants.ANALYTICS_ACCELERATOR_CONFIGURATION_PREFIX;
|
| 53 | +import static org.apache.hadoop.fs.s3a.Constants.S3_ENCRYPTION_ALGORITHM; |
| 54 | +import static org.apache.hadoop.fs.s3a.Constants.S3_ENCRYPTION_KEY; |
46 | 55 | import static org.apache.hadoop.fs.s3a.S3ATestUtils.enableAnalyticsAccelerator;
|
| 56 | +import static org.apache.hadoop.fs.s3a.S3ATestUtils.getTestBucketName; |
47 | 57 | import static org.apache.hadoop.fs.s3a.S3ATestUtils.removeBaseAndBucketOverrides;
|
48 | 58 | import static org.apache.hadoop.fs.s3a.test.PublicDatasetTestUtils.getExternalData;
|
49 | 59 | import static org.apache.hadoop.fs.statistics.IOStatisticAssertions.verifyStatisticCounterValue;
|
|
64 | 74 | public class ITestS3AAnalyticsAcceleratorStreamReading extends AbstractS3ATestBase {
|
65 | 75 |
|
66 | 76 | private static final String PHYSICAL_IO_PREFIX = "physicalio";
|
| 77 | + private static final String SSEC_KEY = "4niV/jPK5VFRHY+KNb6wtqYd4xXyMgdJ9XQJpcQUVbs="; |
67 | 78 |
|
68 | 79 | private Path externalTestFile;
|
69 | 80 |
|
@@ -194,4 +205,61 @@ public void testInvalidConfigurationThrows() throws Exception {
|
194 | 205 | () -> S3SeekableInputStreamConfiguration.fromConfiguration(connectorConfiguration));
|
195 | 206 | }
|
196 | 207 |
|
| 208 | + /** |
| 209 | + * This test verifies that the OpenStreamInfo object contains correct encryption |
| 210 | + * settings when reading an SSEC encrypted file with analytics stream. |
| 211 | + * |
| 212 | + * @throws Exception |
| 213 | + */ |
| 214 | + |
| 215 | + @Test |
| 216 | + public void testAnalyticsStreamOpenStreamInfoWhenSSECEncryptionEnabled() throws Exception { |
| 217 | + Configuration confSSEC = this.createConfiguration(); |
| 218 | + S3ATestUtils.disableFilesystemCaching(confSSEC); |
| 219 | + removeBaseAndBucketOverrides(getTestBucketName(confSSEC), confSSEC, S3_ENCRYPTION_ALGORITHM, S3_ENCRYPTION_KEY); |
| 220 | + |
| 221 | + confSSEC.set(S3_ENCRYPTION_ALGORITHM, S3AEncryptionMethods.SSE_C.getMethod()); |
| 222 | + confSSEC.set(S3_ENCRYPTION_KEY, SSEC_KEY); |
| 223 | + |
| 224 | + S3AContract contractSSEC = (S3AContract) createContract(confSSEC); |
| 225 | + contractSSEC.init(); |
| 226 | + contractSSEC.setConf(confSSEC); |
| 227 | + S3AFileSystem fileSystemSSEC = (S3AFileSystem) contractSSEC.getTestFileSystem(); |
| 228 | + |
| 229 | + int len = TEST_FILE_LEN; |
| 230 | + describe("Create an encrypted file and verify OpenStreamInfo encryption settings"); |
| 231 | + Path src = methodPath(); |
| 232 | + byte[] data = dataset(len, 'a', 'z'); |
| 233 | + writeDataset(fileSystemSSEC, src, data, len, 1024 * 1024, true); |
| 234 | + // Read with encryption settings |
| 235 | + OpenStreamInformation originalInfo; |
| 236 | + try (FSDataInputStream in = fileSystemSSEC.open(src)) { |
| 237 | + AnalyticsStream s3AInputStream = (AnalyticsStream) in.getWrappedStream(); |
| 238 | + Field inputStreamField = s3AInputStream.getClass().getDeclaredField("inputStream"); |
| 239 | + inputStreamField.setAccessible(true); |
| 240 | + S3SeekableInputStream seekableInputStream = (S3SeekableInputStream) inputStreamField.get(s3AInputStream); |
| 241 | + |
| 242 | + Field logicalIOField = seekableInputStream.getClass().getDeclaredField("logicalIO"); |
| 243 | + logicalIOField.setAccessible(true); |
| 244 | + Object logicalIO = logicalIOField.get(seekableInputStream); |
| 245 | + |
| 246 | + Field physicalIOField = logicalIO.getClass().getDeclaredField("physicalIO"); |
| 247 | + physicalIOField.setAccessible(true); |
| 248 | + Object physicalIO = physicalIOField.get(logicalIO); |
| 249 | + |
| 250 | + Field openStreamInfoField = physicalIO.getClass().getDeclaredField("openStreamInformation"); |
| 251 | + openStreamInfoField.setAccessible(true); |
| 252 | + originalInfo = (OpenStreamInformation) openStreamInfoField.get(physicalIO); |
| 253 | + |
| 254 | + // Verify the OpenStreamInfo object exists |
| 255 | + assertNotNull(originalInfo.getEncryptionSecrets().getSsecCustomerKey().get(), "OpenStreamInfo should not be null"); |
| 256 | + assertEquals(SSEC_KEY, originalInfo.getEncryptionSecrets().getSsecCustomerKey().get()); |
| 257 | + } |
| 258 | + |
| 259 | + // Clean up |
| 260 | + fileSystemSSEC.delete(src, false); |
| 261 | + } |
| 262 | + |
| 263 | + |
| 264 | + |
197 | 265 | }
|
0 commit comments