findify / s3mock

Embedded S3 server for easy mocking
MIT License
388 stars 107 forks source link

Allow lastModified to be set for object (default to current time if not explicitly set) #173

Open sdwards opened 4 years ago

jorkzijlstra commented 3 years ago

@romangrebennikov Are there any plans to merge this?

kevin-denver commented 3 years ago

I would love to see this merged too because I'm currently stuck without this functionality

florind commented 3 years ago

+1

yonatang commented 1 year ago

+1

yonatang commented 1 year ago

This repo has no activity since 2020. So assuming no one is going to merge this in, here's a reflection based walk-around I'm using, hope it helps:

import io.findify.s3mock.S3Mock;
import io.findify.s3mock.provider.InMemoryProvider;
import scala.collection.concurrent.TrieMap;

import java.lang.reflect.Field;
import java.util.Date;

public class YourTestClass {

    // ...

    private static Field bucketStoreField;
    static {
        try {
            bucketStoreField = InMemoryProvider.class.getDeclaredField("bucketDataStore");
            bucketStoreField.setAccessible(true);
        } catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    public void setLastModified(String bucket, String key, Date lastModified) {
        InMemoryProvider p = (InMemoryProvider)s3mock.p();
        p.getObject(bucket, key).metadata().get().setLastModified(lastModified);
        // Hack to make listObject work
        TrieMap<String, InMemoryProvider.BucketContents> bucketStore =  (TrieMap<String, InMemoryProvider.BucketContents>)bucketStoreField.get(p);
        InMemoryProvider.BucketContents bucketContents = bucketStore.get(bucket).get();
        InMemoryProvider.KeyContents rawObject = bucketContents.keysInBucket().get(key).get();
        akka.http.scaladsl.model.DateTime newDateTime = (akka.http.scaladsl.model.DateTime)akka.http.scaladsl.model.DateTime.create(lastModified.getTime());
        bucketContents.keysInBucket().put(key, rawObject.copy(newDateTime, rawObject.data()));

    }
}