<%doc>

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.
</%doc>
<%import>
org.apache.hadoop.hbase.HRegionInfo;
org.apache.hadoop.hbase.master.AssignmentManager;
org.apache.hadoop.hbase.master.RegionState;
org.apache.hadoop.conf.Configuration;
org.apache.hadoop.hbase.HBaseConfiguration;
org.apache.hadoop.hbase.HConstants;
java.util.Iterator;
java.util.Map;
</%import>
<%args>
AssignmentManager assignmentManager;
int limit = 100;
</%args>
<%java>
Map<String, RegionState> rit = assignmentManager
  .getRegionStates().getRegionsInTransition();
// process the map to find region in transition details
Configuration conf = HBaseConfiguration.create();
int ritThreshold = conf.getInt(HConstants.METRICS_RIT_STUCK_WARNING_THRESHOLD, 60000);
int numOfRITOverThreshold = 0;
long maxRITTime = Long.MIN_VALUE;
long currentTime = System.currentTimeMillis();
String regionIDForOldestRIT = ""; // avoiding null
for (Map.Entry<String, RegionState> e : rit.entrySet()) {
  long ritTime = currentTime - e.getValue().getStamp();
  if(ritTime > ritThreshold) {
     numOfRITOverThreshold++;
   }
   if(maxRITTime < ritTime) {
     maxRITTime = ritTime;
     regionIDForOldestRIT = e.getKey();
   }
}

int toRemove = rit.size() - limit;
int removed = 0;
if (toRemove > 0) {
  // getRegionsInTransition returned a copy, so we can mutate it
  for (Iterator<Map.Entry<String, RegionState>> it = rit.entrySet().iterator();
       it.hasNext() && toRemove > 0;
       ) {
    Map.Entry<String, RegionState> e = it.next();
    if (HRegionInfo.FIRST_META_REGIONINFO.getEncodedName().equals(
          e.getKey()) ||
        HRegionInfo.ROOT_REGIONINFO.getEncodedName().equals(
          e.getKey()) || regionIDForOldestRIT.equals(e.getKey())) {
      // don't remove the meta & the oldest rit regions, they're too interesting!
      continue;
    } 
    it.remove();
    toRemove--;
    removed++;
  }
}

</%java>


<%if !rit.isEmpty() %>
    <h2>Regions in Transition</h2>
    <table class="table table-striped">
            <tr><th>Region</th><th>State</th><th>RIT time (ms)</th></tr>
            <%for Map.Entry<String, RegionState> entry : rit.entrySet() %>
            <%if regionIDForOldestRIT.equals(entry.getKey()) %>
                    <tr BGCOLOR="#FE2E2E" >
            <%else>
                    <tr>
            </%if>
            <td><% entry.getKey() %></td><td><% entry.getValue().toDescriptiveString() %></td>
    <td><% (currentTime - entry.getValue().getStamp()) %> </td></tr>
            </%for>
            <tr BGCOLOR="#D7DF01"> <td>Total number of Regions in Transition for more than <% ritThreshold %> milliseconds</td><td> <% numOfRITOverThreshold %></td><td></td>
            </tr>
    <tr> <td> Total number of Regions in Transition</td><td><% rit.size() %> </td><td></td>
    </table>
    <%if removed > 0 %>
    (<% removed %> more regions in transition not shown)
    </%if>
</%if>

