@GET
  @Path(WEBUI_BROWSE)
  @ReturnType("alluxio.wire.MasterWebUIBrowse")
  public Response getWebUIBrowse(@DefaultValue("/") @QueryParam("path") String requestPath,
      @DefaultValue("0") @QueryParam("offset") String requestOffset,
      @DefaultValue("") @QueryParam("end") String requestEnd,
      @DefaultValue("20") @QueryParam("limit") String requestLimit) {
    return RestUtils.call(() -> {
      MasterWebUIBrowse response = new MasterWebUIBrowse();

      if (!ServerConfiguration.getBoolean(PropertyKey.WEB_FILE_INFO_ENABLED)) {
        return response;
      }

      if (SecurityUtils.isSecurityEnabled(ServerConfiguration.global())
          && AuthenticatedClientUser.get(ServerConfiguration.global()) == null) {
        AuthenticatedClientUser.set(LoginUser.get(ServerConfiguration.global()).getName());
      }
      response.setDebug(ServerConfiguration.getBoolean(PropertyKey.DEBUG)).setShowPermissions(
          ServerConfiguration.getBoolean(PropertyKey.SECURITY_AUTHORIZATION_PERMISSION_ENABLED))
          .setMasterNodeAddress(mMasterProcess.getRpcAddress().toString()).setInvalidPathError("");
      List<FileInfo> filesInfo;
      String path = requestPath;
      if (path == null || path.isEmpty()) {
        path = AlluxioURI.SEPARATOR;
      }
      AlluxioURI currentPath = new AlluxioURI(path);
      response.setCurrentPath(currentPath.toString()).setViewingOffset(0);

      try {
        long fileId = mFileSystemMaster.getFileId(currentPath);
        FileInfo fileInfo = mFileSystemMaster.getFileInfo(fileId);
        UIFileInfo currentFileInfo = new UIFileInfo(fileInfo, ServerConfiguration.global(),
            new MasterStorageTierAssoc().getOrderedStorageAliases());
        if (currentFileInfo.getAbsolutePath() == null) {
          throw new FileDoesNotExistException(currentPath.toString());
        }
        response.setCurrentDirectory(currentFileInfo)
            .setBlockSizeBytes(currentFileInfo.getBlockSizeBytes());
        if (!currentFileInfo.getIsDirectory()) {
          long relativeOffset = 0;
          long offset;
          try {
            if (requestOffset != null) {
              relativeOffset = Long.parseLong(requestOffset);
            }
          } catch (NumberFormatException e) {
            relativeOffset = 0;
          }
          // If no param "end" presents, the offset is relative to the beginning; otherwise, it is
          // relative to the end of the file.
          if (requestEnd.equals("")) {
            offset = relativeOffset;
          } else {
            offset = fileInfo.getLength() - relativeOffset;
          }
          if (offset < 0) {
            offset = 0;
          } else if (offset > fileInfo.getLength()) {
            offset = fileInfo.getLength();
          }
          try {
            AlluxioURI absolutePath = new AlluxioURI(currentFileInfo.getAbsolutePath());
            FileSystem fs = mFsClient;
            String fileData;
            URIStatus status = fs.getStatus(absolutePath);
            if (status.isCompleted()) {
              OpenFilePOptions options =
                  OpenFilePOptions.newBuilder().setReadType(ReadPType.NO_CACHE).build();
              try (FileInStream is = fs.openFile(absolutePath, options)) {
                int len = (int) Math.min(5 * Constants.KB, status.getLength() - offset);
                byte[] data = new byte[len];
                long skipped = is.skip(offset);
                if (skipped < 0) {
                  // nothing was skipped
                  fileData = "Unable to traverse to offset; is file empty?";
                } else if (skipped < offset) {
                  // couldn't skip all the way to offset
                  fileData = "Unable to traverse to offset; is offset larger than the file?";
                } else {
                  // read may not read up to len, so only convert what was read
                  int read = is.read(data, 0, len);
                  if (read < 0) {
                    // stream couldn't read anything, skip went to EOF?
                    fileData = "Unable to read file";
                  } else {
                    fileData = WebUtils.convertByteArrayToStringWithoutEscape(data, 0, read);
                  }
                }
              }
            } else {
              fileData = "The requested file is not complete yet.";
            }
            List<UIFileBlockInfo> uiBlockInfo = new ArrayList<>();
            for (FileBlockInfo fileBlockInfo : mFileSystemMaster
                .getFileBlockInfoList(absolutePath)) {
              uiBlockInfo.add(new UIFileBlockInfo(fileBlockInfo, ServerConfiguration.global()));
            }
            response.setFileBlocks(uiBlockInfo).setFileData(fileData)
                .setHighestTierAlias(mBlockMaster.getGlobalStorageTierAssoc().getAlias(0));
          } catch (AlluxioException e) {
            throw new IOException(e);
          }
          response.setViewingOffset(offset);
          return response;
        }

        if (currentPath.isRoot()) {
          response.setPathInfos(new UIFileInfo[0]);
        } else {
          String[] splitPath = PathUtils.getPathComponents(currentPath.toString());
          UIFileInfo[] pathInfos = new UIFileInfo[splitPath.length - 1];
          fileId = mFileSystemMaster.getFileId(currentPath);
          pathInfos[0] =
              new UIFileInfo(mFileSystemMaster.getFileInfo(fileId), ServerConfiguration.global(),
                  new MasterStorageTierAssoc().getOrderedStorageAliases());
          AlluxioURI breadcrumb = new AlluxioURI(AlluxioURI.SEPARATOR);
          for (int i = 1; i < splitPath.length - 1; i++) {
            breadcrumb = breadcrumb.join(splitPath[i]);
            fileId = mFileSystemMaster.getFileId(breadcrumb);
            pathInfos[i] =
                new UIFileInfo(mFileSystemMaster.getFileInfo(fileId), ServerConfiguration.global(),
                    new MasterStorageTierAssoc().getOrderedStorageAliases());
          }
          response.setPathInfos(pathInfos);
        }

        filesInfo = mFileSystemMaster.listStatus(currentPath, ListStatusContext.mergeFrom(
            ListStatusPOptions.newBuilder().setLoadMetadataType(LoadMetadataPType.ALWAYS)));
      } catch (FileDoesNotExistException e) {
        response.setInvalidPathError("Error: Invalid Path " + e.getMessage());
        return response;
      } catch (InvalidPathException e) {
        response.setInvalidPathError("Error: Invalid Path " + e.getLocalizedMessage());
        return response;
      } catch (UnavailableException e) {
        response.setInvalidPathError("The service is temporarily unavailable. " + e.getMessage());
        return response;
      } catch (IOException e) {
        response.setInvalidPathError(
            "Error: File " + currentPath + " is not available " + e.getMessage());
        return response;
      } catch (AccessControlException e) {
        response.setInvalidPathError(
            "Error: File " + currentPath + " cannot be accessed " + e.getMessage());
        return response;
      }

      List<UIFileInfo> fileInfos = new ArrayList<>(filesInfo.size());
      for (FileInfo fileInfo : filesInfo) {
        UIFileInfo toAdd = new UIFileInfo(fileInfo, ServerConfiguration.global(),
            new MasterStorageTierAssoc().getOrderedStorageAliases());
        try {
          if (!toAdd.getIsDirectory() && fileInfo.getLength() > 0) {
            FileBlockInfo blockInfo =
                mFileSystemMaster.getFileBlockInfoList(new AlluxioURI(toAdd.getAbsolutePath()))
                    .get(0);
            List<String> locations = new ArrayList<>();
            // add the in-Alluxio block locations
            for (BlockLocation location : blockInfo.getBlockInfo().getLocations()) {
              WorkerNetAddress address = location.getWorkerAddress();
              locations.add(address.getHost() + ":" + address.getDataPort());
            }
            // add underFS locations
            locations.addAll(blockInfo.getUfsLocations());
            toAdd.setFileLocations(locations);
          }
        } catch (FileDoesNotExistException e) {
          response.setFileDoesNotExistException("Error: non-existing file " + e.getMessage());
          return response;
        } catch (InvalidPathException e) {
          response.setInvalidPathException("Error: invalid path " + e.getMessage());
          return response;
        } catch (AccessControlException e) {
          response.setAccessControlException(
              "Error: File " + currentPath + " cannot be accessed " + e.getMessage());
          return response;
        }
        fileInfos.add(toAdd);
      }
      Collections.sort(fileInfos, UIFileInfo.PATH_STRING_COMPARE);

      response.setNTotalFile(fileInfos.size());

      try {
        int offset = Integer.parseInt(requestOffset);
        int limit = Integer.parseInt(requestLimit);
        limit = offset == 0 && limit > fileInfos.size() ? fileInfos.size() : limit;
        limit = offset + limit > fileInfos.size() ? fileInfos.size() - offset : limit;
        int sum = Math.addExact(offset, limit);
        fileInfos = fileInfos.subList(offset, sum);
        response.setFileInfos(fileInfos);
      } catch (NumberFormatException e) {
        response.setFatalError("Error: offset or limit parse error, " + e.getLocalizedMessage());
        return response;
      } catch (ArithmeticException e) {
        response.setFatalError(
            "Error: offset or offset + limit is out of bound, " + e.getLocalizedMessage());
        return response;
      } catch (IllegalArgumentException e) {
        response.setFatalError(e.getLocalizedMessage());
        return response;
      }

      return response;
    }, ServerConfiguration.global());
  }
