4040
4141import java .io .IOException ;
4242import java .io .InputStream ;
43+ import java .io .UncheckedIOException ;
44+ import java .net .InetAddress ;
45+ import java .net .Socket ;
4346import java .security .DigestInputStream ;
4447import java .util .ArrayList ;
4548import java .util .List ;
4649import java .util .Map ;
4750import java .util .concurrent .ConcurrentHashMap ;
4851
52+ import static org .junit .Assert .assertTrue ;
53+
4954class MockAmazonS3 extends AbstractAmazonS3 {
5055
56+ private final int mockSocketPort ;
57+
5158 private Map <String , InputStream > blobs = new ConcurrentHashMap <>();
5259
5360 // in ESBlobStoreContainerTestCase.java, the maximum
5461 // length of the input data is 100 bytes
5562 private byte [] byteCounter = new byte [100 ];
5663
64+
65+ MockAmazonS3 (int mockSocketPort ) {
66+ this .mockSocketPort = mockSocketPort ;
67+ }
68+
69+ // Simulate a socket connection to check that SocketAccess.doPrivileged() is used correctly.
70+ // Any method of AmazonS3 might potentially open a socket to the S3 service. Firstly, a call
71+ // to any method of AmazonS3 has to be wrapped by SocketAccess.doPrivileged().
72+ // Secondly, each method on the stack from doPrivileged to opening the socket has to be
73+ // located in a jar that is provided by the plugin.
74+ // Thirdly, a SocketPermission has to be configured in plugin-security.policy.
75+ // By opening a socket in each method of MockAmazonS3 it is ensured that in production AmazonS3
76+ // is able to to open a socket to the S3 Service without causing a SecurityException
77+ private void simulateS3SocketConnection () {
78+ try (Socket socket = new Socket (InetAddress .getByName ("127.0.0.1" ), mockSocketPort )) {
79+ assertTrue (socket .isConnected ()); // NOOP to keep static analysis happy
80+ } catch (IOException e ) {
81+ throw new UncheckedIOException (e );
82+ }
83+ }
84+
85+
5786 @ Override
5887 public boolean doesBucketExist (String bucket ) {
5988 return true ;
@@ -63,6 +92,7 @@ public boolean doesBucketExist(String bucket) {
6392 public ObjectMetadata getObjectMetadata (
6493 GetObjectMetadataRequest getObjectMetadataRequest )
6594 throws AmazonClientException , AmazonServiceException {
95+ simulateS3SocketConnection ();
6696 String blobName = getObjectMetadataRequest .getKey ();
6797
6898 if (!blobs .containsKey (blobName )) {
@@ -75,6 +105,7 @@ public ObjectMetadata getObjectMetadata(
75105 @ Override
76106 public PutObjectResult putObject (PutObjectRequest putObjectRequest )
77107 throws AmazonClientException , AmazonServiceException {
108+ simulateS3SocketConnection ();
78109 String blobName = putObjectRequest .getKey ();
79110
80111 if (blobs .containsKey (blobName )) {
@@ -88,6 +119,7 @@ public PutObjectResult putObject(PutObjectRequest putObjectRequest)
88119 @ Override
89120 public S3Object getObject (GetObjectRequest getObjectRequest )
90121 throws AmazonClientException , AmazonServiceException {
122+ simulateS3SocketConnection ();
91123 // in ESBlobStoreContainerTestCase.java, the prefix is empty,
92124 // so the key and blobName are equivalent to each other
93125 String blobName = getObjectRequest .getKey ();
@@ -107,6 +139,7 @@ public S3Object getObject(GetObjectRequest getObjectRequest)
107139 @ Override
108140 public ObjectListing listObjects (ListObjectsRequest listObjectsRequest )
109141 throws AmazonClientException , AmazonServiceException {
142+ simulateS3SocketConnection ();
110143 MockObjectListing list = new MockObjectListing ();
111144 list .setTruncated (false );
112145
@@ -140,6 +173,7 @@ public ObjectListing listObjects(ListObjectsRequest listObjectsRequest)
140173 @ Override
141174 public CopyObjectResult copyObject (CopyObjectRequest copyObjectRequest )
142175 throws AmazonClientException , AmazonServiceException {
176+ simulateS3SocketConnection ();
143177 String sourceBlobName = copyObjectRequest .getSourceKey ();
144178 String targetBlobName = copyObjectRequest .getDestinationKey ();
145179
@@ -160,6 +194,7 @@ public CopyObjectResult copyObject(CopyObjectRequest copyObjectRequest)
160194 @ Override
161195 public void deleteObject (DeleteObjectRequest deleteObjectRequest )
162196 throws AmazonClientException , AmazonServiceException {
197+ simulateS3SocketConnection ();
163198 String blobName = deleteObjectRequest .getKey ();
164199
165200 if (!blobs .containsKey (blobName )) {
0 commit comments