code: public static void safeRenameRecursively(FileSystem fileSystem, Path from, Path to) throws IOException {
  
      for (FileStatus fromFile : FileListUtils.listFilesRecursively(fileSystem, from)) {
  
        Path relativeFilePath =
            new Path(StringUtils.substringAfter(fromFile.getPath().toString(), from.toString() + Path.SEPARATOR));
  
        Path toFilePath = new Path(to, relativeFilePath);
  
        if (!fileSystem.exists(toFilePath)) {
          boolean renamed = false;
  
          // underlying file open can fail with file not found error due to some race condition
          // when the parent directory is created in another thread, so retry a few times
          for (int i = 0; !renamed && i < MAX_RENAME_TRIES; i++) {
            try {
              renamed = fileSystem.rename(fromFile.getPath(), toFilePath);
              break;
            } catch (FileNotFoundException e) {
              if (i + 1 >= MAX_RENAME_TRIES) {
                throw e;
              }
            }
          }
  
          if (!renamed) {
            throw new IOException(String.format("Failed to rename %s to %s.", fromFile.getPath(), toFilePath));
          }
          log.info(String.format("Renamed %s to %s", fromFile.getPath(), toFilePath));
        } else {
          log.info(String.format("File already exists %s. Will not rewrite", toFilePath));
        }
      }
    }
docs: A thread safe variation of {@link #renamePath(FileSystem, Path, Path)} which can be used in
  multi-threaded/multi-mapper environment. The rename operation always happens at file level hence directories are
  not overwritten under the 'to' path.
  
  <p>
  If the contents of destination 'to' path is not expected to be modified concurrently, use
  {@link #renamePath(FileSystem, Path, Path)} which is faster and more optimized
  </p>
  
  <b>NOTE: This does not seem to be working for all {@link FileSystem} implementations. Use
  {@link #renameRecursively(FileSystem, Path, Path)}</b>
  
  @param fileSystem on which the data needs to be moved
  @param from path of the data to be moved
  @param to path of the data to be moved