@ GET @ Path ( WEBUI_BROWSE ) @ ReturnType ( "alluxio.wire.MasterWebUIBrowse" ) public Response getWebUIBrowse ( @ DefaultValue ( "/" ) @ QueryParam ( "path" ) String requestPath , @ DefaultValue ( "0" ) @ QueryParam ( "offset" ) String requestOffset , @ DefaultValue ( "" ) @ QueryParam ( "end" ) String requestEnd , @ DefaultValue ( "20" ) @ QueryParam ( "limit" ) String requestLimit ) { return RestUtils . call ( ( ) -> { MasterWebUIBrowse response = new MasterWebUIBrowse ( ) ; if ( ! ServerConfiguration . getBoolean ( PropertyKey . WEB_FILE_INFO_ENABLED ) ) { return response ; } if ( SecurityUtils . isSecurityEnabled ( ServerConfiguration . global ( ) ) && AuthenticatedClientUser . get ( ServerConfiguration . global ( ) ) == null ) { AuthenticatedClientUser . set ( LoginUser . get ( ServerConfiguration . global ( ) ) . getName ( ) ) ; } response . setDebug ( ServerConfiguration . getBoolean ( PropertyKey . DEBUG ) ) . setShowPermissions ( ServerConfiguration . getBoolean ( PropertyKey . SECURITY_AUTHORIZATION_PERMISSION_ENABLED ) ) . setMasterNodeAddress ( mMasterProcess . getRpcAddress ( ) . toString ( ) ) . setInvalidPathError ( "" ) ; List < FileInfo > filesInfo ; String path = requestPath ; if ( path == null || path . isEmpty ( ) ) { path = AlluxioURI . SEPARATOR ; } AlluxioURI currentPath = new AlluxioURI ( path ) ; response . setCurrentPath ( currentPath . toString ( ) ) . setViewingOffset ( 0 ) ; try { long fileId = mFileSystemMaster . getFileId ( currentPath ) ; FileInfo fileInfo = mFileSystemMaster . getFileInfo ( fileId ) ; UIFileInfo currentFileInfo = new UIFileInfo ( fileInfo , ServerConfiguration . global ( ) , new MasterStorageTierAssoc ( ) . getOrderedStorageAliases ( ) ) ; if ( currentFileInfo . getAbsolutePath ( ) == null ) { throw new FileDoesNotExistException ( currentPath . toString ( ) ) ; } response . setCurrentDirectory ( currentFileInfo ) . setBlockSizeBytes ( currentFileInfo . getBlockSizeBytes ( ) ) ; if ( ! currentFileInfo . getIsDirectory ( ) ) { long relativeOffset = 0 ; long offset ; try { if ( requestOffset != null ) { relativeOffset = Long . parseLong ( requestOffset ) ; } } catch ( NumberFormatException e ) { relativeOffset = 0 ; } if ( requestEnd . equals ( "" ) ) { offset = relativeOffset ; } else { offset = fileInfo . getLength ( ) - relativeOffset ; } if ( offset < 0 ) { offset = 0 ; } else if ( offset > fileInfo . getLength ( ) ) { offset = fileInfo . getLength ( ) ; } try { AlluxioURI absolutePath = new AlluxioURI ( currentFileInfo . getAbsolutePath ( ) ) ; FileSystem fs = mFsClient ; String fileData ; URIStatus status = fs . getStatus ( absolutePath ) ; if ( status . isCompleted ( ) ) { OpenFilePOptions options = OpenFilePOptions . newBuilder ( ) . setReadType ( ReadPType . NO_CACHE ) . build ( ) ; try ( FileInStream is = fs . openFile ( absolutePath , options ) ) { int len = ( int ) Math . min ( 5 * Constants . KB , status . getLength ( ) - offset ) ; byte [ ] data = new byte [ len ] ; long skipped = is . skip ( offset ) ; if ( skipped < 0 ) { fileData = "Unable to traverse to offset; is file empty?" ; } else if ( skipped < offset ) { fileData = "Unable to traverse to offset; is offset larger than the file?" ; } else { int read = is . read ( data , 0 , len ) ; if ( read < 0 ) { fileData = "Unable to read file" ; } else { fileData = WebUtils . convertByteArrayToStringWithoutEscape ( data , 0 , read ) ; } } } } else { fileData = "The requested file is not complete yet." ; } List < UIFileBlockInfo > uiBlockInfo = new ArrayList < > ( ) ; for ( FileBlockInfo fileBlockInfo : mFileSystemMaster . getFileBlockInfoList ( absolutePath ) ) { uiBlockInfo . add ( new UIFileBlockInfo ( fileBlockInfo , ServerConfiguration . global ( ) ) ) ; } response . setFileBlocks ( uiBlockInfo ) . setFileData ( fileData ) . setHighestTierAlias ( mBlockMaster . getGlobalStorageTierAssoc ( ) . getAlias ( 0 ) ) ; } catch ( AlluxioException e ) { throw new IOException ( e ) ; } response . setViewingOffset ( offset ) ; return response ; } if ( currentPath . isRoot ( ) ) { response . setPathInfos ( new UIFileInfo [ 0 ] ) ; } else { String [ ] splitPath = PathUtils . getPathComponents ( currentPath . toString ( ) ) ; UIFileInfo [ ] pathInfos = new UIFileInfo [ splitPath . length - 1 ] ; fileId = mFileSystemMaster . getFileId ( currentPath ) ; pathInfos [ 0 ] = new UIFileInfo ( mFileSystemMaster . getFileInfo ( fileId ) , ServerConfiguration . global ( ) , new MasterStorageTierAssoc ( ) . getOrderedStorageAliases ( ) ) ; AlluxioURI breadcrumb = new AlluxioURI ( AlluxioURI . SEPARATOR ) ; for ( int i = 1 ; i < splitPath . length - 1 ; i ++ ) { breadcrumb = breadcrumb . join ( splitPath [ i ] ) ; fileId = mFileSystemMaster . getFileId ( breadcrumb ) ; pathInfos [ i ] = new UIFileInfo ( mFileSystemMaster . getFileInfo ( fileId ) , ServerConfiguration . global ( ) , new MasterStorageTierAssoc ( ) . getOrderedStorageAliases ( ) ) ; } response . setPathInfos ( pathInfos ) ; } filesInfo = mFileSystemMaster . listStatus ( currentPath , ListStatusContext . mergeFrom ( ListStatusPOptions . newBuilder ( ) . setLoadMetadataType ( LoadMetadataPType . ALWAYS ) ) ) ; } catch ( FileDoesNotExistException e ) { response . setInvalidPathError ( "Error: Invalid Path " + e . getMessage ( ) ) ; return response ; } catch ( InvalidPathException e ) { response . setInvalidPathError ( "Error: Invalid Path " + e . getLocalizedMessage ( ) ) ; return response ; } catch ( UnavailableException e ) { response . setInvalidPathError ( "The service is temporarily unavailable. " + e . getMessage ( ) ) ; return response ; } catch ( IOException e ) { response . setInvalidPathError ( "Error: File " + currentPath + " is not available " + e . getMessage ( ) ) ; return response ; } catch ( AccessControlException e ) { response . setInvalidPathError ( "Error: File " + currentPath + " cannot be accessed " + e . getMessage ( ) ) ; return response ; } List < UIFileInfo > fileInfos = new ArrayList < > ( filesInfo . size ( ) ) ; for ( FileInfo fileInfo : filesInfo ) { UIFileInfo toAdd = new UIFileInfo ( fileInfo , ServerConfiguration . global ( ) , new MasterStorageTierAssoc ( ) . getOrderedStorageAliases ( ) ) ; try { if ( ! toAdd . getIsDirectory ( ) && fileInfo . getLength ( ) > 0 ) { FileBlockInfo blockInfo = mFileSystemMaster . getFileBlockInfoList ( new AlluxioURI ( toAdd . getAbsolutePath ( ) ) ) . get ( 0 ) ; List < String > locations = new ArrayList < > ( ) ; for ( BlockLocation location : blockInfo . getBlockInfo ( ) . getLocations ( ) ) { WorkerNetAddress address = location . getWorkerAddress ( ) ; locations . add ( address . getHost ( ) + ":" + address . getDataPort ( ) ) ; } locations . addAll ( blockInfo . getUfsLocations ( ) ) ; toAdd . setFileLocations ( locations ) ; } } catch ( FileDoesNotExistException e ) { response . setFileDoesNotExistException ( "Error: non-existing file " + e . getMessage ( ) ) ; return response ; } catch ( InvalidPathException e ) { response . setInvalidPathException ( "Error: invalid path " + e . getMessage ( ) ) ; return response ; } catch ( AccessControlException e ) { response . setAccessControlException ( "Error: File " + currentPath + " cannot be accessed " + e . getMessage ( ) ) ; return response ; } fileInfos . add ( toAdd ) ; } Collections . sort ( fileInfos , UIFileInfo . PATH_STRING_COMPARE ) ; response . setNTotalFile ( fileInfos . size ( ) ) ; try { int offset = Integer . parseInt ( requestOffset ) ; int limit = Integer . parseInt ( requestLimit ) ; limit = offset == 0 && limit > fileInfos . size ( ) ? fileInfos . size ( ) : limit ; limit = offset + limit > fileInfos . size ( ) ? fileInfos . size ( ) - offset : limit ; int sum = Math . addExact ( offset , limit ) ; fileInfos = fileInfos . subList ( offset , sum ) ; response . setFileInfos ( fileInfos ) ; } catch ( NumberFormatException e ) { response . setFatalError ( "Error: offset or limit parse error, " + e . getLocalizedMessage ( ) ) ; return response ; } catch ( ArithmeticException e ) { response . setFatalError ( "Error: offset or offset + limit is out of bound, " + e . getLocalizedMessage ( ) ) ; return response ; } catch ( IllegalArgumentException e ) { response . setFatalError ( e . getLocalizedMessage ( ) ) ; return response ; } return response ; } , ServerConfiguration . global ( ) ) ; }
Gets Web UI browse page data.

@param requestPath the request path
@param requestOffset the request offset
@param requestEnd the request end
@param requestLimit the request limit
@return the response object