Update WFR put action to update files atomically
The WFR put() method in WorkingFileRepositoryImpl will first delete any files in the mediapackage element directory, then upload the given file.
This can lead to race conditions when a workflow operation is updating the episode.xml file. The workflow operation puts a new version of episode.xml while an indexing thread is attempting to read it. For a short window of time, the file is unavailable.
Change the put method to handle the case where a file is being updated by writing the new file to a temporary file name, then moving the temporary file to the real file atomically.
Example of this race condition from a production system: pool-63-thread-213 is a workflow operation, pool-80-thread-1 is an indexing thread (message listener).
2017-06-20 10:56:48,260 | DEBUG | pool-63-thread-213 | (WorkingFileRepositoryImpl:281) - Attempting to write a file to /data/opencast/work/shared/files/mediapackage/d5bbc994-1830-46fd-8900-07439023c2ba/catalog-0/episode.xml
2017-06-20 10:56:48,264 | WARN | pool-80-thread-1 | (WorkspaceImpl:299) - The working file repository URI and paths don't match for read. Looking up http://media.uct.ac.za/files/mediapackage/d5bbc994-1830-46fd-8900-07439023c2ba/catalog-0/episode.xml at /data/opencast/work/shared/files/mediapackage/d5bbc994-1830-46fd-8900-07439023c2ba/catalog-0/episode.xml failed