Creating your own temporary storage

As we mentioned in the Working with Documents section, the SDK needs some temporary storage to be able to give you time limited links to access files that are created. Out of the box, we include one for AWS (using S3) and one for leveraging the /tmp folder on the server. But what if you want to create your own storage, say for Azure blob storage or some other cloud vendor? That's where the TemporaryFileStorageService interface comes into play.

public interface TemporaryFileStorageService {
    public String getPresignedURL(String filename, Duration accessTime);
    public void saveFile(String fileName, byte[] byteArray);
}

The two methods are fairly self-explanatory: one is for saving files to the temporary storage and one gets you a signed URL that will be deleted after the given time. As you implement these, you're responsible for all the file writing, cleanup and deletion logic. We can look at the Local storage class as an example:

@Service
@ConditionalOnMissingBean(TemporaryFileStorageService.class)
@Slf4j
public class LocalFileStorageService implements TemporaryFileStorageService {
    @Value("${file.storage.path:/tmp}")
    String path = "/tmp";

    @Override
    public String getPresignedURL(String filename, Duration accessTime) {
        Timer timer = new Timer("Delete saved file: " + filename);//create a new Timer
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                try {
                    Files.delete(Paths.get(path + File.separator + filename));
                } catch (IOException e) {
                    log.error("Unable to delete temp file: " + e.getMessage());
                }
            }
        }, accessTime.getSeconds());

        return "file://" + path + "/" + filename;
    }

    @Override
    public void saveFile(String fileName, byte[] byteArray) {
        Path filePath = Paths.get(path + File.separator + fileName); // Path to the output file

        try {
            Files.write(filePath, byteArray);
        } catch (IOException e) {
            log.error("Error writing byte array to file: " + e.getMessage());
        }
    }
}

All we're doing here is setting up a very simple Spring service that only gets activated if no other bean of that type is currently active. Then we're writing the files and ensuring that they get deleted after the time specified. Thats it!

In this example, a service restart would lose the timer and leave the file on the hard drive. If your implementation has the same issue, you may consider something more durable for the timers.

Last updated

Was this helpful?