package org.ray.runtime.util;

import com.google.common.base.Preconditions;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import org.apache.commons.io.FileUtils;

public class BinaryFileUtil {
  public static final String REDIS_SERVER_BINARY_NAME = "redis-server";

  public static final String GCS_SERVER_BINARY_NAME = "gcs_server";

  public static final String PLASMA_STORE_SERVER_BINARY_NAME = "plasma_store_server";

  public static final String RAYLET_BINARY_NAME = "raylet";

  public static final String REDIS_MODULE_LIBRARY_NAME = "libray_redis_module.so";

  public static final String CORE_WORKER_JAVA_LIBRARY =
      System.mapLibraryName("core_worker_library_java");

  public static File getFile(String destDir, String fileName) {
    File file = new File(String.format("%s/%s", destDir, fileName));
    if (file.exists()) {
      return file;
    }

    final File dir = file.getParentFile();
    try {
      if (!dir.exists()) {
        FileUtils.forceMkdir(dir);
      }
    } catch (IOException e) {
      throw new RuntimeException("Couldn't make directory: " + dir.getAbsolutePath(), e);
    }
    // File does not exist.
    try (InputStream is = BinaryFileUtil.class.getResourceAsStream("/" + fileName)) {
      Preconditions.checkNotNull(is, "{} doesn't exist.", fileName);
      Files.copy(is, Paths.get(file.getCanonicalPath()));
    } catch (IOException e) {
      throw new RuntimeException("Couldn't get temp file from resource " + fileName, e);
    }
    return file;
  }
}

@@ -146,16 +146,84 @@
 Stream;%0A
+import java.io.RandomAccessFile;%0Aimport java.nio.channels.FileLock;%0A
 import j
@@ -835,245 +835,487 @@
 %0A%0A  
-public static File getFile(String destDir, String fileName) %7B%0A    File file = new File(String.format(%22%25s/%25s%22, destDir, fileName));%0A    if (file.exists()) %7B%0A      return
+/**%0A   * Extract a resource file to %3Ccode%3EdestDir%3C/code%3E.%0A   * Note that this a process-safe operation. If multi processes extract the file to same%0A   * directory concurrently, this operation will be protected by a file lock.%0A   *%0A   * @param destDir  a directory to extract resource file to%0A   * @param fileName resource file name%0A   * @return extracted resource
  file
-;
 %0A   
- %7D%0A%0A    final File dir = file.getParentFile();%0A    try %7B%0A  
+*/%0A  public static File getFile(String destDir, String fileName) %7B%0A    final File dir = new File(destDir);%0A
     
@@ -1336,23 +1336,35 @@
 s()) %7B%0A 
+     try %7B%0A
        
+ 
 FileUtil
@@ -1389,22 +1389,16 @@
 %0A      %7D
-%0A    %7D
  catch (
@@ -1406,32 +1406,34 @@
 OException e) %7B%0A
+  
       throw new 
@@ -1506,26 +1506,331 @@
 (), e);%0A    
+  
 %7D%0A
+    %7D%0A    String lockFilePath = destDir + File.separator + %22file_lock%22;%0A    try (FileLock ignored = new RandomAccessFile(lockFilePath, %22rw%22)%0A        .getChannel().lock()) %7B%0A      File file = new File(String.format(%22%25s/%25s%22, destDir, fileName));%0A      if (file.exists()) %7B%0A        return file;%0A      %7D%0A%0A  
     // File 
@@ -1845,24 +1845,26 @@
  exist.%0A    
+ 
+ 
 try (InputSt
@@ -1929,24 +1929,26 @@
 ileName)) %7B%0A
+  
       Precon
@@ -2006,24 +2006,26 @@
 ame);%0A      
+  
 Files.copy(i
@@ -2064,24 +2064,26 @@
 th()));%0A    
+ 
+ 
 %7D catch (IOE
@@ -2092,24 +2092,26 @@
 eption e) %7B%0A
+  
       throw 
@@ -2187,26 +2187,30 @@
 me, e);%0A    
-%7D%0A
+  %7D%0A  
     return f
@@ -2214,14 +2214,87 @@
 n file;%0A
+    %7D catch (IOException e) %7B%0A      throw new RuntimeException(e);%0A    %7D%0A
   %7D%0A%7D%0A

fix concurrently extract file (#7225)