user10144071
user10144071

Reputation: 135

Bucket lifecycle configuration using json

I am trying to apply Lifecycle Configurations on S3 bucket. Trying to apply using following JSON:

[{
"id": "tmpdelete",
"status": "Enabled",
"filter": {
    "predicate": {
        "prefix": "tmp"
    }
},
"transitions": [{
    "days": "1",
    "storageClass": "GLACIER"
}],
"noncurrentVersionTransitions": [{
    "days": "1",
    "storageClass": "GLACIER"
}],
"expirationInDays": "2",
"noncurrentVersionExpirationInDays": "2",
"expiredObjectDeleteMarker": "true"
}]

When i am trying to map it with Rule[].class it is not working. I am using following code:

    String json = above_json;
    Rule[] rules = null;

    Gson gson = new GsonBuilder().serializeNulls().excludeFieldsWithModifiers(Modifier.FINAL,
        Modifier.TRANSIENT, Modifier.STATIC, Modifier.ABSTRACT).create();
    rules = gson.fromJson(json, Rule[].class);

    try {

        amazonS3.setBucketLifecycleConfiguration(bucketName, new BucketLifecycleConfiguration().withRules(rules));
    } catch (Exception e) {
        throw e;
    }

It throws error saying Failed to invoke public com.amazonaws.services.s3.model.lifecycle.LifecycleFilterPredicate() with no args. LifecycleFilterPredicate is an abstract class which implements Serializable and it doesn't have no-args contructor. How to solve this problem.?

Upvotes: 0

Views: 608

Answers (2)

user10144071
user10144071

Reputation: 135

I tried this and it worked for me

public class RuleInstanceCreator implements InstanceCreator<LifecycleFilterPredicate> {

    @Override
    public LifecycleFilterPredicate createInstance(Type type) {

        return new LifecycleFilterPredicate() {

            private static final long serialVersionUID = 1L;

            @Override
            public void accept(LifecyclePredicateVisitor lifecyclePredicateVisitor) {
            }

        };
    }

}

    Gson gson = new GsonBuilder()
            .registerTypeAdapter(LifecycleFilterPredicate.class, new LifecycleFilterPredicateAdapter()).create();

    rules = gson.fromJson(json, Rule[].class);

Upvotes: 0

xenocratus
xenocratus

Reputation: 126

Ok, I think I found your problem: when GSON tries to construct the objects from that json string into an actual object (or, in this case, a list of objects), the process fails because when it gets to the filter.predicate bit, it probably tries to do something like this:

LifecycleFilterPredicate predicate = new LifecycleFilterPredicate();
predicate.setPrefix("tmp");

Which doesn't work because LifecycleFilterPredicate doesn't have a public constructor without any arguments, as you've stated.

I think that, unfortunately, your only solution is to parse the JSON in a different way.

UPDATE

You'll need to make use of a GSON TypeAdapter as follows:

class LifecycleFilterPredicateAdapter extends TypeAdapter<LifecycleFilterPredicate>
{
    @Override
    public LifecycleFilterPredicate read(JsonReader reader)
        throws IOException
    {
        if (reader.peek() == JsonToken.NULL) {
            reader.nextNull();
            return null;
        }
        reader.beginObject();
        if(!"prefix".equals(reader.nextName()))
        {
            return null;
        }
        String prefix = reader.nextString();
        LifecyclePrefixPredicate predicate = new LifecyclePrefixPredicate(prefix);
        reader.endObject();
        return predicate;
    }

    @Override
    public void write(JsonWriter writer, LifecycleFilterPredicate predicate)
        throws IOException
    {
        //nothing here
    }
}
...
Gson gson = new GsonBuilder().serializeNulls().excludeFieldsWithModifiers(Modifier.FINAL,
            Modifier.TRANSIENT, Modifier.STATIC, Modifier.ABSTRACT)
            .registerTypeAdapter(LifecycleFilterPredicate.class, new LifecycleFilterPredicateAdapter()).create();

I've tried it locally and don't get the exception anymore :)

Upvotes: 1

Related Questions