S3Mock icon indicating copy to clipboard operation
S3Mock copied to clipboard

Cannot get ACL for new object

Open alexandernajafi opened this issue 2 years ago • 4 comments

When I try to fetch the ACL list for a newly created object, the call fails with the following stack trace. See below for a code example to reproduce.

com.amazonaws.SdkClientException: Failed to parse XML document with handler class com.amazonaws.services.s3.model.transform.XmlResponsesSaxParser$AccessControlListHandler

	at com.amazonaws.services.s3.model.transform.XmlResponsesSaxParser.parseXmlInputStream(XmlResponsesSaxParser.java:177)
	at com.amazonaws.services.s3.model.transform.XmlResponsesSaxParser.parseAccessControlListResponse(XmlResponsesSaxParser.java:402)
	at com.amazonaws.services.s3.model.transform.Unmarshallers$AccessControlListUnmarshaller.unmarshall(Unmarshallers.java:165)
	at com.amazonaws.services.s3.model.transform.Unmarshallers$AccessControlListUnmarshaller.unmarshall(Unmarshallers.java:161)
	at com.amazonaws.services.s3.internal.S3XmlResponseHandler.handle(S3XmlResponseHandler.java:62)
	at com.amazonaws.services.s3.internal.ResponseHeaderHandlerChain.handle(ResponseHeaderHandlerChain.java:44)
	at com.amazonaws.services.s3.internal.ResponseHeaderHandlerChain.handle(ResponseHeaderHandlerChain.java:30)
	at com.amazonaws.http.response.AwsResponseHandlerAdapter.handle(AwsResponseHandlerAdapter.java:69)
	at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleResponse(AmazonHttpClient.java:1777)
	at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleSuccessResponse(AmazonHttpClient.java:1474)
	at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1381)
	at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1154)
	at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:811)
	at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:779)
	at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:753)
	at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:713)
	at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:695)
	at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:559)
	at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:539)
	at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:5437)
	at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:5384)
	at com.amazonaws.services.s3.AmazonS3Client.getAcl(AmazonS3Client.java:4050)
	at com.amazonaws.services.s3.AmazonS3Client.getObjectAcl(AmazonS3Client.java:1167)
	at com.amazonaws.services.s3.AmazonS3Client.getObjectAcl(AmazonS3Client.java:1151)
	at com.weiq.core.service.FileServiceTest.shouldGetFile(FileServiceTest.java:69)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
	at com.adobe.testing.s3mock.junit4.S3MockRule$1.evaluate(S3MockRule.java:66)
	at org.junit.rules.RunRules.evaluate(RunRules.java:20)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)

To reproduce is simple. Set up the S3Mock and run the following test (assuming mock is set up at port 8001)

  @Test
  public void failing() {
    final AmazonS3 s3 =
        AmazonS3ClientBuilder.standard()
            .withPathStyleAccessEnabled(true)
            .withEndpointConfiguration(
                new AwsClientBuilder.EndpointConfiguration("http://localhost:8001", "us-west-2"))
            .withCredentials(new AWSStaticCredentialsProvider(new AnonymousAWSCredentials()))
            .build();

    s3.createBucket("test-bucket");
    s3.putObject("test-bucket", "/test", "file content");
    final AccessControlList acl = s3.getObjectAcl("test-bucket", "/test");
  }

The mock is started using the Juni4 ClassRule with

  @ClassRule
  public static final S3MockRule S3_MOCK_RULE =
      S3MockRule.builder().withHttpPort(8001).silent().build();

alexandernajafi avatar Oct 01 '21 14:10 alexandernajafi

@alexandernajafi thanks for your ticket.

Unfortunately, ACLs are currently not implemented by the S3Mock.

afranken avatar Oct 18 '21 16:10 afranken

@afranken hm, if I first set the ACL manually and then fetch it, both calls work.

alexandernajafi avatar Oct 18 '21 17:10 alexandernajafi

I'm guessing that your client instance caches the ACL internally and returns it. When you use two different client instances for putting and getting the ACL, the get call will fail.

afranken avatar Oct 18 '21 18:10 afranken

related: #213

afranken avatar Oct 18 '21 18:10 afranken

Just released 2.7.0 which adds ObjectAcl support.

afranken avatar Sep 26 '22 13:09 afranken