Index: src/main/java/org/apache/hadoop/hbase/master/GroupStatusServlet.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/master/GroupStatusServlet.java (revision 0) +++ src/main/java/org/apache/hadoop/hbase/master/GroupStatusServlet.java (working copy) @@ -0,0 +1,141 @@ +/** + * Copyright 2011 The Apache Software Foundation + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.hbase.master; + +import java.io.IOException; + +import java.util.ArrayList; +import java.util.Map; + +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.hbase.ServerName; +import org.apache.hadoop.hbase.master.GroupInfoManager.ServerPlan; +import org.apache.hbase.tmpl.master.GroupStatusTmpl; + +/** + * The servlet responsible for rendering the group manager + */ +public class GroupStatusServlet extends HttpServlet { + private static final Log LOG = LogFactory.getLog(GroupStatusServlet.class); + private static final long serialVersionUID = 1L; + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws IOException { + HMaster master = (HMaster) getServletContext().getAttribute( + HMaster.MASTER); + assert master != null : "No Master in context!"; + ServerName rootLocation = getRootLocationOrNull(master); + ServerName metaLocation = master.getCatalogTracker().getMetaLocation(); + + GroupInfoManager manager = ((RSGroupAssignmentManager)master.getAssignmentManager()).getInfoManager(); + Map groups = manager.getGroups(); + ArrayList allgroups = getGroupList(groups); + ArrayList moveplans = null; + + response.setContentType("text/html"); + + GroupStatusTmpl tmpl = new GroupStatusTmpl() + .setRootLocation(rootLocation).setMetaLocation(metaLocation) + .setManager(manager) + .setGroups(groups).setAllgroups(allgroups); + if (request.getParameter("action") != null) + tmpl.setAction(request.getParameter("action")); + if (request.getParameter("newgroupname") != null) { + tmpl.setNewgroupname(request.getParameter("newgroupname")); + } + if (request.getParameter("groupname") != null) { + tmpl.setGroupname(request.getParameter("groupname")); + } + if (request.getParameter("tablename") != null) { + tmpl.setTablename(request.getParameter("tablename")); + } + if (request.getParameter("special") != null) { + tmpl.setSpecial(request.getParameter("special")); + } + if (request.getParameter("plan") != null) { + tmpl.setPlan(request.getParameter("plan")); + moveplans = parseServerMovePlanLine(request.getParameter("plan")); + tmpl.setMoveplans(moveplans); + } + tmpl.render(response.getWriter(), master); + } + + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws IOException { + doGet(request,response); + } + + public static ArrayList getGroupList( + final Map groups) { + ArrayList allgroups = new ArrayList(); + for (Map.Entry entry : groups.entrySet()) { + allgroups.add(entry.getKey()); + } + return allgroups; + } + + private ServerName getRootLocationOrNull(HMaster master) { + try { + return master.getCatalogTracker().getRootLocation(); + } catch (InterruptedException e) { + LOG.warn("Unable to get root location", e); + return null; + } + } + + /** + * Parse line to list of {@link ServerMovingPlan} + * + * @param line + * plan line ,like + * data1:60020:1325087182657:0:1#data2:60020:1325087182657 + * :0:1,plan split by '#', + * @return list of {@link ServerMovingPlan} + */ + public static ArrayList parseServerMovePlanLine( + final String planLine) { + ArrayList plans = new ArrayList(); + if (planLine == null || planLine.length() <= 0) + return plans; + String[] pls = planLine.split(GroupInfo.MOVEPLAN_SPLITER); + ServerName sn = null; + ServerPlan plan = null; + for (String st : pls) { + String[] data = st.split(":"); + try { + sn = new ServerName(data[0] + ":" + data[1], + Long.valueOf(data[2])); + plan = new ServerPlan(sn, data[3], data[4]); + plans.add(plan); + } catch (Exception e) { + LOG.error("Invalid plan line format ", e); + continue; + } + } + return plans; + } +} Index: src/main/java/org/apache/hadoop/hbase/master/GroupInfoServlet.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/master/GroupInfoServlet.java (revision 0) +++ src/main/java/org/apache/hadoop/hbase/master/GroupInfoServlet.java (working copy) @@ -0,0 +1,58 @@ +/** + * Copyright The Apache Software Foundation + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.hbase.master; + +import java.io.IOException; + +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.hbase.tmpl.master.GroupInfoTmpl; +/** + * The servlet responsible for rendering the group information + */ +public class GroupInfoServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws IOException { + HMaster master = (HMaster) getServletContext().getAttribute( + HMaster.MASTER); + assert master != null : "No Master in context!"; + String groupName = request.getParameter("name"); + if (groupName == null) + groupName = GroupInfo.DEFAULT_GROUP; + GroupInfoManager manager = ((RSGroupAssignmentManager)master.getAssignmentManager()).getInfoManager(); + GroupInfo groupinfo = manager.getGroups().get(groupName); + response.setContentType("text/html"); + GroupInfoTmpl tmpl = new GroupInfoTmpl().setGroupName(groupName) + .setManager(manager) + .setGroupinfo(groupinfo); + tmpl.render(response.getWriter(), master); + } + + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws IOException { + doGet(request, response); + } +} Index: src/main/java/org/apache/hadoop/hbase/master/HMaster.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/master/HMaster.java (revision 1227140) +++ src/main/java/org/apache/hadoop/hbase/master/HMaster.java (working copy) @@ -755,6 +755,8 @@ this.infoServer = new InfoServer(MASTER, a, port, false, this.conf); this.infoServer.addServlet("status", "/master-status", MasterStatusServlet.class); this.infoServer.addServlet("dump", "/dump", MasterDumpServlet.class); + this.infoServer.addServlet("group", "/group-status",GroupStatusServlet.class); + this.infoServer.addServlet("groupinfo", "/group-info",GroupInfoServlet.class); this.infoServer.setAttribute(MASTER, this); this.infoServer.start(); } Index: src/main/jamon/org/apache/hbase/tmpl/master/GroupStatusTmpl.jamon =================================================================== --- src/main/jamon/org/apache/hbase/tmpl/master/GroupStatusTmpl.jamon (revision 0) +++ src/main/jamon/org/apache/hbase/tmpl/master/GroupStatusTmpl.jamon (working copy) @@ -0,0 +1,285 @@ +<%doc> +Copyright 2011 The Apache Software Foundation + +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +<%args> +HMaster master; +ServerName rootLocation = null; +ServerName metaLocation = null; +GroupInfoManager manager = null; +Map groups = null; +ArrayList allgroups = null; +ArrayList moveplans= null; +String action=null; +String newgroupname =null; +String special=null; +String plan =null; +String groupname=null; +String tablename=null; + +<%import> +java.util.ArrayList; +java.util.HashSet; +java.util.Map; +org.apache.hadoop.hbase.ServerName; +org.apache.hadoop.hbase.master.GroupInfo; +org.apache.hadoop.hbase.master.GroupInfoManager; +org.apache.hadoop.hbase.master.GroupInfoManager.ServerPlan; +org.apache.hadoop.hbase.HServerLoad; +org.apache.hadoop.hbase.master.HMaster; + +<%java + boolean stat= false; + int successnum = 0; + %> +<%if action!=null %> + + + Hbase Group Action Process + + + + + +

