IBM / ibm-cos-sdk-java

ibm-cos-sdk-java

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

listBuckets fails after a failed createBucket

Hendrik-H opened this issue · comments

When a createBucket fails due to a conflict with an existing bucket a following listBuckets call fails with this exception:

Exception in thread "main" com.ibm.cloud.objectstorage.services.s3.model.AmazonS3Exception: Unknown Version (Service: Amazon S3; Status Code: 400; Error Code: 400 Unknown Version; Request ID: null), S3 Extended Request ID: null
	at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1588)
	at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1258)
	at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1030)
	at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:742)
	at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:716)
	at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699)
	at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667)
	at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649)
	at com.ibm.cloud.objectstorage.http.AmazonHttpClient.execute(AmazonHttpClient.java:513)
	at com.ibm.cloud.objectstorage.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3864)
	at com.ibm.cloud.objectstorage.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3811)
	at com.ibm.cloud.objectstorage.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3805)
	at com.ibm.cloud.objectstorage.services.s3.AmazonS3Client.listBuckets(AmazonS3Client.java:879)
	at com.ibm.cloud.objectstorage.services.s3.AmazonS3Client.listBuckets(AmazonS3Client.java:885)
	at scratch.cos.Main.main(Main.java:51)

The extra strange thing is that the wire trace shows no difference between a failing listBuckets call and working one, exception from the signature.

@Hendrik-H I will look into this issue and get back to you with my findings.

@Hendrik-H would you be able to paste your code here, ensuring to remove all credentials info, Im having issues replicating the error.

@smcgrath-IBM my test code looks like this:

package scratch.cos;

import com.ibm.cloud.objectstorage.AmazonServiceException;
import com.ibm.cloud.objectstorage.ClientConfiguration;
import com.ibm.cloud.objectstorage.auth.AWSStaticCredentialsProvider;
import com.ibm.cloud.objectstorage.auth.BasicAWSCredentials;
import com.ibm.cloud.objectstorage.client.builder.AwsClientBuilder.EndpointConfiguration;
import com.ibm.cloud.objectstorage.services.s3.AmazonS3;
import com.ibm.cloud.objectstorage.services.s3.AmazonS3ClientBuilder;
import com.ibm.cloud.objectstorage.services.s3.model.Bucket;
import com.ibm.cloud.objectstorage.services.s3.model.CreateBucketRequest;

public class Main {
	
	public static void main(String[] args) throws Exception {
        String endpointURL = "https://s3.us.cloud-object-storage.appdomain.cloud";
        
        AmazonS3 cos = AmazonS3ClientBuilder.standard()
        		.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("...", "...")))
                .withEndpointConfiguration(new EndpointConfiguration(endpointURL, null))
                .withPathStyleAccessEnabled(true)
                .withClientConfiguration(new ClientConfiguration().withRequestTimeout(5000))
                .build();
        
        //cos.createBucket("test-bucket", "us-standard"); // all the none deprecated options don't seem to work correctly
        try {
        	System.out.println("exists: " + cos.doesBucketExist("test-bucket"));
//        	cos.deleteBucket("test-bucket");
        	cos.createBucket("test-bucket", "us-standard"); // all the none deprecated options don't seem to work correctly
        } catch (AmazonServiceException e) {
        	System.err.println(e.getErrorCode());
        	System.err.println(e.getErrorMessage());
        }
        
        for (Bucket bucket: cos.listBuckets()) {
        	System.out.println(bucket.getName() + " (created: " + bucket.getCreationDate() + " / owner: " + bucket.getOwner() + ")");
        }
	}
}

the output is:

exists: true
BucketAlreadyExists
The requested bucket name is not available. The bucket namespace is shared by all users of the system. Please select a different name and try again.
Exception in thread "main" com.ibm.cloud.objectstorage.services.s3.model.AmazonS3Exception: Unknown Version (Service: Amazon S3; Status Code: 400; Error Code: 400 Unknown Version; Request ID: null), S3 Extended Request ID: null
	at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1588)
	at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1258)
	at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1030)
	at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:742)
	at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:716)
	at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699)
	at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667)
	at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649)
	at com.ibm.cloud.objectstorage.http.AmazonHttpClient.execute(AmazonHttpClient.java:513)
	at com.ibm.cloud.objectstorage.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3864)
	at com.ibm.cloud.objectstorage.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3811)
	at com.ibm.cloud.objectstorage.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3805)
	at com.ibm.cloud.objectstorage.services.s3.AmazonS3Client.listBuckets(AmazonS3Client.java:879)
	at com.ibm.cloud.objectstorage.services.s3.AmazonS3Client.listBuckets(AmazonS3Client.java:885)
	at scratch.cos.Main.main(Main.java:35)

Without the failing createBucket call the listBucket call works without any error.
I'm using the latest SDK version: 2.4.1

Thanks @Hendrik-H I can see the same issue now, although the listbuckets is throwing a 'No URI' message in the exception for myself. I have raised an internal JIRA to track this issue for a future patch release - CSAFE-49102. This git issue will be updated when we have a solution ready.

@Hendrik-H can you set this value on your ClientConfiguration object .withUseExpectContinue(false) this has resolved the issue for me

Hi @Hendrik-H did you get a chance to try this configuration?

hi @smcgrath-IBM , I saw your update but did not get to it yet. I have it on my todo list and will let you know as soon as I had a chance. I hope to get to it in the next days.

Hi @Hendrik-H any update on the solution I provided?

@smcgrath-IBM yes, I can confirm that my problem gets resolved that way. Is that the final resolution or just a work around? What's the exact semantics of that options? I could not really find any documentation explaining what effects it has.

Thats good news. Setting ExpectContinue to false ensures a new tcp connection with the server for each request. If this solution works for you, let me know if we can close out this issue.

So that will have a negative performance impact. As a work around that's ok but I don't consider that to be a fix. Clearly there is something wrong in the state handling of client.

@Hendrik-H this is been investigated from the server side. I will leave this issue open and advise you when a solution is in place instead of the work around.

@Hendrik-H, just an update, an issue has been found on the load balancer with how it interacts with the application server at a packet level. Work is in progress to resolve.

@smcgrath-IBM awesome! guess it will make testing a bit hard for me but as you have the full test code you should be able to verify that once you have a version with the fix setup.

Hi @Hendrik-H,
This ticket has been open quite some time and as the underlying issue is not directly related to the code within the SDK, I would like to close this issue.
The issue has been root caused to a component outside of the SDK, and discussions are underway with the vendor on the issue and possible fix. At this time we don't foresee any SDK needs to address this issue and there is no value in keeping this issue open on the SDK.