package coprocessor; import java.io.IOException; import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.CoprocessorEnvironment; import org.apache.hadoop.hbase.client.Durability; import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.coprocessor.BaseRegionObserver; import org.apache.hadoop.hbase.coprocessor.ObserverContext; import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment; import org.apache.hadoop.hbase.regionserver.HRegion; import org.apache.hadoop.hbase.regionserver.wal.WALEdit; import org.apache.hadoop.hbase.util.Bytes; // cc SequentialIdGeneratorObserver Adds a coprocessor local ID into the operation public class SequentialIdGeneratorObserver extends BaseRegionObserver { public static final Log LOG = LogFactory.getLog(HRegion.class); // vv SequentialIdGeneratorObserver private static String KEY_ID = "X-ID-GEN"; private byte[] family; private byte[] qualifier; private String regionName; private Random rnd = new Random(); private int delay; @Override public void start(CoprocessorEnvironment e) throws IOException { if (e instanceof RegionCoprocessorEnvironment) { RegionCoprocessorEnvironment env = (RegionCoprocessorEnvironment) e; Configuration conf = env.getConfiguration(); // co SequentialIdGeneratorObserver-1-Conf Get environment and configuration instances. this.regionName = env.getRegionInfo().getEncodedName(); String family = conf.get("com.larsgeorge.copro.seqidgen.family", "cf1"); this.family = Bytes.toBytes(family); String qualifier = conf.get("com.larsgeorge.copro.seqidgen.qualifier", // co SequentialIdGeneratorObserver-2-Settings Retrieve the settings passed into the configuration. "GENID"); this.qualifier = Bytes.toBytes(qualifier); int startId = conf.getInt("com.larsgeorge.copro.seqidgen.startId", 1); this.delay = conf.getInt("com.larsgeorge.copro.seqidgen.delay", 100); env.getSharedData().putIfAbsent(KEY_ID, new AtomicInteger(startId)); // co SequentialIdGeneratorObserver-3-Gen Set up generator if this has not been done yet on this region server. } else { LOG.warn("Received wrong context."); } } @Override public void stop(CoprocessorEnvironment e) throws IOException { if (e instanceof RegionCoprocessorEnvironment) { RegionCoprocessorEnvironment env = (RegionCoprocessorEnvironment) e; AtomicInteger id = (AtomicInteger) env.getSharedData().get(KEY_ID); LOG.info("Final ID issued: " + regionName + "-" + id.get()); // co SequentialIdGeneratorObserver-4-Log Log the final number generated by this coprocessor. } else { LOG.warn("Received wrong context."); } } @Override public void prePut(ObserverContext<RegionCoprocessorEnvironment> e, Put put, WALEdit edit, Durability durability) throws IOException { RegionCoprocessorEnvironment env = e.getEnvironment(); AtomicInteger id = (AtomicInteger) env.getSharedData().get(KEY_ID); put.addColumn(family, qualifier, Bytes.toBytes(regionName + "-" + // co SequentialIdGeneratorObserver-5-SetId Set the shared ID for this instance of put. id.incrementAndGet())); try { Thread.sleep(rnd.nextInt(delay)); // co SequentialIdGeneratorObserver-6-Sleep Sleep for 0 to "delay" milliseconds. } catch (InterruptedException e1) { e1.printStackTrace(); } } // ^^ SequentialIdGeneratorObserver }