Group action request accepted

+

+


+

+ <%if action.equals("addgroup") && newgroupname != null %> +
newgroupname is:<% newgroupname %>

+ <%java stat = manager.addGroup(newgroupname, + special == null ? false : true); %> + <%if stat == false %> + Add group exception + + Add Group request accepted. + <%elseif action.equals("moveserverplan") && plan != null %> +
moveplan is:<% plan %>

+ <%java successnum = manager.moveServer(moveplans).size(); %> + <%if successnum == 0 %> + Move server exception + + Move Server request accepted. + <%elseif action.equals("deletegroup") && groupname != null %> +
groupname is:<% groupname %>

+ <%java stat = manager.removeGroup(groupname); %> + <%if stat == false %> + Delete group exception + + Delete Group request accepted + <%elseif action.equals("balancegroup") && groupname != null %> +
groupname is:<% groupname %>

+ <%java stat = manager.balanceGroup(groupname); %> + <%if stat == false %> + Balance group exception + + Balance Group request accepted. + <%elseif action.equals("changetable") && tablename != null && newgroupname != null %> +
tablename is:<% tablename %>

+
newgroupname is:<% newgroupname %>

+ <%java stat = GroupInfoManager.changeTableGroup(master.getConfiguration(),newgroupname, tablename); %> + <%if stat == false %> + Change table group exception + + Change Table request accepted. + <%elseif action.equals("balancetable") && tablename != null %> +
tablename is:<% tablename %>

+ <%java stat = manager.balanceTable(tablename); %> + <%if stat == false %> + Balance table group exception + + Balance Table request accepted. + <%else> +

404 , Unknown Action request

+ +

+ Go Group Manage Page, or wait for the + redirect. +

+ + <%java return; %> +<%else> + + + + Hbase Group Manage Information + + + + + +

Group Information Management

+ +
+
+

