/* * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0 * (the "License"). You may not use this work except in compliance with the License, which is * available at www.apache.org/licenses/LICENSE-2.0 * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied, as more fully set forth in the License. * * See the NOTICE file distributed with this work for information regarding copyright ownership. */ package alluxio.web; import alluxio.Configuration; import alluxio.PropertyKey; import alluxio.RuntimeConstants; import alluxio.StorageTierAssoc; import alluxio.master.MasterProcess; import alluxio.master.block.BlockMaster; import alluxio.master.file.FileSystemMaster; import alluxio.master.file.StartupConsistencyCheck; import alluxio.underfs.UnderFileSystem; import alluxio.util.FormatUtils; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.annotation.concurrent.ThreadSafe; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet that provides data for viewing the general status of the filesystem. */ @ThreadSafe public final class WebInterfaceGeneralServlet extends HttpServlet { /** * Class to make referencing tiered storage information more intuitive. */ public static final class StorageTierInfo { private final String mStorageTierAlias; private final long mCapacityBytes; private final long mUsedBytes; private final int mUsedPercent; private final long mFreeBytes; private final int mFreePercent; private StorageTierInfo(String storageTierAlias, long capacityBytes, long usedBytes) { mStorageTierAlias = storageTierAlias; mCapacityBytes = capacityBytes; mUsedBytes = usedBytes; mFreeBytes = mCapacityBytes - mUsedBytes; mUsedPercent = (int) (100L * mUsedBytes / mCapacityBytes); mFreePercent = 100 - mUsedPercent; } /** * @return the storage alias */ public String getStorageTierAlias() { return mStorageTierAlias; } /** * @return the capacity */ public String getCapacity() { return FormatUtils.getSizeFromBytes(mCapacityBytes); } /** * @return the free capacity */ public String getFreeCapacity() { return FormatUtils.getSizeFromBytes(mFreeBytes); } /** * @return the free space as a percentage */ public int getFreeSpacePercent() { return mFreePercent; } /** * @return the used capacity */ public String getUsedCapacity() { return FormatUtils.getSizeFromBytes(mUsedBytes); } /** * @return the used space as a percentage */ public int getUsedSpacePercent() { return mUsedPercent; } } private static final long serialVersionUID = 2335205655766736309L; private final transient MasterProcess mMasterProcess; /** * Creates a new instance of {@link WebInterfaceGeneralServlet}. * * @param masterProcess Alluxio master process */ public WebInterfaceGeneralServlet(MasterProcess masterProcess) { mMasterProcess = masterProcess; } /** * Redirects the request to a JSP after populating attributes via populateValues. * * @param request the {@link HttpServletRequest} object * @param response the {@link HttpServletResponse} object * @throws ServletException if the target resource throws this exception */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { populateValues(request); getServletContext().getRequestDispatcher("/general.jsp").forward(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { populateValues(request); getServletContext().getRequestDispatcher("/general.jsp").forward(request, response); } /** * Lists the {@link StorageTierInfo} objects of each storage level alias. * * @return the list of {@link StorageTierInfo} objects, in order from highest tier to lowest */ private StorageTierInfo[] generateOrderedStorageTierInfo() { BlockMaster blockMaster = mMasterProcess.getMaster(BlockMaster.class); StorageTierAssoc globalStorageTierAssoc = blockMaster.getGlobalStorageTierAssoc(); List<StorageTierInfo> infos = new ArrayList<>(); Map<String, Long> totalBytesOnTiers = blockMaster.getTotalBytesOnTiers(); Map<String, Long> usedBytesOnTiers = blockMaster.getUsedBytesOnTiers(); for (int ordinal = 0; ordinal < globalStorageTierAssoc.size(); ordinal++) { String tierAlias = globalStorageTierAssoc.getAlias(ordinal); if (totalBytesOnTiers.containsKey(tierAlias) && totalBytesOnTiers.get(tierAlias) > 0) { StorageTierInfo info = new StorageTierInfo(tierAlias, totalBytesOnTiers.get(tierAlias), usedBytesOnTiers.get(tierAlias)); infos.add(info); } } return infos.toArray(new StorageTierInfo[infos.size()]); } /** * Populates key, value pairs for UI display. * * @param request The {@link HttpServletRequest} object */ private void populateValues(HttpServletRequest request) throws IOException { BlockMaster blockMaster = mMasterProcess.getMaster(BlockMaster.class); FileSystemMaster fileSystemMaster = mMasterProcess.getMaster(FileSystemMaster.class); request.setAttribute("debug", Configuration.getBoolean(PropertyKey.DEBUG)); request.setAttribute("masterNodeAddress", mMasterProcess.getRpcAddress().toString()); request.setAttribute("uptime", WebUtils .convertMsToClockTime(System.currentTimeMillis() - mMasterProcess.getStartTimeMs())); request.setAttribute("startTime", WebUtils.convertMsToDate(mMasterProcess.getStartTimeMs())); request.setAttribute("version", RuntimeConstants.VERSION); request.setAttribute("liveWorkerNodes", Integer.toString(blockMaster.getWorkerCount())); request.setAttribute("capacity", FormatUtils.getSizeFromBytes(blockMaster.getCapacityBytes())); request.setAttribute("usedCapacity", FormatUtils.getSizeFromBytes(blockMaster.getUsedBytes())); request.setAttribute("freeCapacity", FormatUtils.getSizeFromBytes(blockMaster.getCapacityBytes() - blockMaster.getUsedBytes())); StartupConsistencyCheck check = fileSystemMaster.getStartupConsistencyCheck(); request.setAttribute("consistencyCheckStatus", check.getStatus()); if (check.getStatus() == StartupConsistencyCheck.Status.COMPLETE) { request.setAttribute("inconsistentPaths", check.getInconsistentUris().size()); request.setAttribute("inconsistentPathItems", check.getInconsistentUris()); } else { request.setAttribute("inconsistentPaths", 0); } String ufsRoot = Configuration.get(PropertyKey.MASTER_MOUNT_TABLE_ROOT_UFS); UnderFileSystem ufs = UnderFileSystem.Factory.create(ufsRoot); long sizeBytes = ufs.getSpace(ufsRoot, UnderFileSystem.SpaceType.SPACE_TOTAL); if (sizeBytes >= 0) { request.setAttribute("diskCapacity", FormatUtils.getSizeFromBytes(sizeBytes)); } else { request.setAttribute("diskCapacity", "UNKNOWN"); } sizeBytes = ufs.getSpace(ufsRoot, UnderFileSystem.SpaceType.SPACE_USED); if (sizeBytes >= 0) { request.setAttribute("diskUsedCapacity", FormatUtils.getSizeFromBytes(sizeBytes)); } else { request.setAttribute("diskUsedCapacity", "UNKNOWN"); } sizeBytes = ufs.getSpace(ufsRoot, UnderFileSystem.SpaceType.SPACE_FREE); if (sizeBytes >= 0) { request.setAttribute("diskFreeCapacity", FormatUtils.getSizeFromBytes(sizeBytes)); } else { request.setAttribute("diskFreeCapacity", "UNKNOWN"); } StorageTierInfo[] infos = generateOrderedStorageTierInfo(); request.setAttribute("storageTierInfos", infos); } }