001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.master.http.hbck.resource; 019 020import java.util.List; 021import java.util.stream.Collectors; 022import javax.inject.Inject; 023import org.apache.hadoop.hbase.HbckEmptyRegionInfo; 024import org.apache.hadoop.hbase.HbckInconsistentRegions; 025import org.apache.hadoop.hbase.HbckOrphanRegionsOnFS; 026import org.apache.hadoop.hbase.HbckOrphanRegionsOnRS; 027import org.apache.hadoop.hbase.HbckOverlapRegions; 028import org.apache.hadoop.hbase.HbckRegionDetails; 029import org.apache.hadoop.hbase.HbckRegionHoles; 030import org.apache.hadoop.hbase.HbckServerName; 031import org.apache.hadoop.hbase.HbckUnknownServers; 032import org.apache.hadoop.hbase.ServerName; 033import org.apache.hadoop.hbase.client.RegionInfo; 034import org.apache.hadoop.hbase.master.MasterServices; 035import org.apache.hadoop.hbase.master.hbck.HbckReport; 036import org.apache.hadoop.hbase.master.http.hbck.model.HbckMetrics; 037import org.apache.hadoop.hbase.master.janitor.CatalogJanitorReport; 038import org.apache.hadoop.hbase.util.Bytes; 039import org.apache.yetus.audience.InterfaceAudience; 040 041import org.apache.hbase.thirdparty.javax.ws.rs.GET; 042import org.apache.hbase.thirdparty.javax.ws.rs.Path; 043import org.apache.hbase.thirdparty.javax.ws.rs.Produces; 044import org.apache.hbase.thirdparty.javax.ws.rs.core.MediaType; 045 046/** 047 * The root object exposing hbck.jsp page as JSON Output. 048 */ 049@Path("hbck-metrics") 050@Produces({ MediaType.APPLICATION_JSON }) 051@InterfaceAudience.Private 052public class HbckMetricsResource { 053 private final HbckReport hbckReport; 054 private final CatalogJanitorReport catalogJanitorReport; 055 056 @Inject 057 public HbckMetricsResource(MasterServices master) { 058 this.hbckReport = master.getHbckChore().getLastReport(); 059 this.catalogJanitorReport = master.getCatalogJanitor().getLastReport(); 060 } 061 062 @GET 063 public HbckMetrics getBaseHbckMetrics() { 064 return new HbckMetrics(hbckReport.getCheckingStartTimestamp().toEpochMilli(), 065 hbckReport.getCheckingEndTimestamp().toEpochMilli(), getOrphanRegionsOnFS(), 066 getOrphanRegionsOnRS(), getInconsistentRegions(), getRegionChainHoles(), 067 getRegionChainOverlap(), getUnknownServers(), getEmptyRegionInfo()); 068 } 069 070 @GET 071 @Path("/orphan-regions-on-fs") 072 public List<HbckOrphanRegionsOnFS> getOrphanRegionsOnFS() { 073 return hbckReport.getOrphanRegionsOnFS().entrySet().stream() 074 .map(obj1 -> new HbckOrphanRegionsOnFS(obj1.getKey(), obj1.getValue().toString())) 075 .collect(Collectors.toList()); 076 } 077 078 @GET 079 @Path("/orphan-regions-on-rs") 080 public List<HbckOrphanRegionsOnRS> getOrphanRegionsOnRS() { 081 return hbckReport.getOrphanRegionsOnRS().entrySet().stream() 082 .map(obj1 -> new HbckOrphanRegionsOnRS(obj1.getKey(), parseServerName(obj1.getValue()))) 083 .collect(Collectors.toList()); 084 } 085 086 @GET 087 @Path("/inconsistent-regions") 088 public List<HbckInconsistentRegions> getInconsistentRegions() { 089 return hbckReport.getInconsistentRegions().entrySet().stream() 090 .map(obj1 -> new HbckInconsistentRegions(obj1.getKey(), 091 parseServerName(obj1.getValue().getFirst()), obj1.getValue().getSecond().stream() 092 .map(this::parseServerName).collect(Collectors.toList()))) 093 .collect(Collectors.toList()); 094 } 095 096 @GET 097 @Path("/region-holes") 098 public List<HbckRegionHoles> getRegionChainHoles() { 099 return catalogJanitorReport.getHoles().stream() 100 .map(obj1 -> new HbckRegionHoles(parseRegionInfo(obj1.getFirst()), 101 parseRegionInfo(obj1.getSecond()))) 102 .collect(Collectors.toList()); 103 } 104 105 @GET 106 @Path("/region-overlaps") 107 public List<HbckOverlapRegions> getRegionChainOverlap() { 108 return catalogJanitorReport.getOverlaps().stream() 109 .map(obj1 -> new HbckOverlapRegions(parseRegionInfo(obj1.getFirst()), 110 parseRegionInfo(obj1.getSecond()))) 111 .collect(Collectors.toList()); 112 } 113 114 @GET 115 @Path("/unknown-servers") 116 public List<HbckUnknownServers> getUnknownServers() { 117 return catalogJanitorReport.getUnknownServers().stream() 118 .map(obj1 -> new HbckUnknownServers(parseRegionInfo(obj1.getFirst()), 119 parseServerName(obj1.getSecond()))) 120 .collect(Collectors.toList()); 121 } 122 123 @GET 124 @Path("/empty-regioninfo") 125 public List<HbckEmptyRegionInfo> getEmptyRegionInfo() { 126 return catalogJanitorReport.getEmptyRegionInfo().stream() 127 .map(obj1 -> new HbckEmptyRegionInfo(Bytes.toString(obj1))).collect(Collectors.toList()); 128 } 129 130 public HbckRegionDetails parseRegionInfo(RegionInfo regionInfo) { 131 return new HbckRegionDetails(regionInfo.getEncodedName(), 132 regionInfo.getTable().getNameAsString(), new String(regionInfo.getStartKey()), 133 new String(regionInfo.getEndKey())); 134 } 135 136 public HbckServerName parseServerName(ServerName serverName) { 137 return new HbckServerName(serverName.getHostname(), serverName.getPort(), 138 serverName.getStartCode()); 139 } 140}