Group Information:

+
+ + + + + + + + + <%for Map.Entry entry : groups.entrySet() %> + + + + + + <%if entry.getValue().isDefault() %> + + + <%else> + + + + + + + + + + + + + +
GroupNameServerNumberRegionNumberisSpecialAction
group:<% entry.getKey()%> + <% entry.getValue().getServers().size() %><% manager.getRegionsOfGroup(entry.getKey()).size() %><% entry.getValue().isSpecialConf() %>DEFAULT_GROUP
Delete + Group: <% entry.getKey() %> +
groupname:isSpecial: + +
+
+
+ +
+

Group Server Detail:

+
+ + + + + + + + + <%java + String origroup = null; + GroupInfo groupinfo = null; + HashSet servers = null; + int index = 0; + %> + <%for Map.Entry entry : groups.entrySet() %> + <%java + origroup = entry.getKey(); + servers = entry.getValue().getServers(); + %> + <%for ServerName server : servers %> + <%java + int infoPort = master.getConfiguration().getInt( + "hbase.regionserver.info.port", 60030); + String url = "http://" + server.getHostname() + ":" + infoPort + + "/"; + HServerLoad hsl = master.getServerManager().getLoad(server); + String planline = null; + %> + + + + + + <%if (server.equals(rootLocation) || server.equals(metaLocation)) %> + + + <%else> + + + + <%java + index++; + %> + + + + + + + + + + + + + +
ServerNameRequestNumberRegionNumberoriginalGrouptargetGroup
><% server.getHostAndPort() %> + <% hsl == null ? 0 : hsl.getNumberOfRequests() %><% hsl == null ? 0 : hsl.getNumberOfRegions() %>group:<% origroup %>ROOT_or_META +
Status +
+
+
+ + + Index: src/main/jamon/org/apache/hbase/tmpl/master/GroupInfoTmpl.jamon =================================================================== --- src/main/jamon/org/apache/hbase/tmpl/master/GroupInfoTmpl.jamon (revision 0) +++ src/main/jamon/org/apache/hbase/tmpl/master/GroupInfoTmpl.jamon (working copy) @@ -0,0 +1,145 @@ +<%doc> +Copyright 2011 The Apache Software Foundation + +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +<%args> +HMaster master; +String groupName = null; +GroupInfoManager manager = null; +GroupInfo groupinfo = null; + +<%import> +java.util.HashSet; +java.util.List; +org.apache.hadoop.hbase.ServerName; +org.apache.hadoop.hbase.HServerLoad; +org.apache.hadoop.hbase.master.HMaster; +org.apache.hadoop.hbase.master.GroupInfo; +org.apache.hadoop.hbase.master.GroupInfoManager; +org.apache.hadoop.hbase.util.Bytes; +org.apache.hadoop.hbase.HTableDescriptor; + + + + +Group <% groupName %> Information Detail + + + + +

Group <% groupName %> Information Detail

+ +
+
+
+ Group <% groupName %> Servers Detail: +
+
+ + + + + + + <%java + HashSet serverset = groupinfo.getServers(); + int regionnum = 0; + int tablenum = 0; + int tablesize = 0; + int regionsize = 0; + %> + <%for ServerName server : serverset %> + <%java + int infoPort = master.getConfiguration().getInt( + "hbase.regionserver.info.port", 60030); + String url = "http://" + server.getHostname() + ":" + infoPort + + "/"; + HServerLoad hsl = master.getServerManager().getLoad(server); + tablesize = manager.getTablesOfServer(server).size(); + regionsize = (hsl == null ? 0 : hsl.getNumberOfRegions()); + tablenum +=tablesize; + regionnum += regionsize; + %> + + + + + + + + + + + +
ServerNameTableNumberRegionNumber
><% server.getHostAndPort() %> + <% tablesize %><% regionsize %>
Total<% tablenum %><% regionnum %>
+
+ +
+
+
+ Group <% groupName %> Table Detail: +
+
+ + + + + + + + + <%java + List tables = manager.getTablesOfGroup(groupName); + HTableDescriptor des =null; + %> + <%for String tableName : tables %> + + <%java des = master.getTableDescriptors().get(tableName);%> + + + + <%if (!des.isMetaRegion() && !des.isRootRegion()) %> + + + + + + + + +
TableNameRegionNumberoriginalGroupnewGroupbalance
><% tableName %><% master.getAssignmentManager().getRegionsOfTable(Bytes.toBytes(tableName)).size() %><% GroupInfo.getGroupString(des) %>
+ + Balance Table: <% des.getNameAsString() %> +
+
+
+ +