@Override public void nodeDataChanged(String path) { if (keysParentZNode.equals(ZKUtil.getParent(path))) { try { byte[] data = ZKUtil.getDataAndWatch(watcher, path); if (data == null || data.length == 0) { LOG.debug("Ignoring empty node "+path); return; } AuthenticationKey key = (AuthenticationKey)Writables.getWritable(data, new AuthenticationKey()); secretManager.addKey(key); } catch (KeeperException ke) { LOG.fatal("Error reading data from zookeeper", ke); watcher.abort("Error reading updated key znode "+path, ke); } catch (IOException ioe) { LOG.fatal("Error reading key writables", ioe); watcher.abort("Error reading key writables from znode "+path, ioe); } } }
private void refreshNodes(List<ZKUtil.NodeAndData> nodes) { for (ZKUtil.NodeAndData n : nodes) { String path = n.getNode(); String keyId = ZKUtil.getNodeName(path); try { byte[] data = n.getData(); if (data == null || data.length == 0) { LOG.debug("Ignoring empty node "+path); continue; } AuthenticationKey key = (AuthenticationKey)Writables.getWritable( data, new AuthenticationKey()); secretManager.addKey(key); } catch (IOException ioe) { LOG.fatal("Failed reading new secret key for id '" + keyId + "' from zk", ioe); watcher.abort("Error deserializing key from znode "+path, ioe); } } }
public void addKeyToZK(AuthenticationKey key) { String keyZNode = getKeyNode(key.getKeyId()); try { byte[] keyData = Writables.getBytes(key); // TODO: is there any point in retrying beyond what ZK client does? ZKUtil.createSetData(watcher, keyZNode, keyData); } catch (KeeperException ke) { LOG.fatal("Unable to synchronize master key "+key.getKeyId()+ " to znode "+keyZNode, ke); watcher.abort("Unable to synchronize secret key "+ key.getKeyId()+" in zookeeper", ke); } catch (IOException ioe) { // this can only happen from an error serializing the key watcher.abort("Failed serializing key "+key.getKeyId(), ioe); } }
public void updateKeyInZK(AuthenticationKey key) { String keyZNode = getKeyNode(key.getKeyId()); try { byte[] keyData = Writables.getBytes(key); try { ZKUtil.updateExistingNodeData(watcher, keyZNode, keyData, -1); } catch (KeeperException.NoNodeException ne) { // node was somehow removed, try adding it back ZKUtil.createSetData(watcher, keyZNode, keyData); } } catch (KeeperException ke) { LOG.fatal("Unable to update master key "+key.getKeyId()+ " in znode "+keyZNode); watcher.abort("Unable to synchronize secret key "+ key.getKeyId()+" in zookeeper", ke); } catch (IOException ioe) { // this can only happen from an error serializing the key watcher.abort("Failed serializing key "+key.getKeyId(), ioe); } }
/** * @param bytes A pb serialized {@link HTableDescriptor} instance with pb magic prefix * @return An instance of {@link HTableDescriptor} made from <code>bytes</code> * @throws DeserializationException * @throws IOException * @see #toByteArray() */ public static HTableDescriptor parseFrom(final byte [] bytes) throws DeserializationException, IOException { if (!ProtobufUtil.isPBMagicPrefix(bytes)) { return (HTableDescriptor)Writables.getWritable(bytes, new HTableDescriptor()); } int pblen = ProtobufUtil.lengthOfPBMagic(); TableSchema.Builder builder = TableSchema.newBuilder(); TableSchema ts; try { ProtobufUtil.mergeFrom(builder, bytes, pblen, bytes.length - pblen); ts = builder.build(); } catch (IOException e) { throw new DeserializationException(e); } return convert(ts); }
/** * Offline parent in meta. * Used when splitting. * @param catalogTracker * @param parent * @param a Split daughter region A * @param b Split daughter region B * @throws NotAllMetaRegionsOnlineException * @throws IOException */ public static void offlineParentInMeta(CatalogTracker catalogTracker, HRegionInfo parent, final HRegionInfo a, final HRegionInfo b) throws NotAllMetaRegionsOnlineException, IOException { HRegionInfo copyOfParent = new HRegionInfo(parent); copyOfParent.setOffline(true); copyOfParent.setSplit(true); Put put = new Put(copyOfParent.getRegionName()); addRegionInfo(put, copyOfParent); put.add(HConstants.CATALOG_FAMILY, HConstants.SPLITA_QUALIFIER, Writables.getBytes(a)); put.add(HConstants.CATALOG_FAMILY, HConstants.SPLITB_QUALIFIER, Writables.getBytes(b)); putToMetaTable(catalogTracker, put); LOG.info("Offlined parent region " + parent.getRegionNameAsString() + " in META"); }
/** * Used in tests. * * Lists all of the regions currently in META. * @param conf * @param offlined True if we are to include offlined regions, false and we'll * leave out offlined regions from returned list. * @return List of all user-space regions. * @throws IOException */ public static List<HRegionInfo> listAllRegions(Configuration conf, final boolean offlined) throws IOException { final List<HRegionInfo> regions = new ArrayList<HRegionInfo>(); MetaScannerVisitor visitor = new BlockingMetaScannerVisitor(conf) { @Override public boolean processRowInternal(Result result) throws IOException { if (result == null || result.isEmpty()) { return true; } byte [] bytes = result.getValue(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER); if (bytes == null) { LOG.warn("Null REGIONINFO_QUALIFIER: " + result); return true; } HRegionInfo regionInfo = Writables.getHRegionInfo(bytes); // If region offline AND we are not to include offlined regions, return. if (regionInfo.isOffline() && !offlined) return true; regions.add(regionInfo); return true; } }; metaScan(conf, visitor); return regions; }
public boolean isTableAvailable(final byte[] tableName) throws IOException { final AtomicBoolean available = new AtomicBoolean(true); final AtomicInteger regionCount = new AtomicInteger(0); MetaScannerVisitor visitor = new MetaScannerVisitorBase() { @Override public boolean processRow(Result row) throws IOException { byte[] value = row.getValue(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER); HRegionInfo info = Writables.getHRegionInfoOrNull(value); if (info != null && !info.isSplitParent()) { if (Bytes.equals(tableName, info.getTableName())) { value = row.getValue(HConstants.CATALOG_FAMILY, HConstants.SERVER_QUALIFIER); if (value == null) { available.set(false); return false; } regionCount.incrementAndGet(); } } return true; } }; MetaScanner.metaScan(conf, this, visitor, null); return available.get() && (regionCount.get() > 0); }
/** * Inserts a new region's meta information into the passed <code>meta</code> region. Used by the * HMaster bootstrap code adding new table to ROOT table. * @param meta META HRegion to be updated * @param r HRegion to add to <code>meta</code> * @throws IOException */ public static void addRegionToMETA(HRegion meta, HRegion r) throws IOException { meta.checkResources(); // The row key is the region name byte[] row = r.getRegionName(); Integer lid = meta.obtainRowLock(row); try { final long now = EnvironmentEdgeManager.currentTimeMillis(); final List<KeyValue> edits = new ArrayList<KeyValue>(2); edits.add(new KeyValue(row, HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER, now, Writables.getBytes(r.getRegionInfo()))); // Set into the root table the version of the meta table. edits.add(new KeyValue(row, HConstants.CATALOG_FAMILY, HConstants.META_VERSION_QUALIFIER, now, Bytes.toBytes(HConstants.META_VERSION))); meta.put(HConstants.CATALOG_FAMILY, edits); } finally { meta.releaseRowLock(lid); } }
/** * Create rows in META for regions of the specified table with the specified * start keys. The first startKey should be a 0 length byte array if you * want to form a proper range of regions. * @param conf * @param htd * @param startKeys * @return list of region info for regions added to meta * @throws IOException */ public List<HRegionInfo> createMultiRegionsInMeta(final Configuration conf, final HTableDescriptor htd, byte [][] startKeys) throws IOException { HTable meta = new HTable(conf, HConstants.META_TABLE_NAME); Arrays.sort(startKeys, Bytes.BYTES_COMPARATOR); List<HRegionInfo> newRegions = new ArrayList<HRegionInfo>(startKeys.length); // add custom ones for (int i = 0; i < startKeys.length; i++) { int j = (i + 1) % startKeys.length; HRegionInfo hri = new HRegionInfo(htd.getName(), startKeys[i], startKeys[j]); Put put = new Put(hri.getRegionName()); put.add(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER, Writables.getBytes(hri)); meta.put(put); LOG.info("createMultiRegionsInMeta: inserted " + hri.toString()); newRegions.add(hri); } meta.close(); return newRegions; }
/** * Returns all rows from the .META. table for a given user table * * @throws IOException When reading the rows fails. */ public List<byte[]> getMetaTableRows(byte[] tableName) throws IOException { // TODO: Redo using MetaReader. HTable t = new HTable(new Configuration(this.conf), HConstants.META_TABLE_NAME); List<byte[]> rows = new ArrayList<byte[]>(); ResultScanner s = t.getScanner(new Scan()); for (Result result : s) { byte[] val = result.getValue(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER); if (val == null) { LOG.error("No region info for row " + Bytes.toString(result.getRow())); // TODO figure out what to do for this new hosed case. continue; } HRegionInfo info = Writables.getHRegionInfo(val); if (Bytes.compareTo(info.getTableName(), tableName) == 0) { LOG.info("getMetaTableRows: row -> " + Bytes.toStringBinary(result.getRow()) + info); rows.add(result.getRow()); } } s.close(); t.close(); return rows; }
@Test public void testGetHRegionInfo() throws IOException { assertNull(CatalogJanitor.getHRegionInfo(new Result())); List<KeyValue> kvs = new ArrayList<KeyValue>(); Result r = new Result(kvs); assertNull(CatalogJanitor.getHRegionInfo(r)); byte [] f = HConstants.CATALOG_FAMILY; // Make a key value that doesn't have the expected qualifier. kvs.add(new KeyValue(HConstants.EMPTY_BYTE_ARRAY, f, HConstants.SERVER_QUALIFIER, f)); r = new Result(kvs); assertNull(CatalogJanitor.getHRegionInfo(r)); // Make a key that does not have a regioninfo value. kvs.add(new KeyValue(HConstants.EMPTY_BYTE_ARRAY, f, HConstants.REGIONINFO_QUALIFIER, f)); HRegionInfo hri = CatalogJanitor.getHRegionInfo(new Result(kvs)); assertTrue(hri == null); // OK, give it what it expects kvs.clear(); kvs.add(new KeyValue(HConstants.EMPTY_BYTE_ARRAY, f, HConstants.REGIONINFO_QUALIFIER, Writables.getBytes(HRegionInfo.FIRST_META_REGIONINFO))); hri = CatalogJanitor.getHRegionInfo(new Result(kvs)); assertNotNull(hri); assertTrue(hri.equals(HRegionInfo.FIRST_META_REGIONINFO)); }
private Result makeResultFromHRegionInfo(HRegionInfo region, HRegionInfo splita, HRegionInfo splitb) throws IOException { List<KeyValue> kvs = new ArrayList<KeyValue>(); kvs.add(new KeyValue( region.getRegionName(), HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER, Writables.getBytes(region))); if (splita != null) { kvs.add(new KeyValue( region.getRegionName(), HConstants.CATALOG_FAMILY, HConstants.SPLITA_QUALIFIER, Writables.getBytes(splita))); } if (splitb != null) { kvs.add(new KeyValue( region.getRegionName(), HConstants.CATALOG_FAMILY, HConstants.SPLITB_QUALIFIER, Writables.getBytes(splitb))); } return new Result(kvs); }
/** * @param sn ServerName to use making startcode and server in meta * @param hri Region to serialize into HRegionInfo * @return A mocked up Result that fakes a Get on a row in the * <code>.META.</code> table. * @throws IOException */ private Result getMetaTableRowResult(final HRegionInfo hri, final ServerName sn) throws IOException { // TODO: Move to a utilities class. More than one test case can make use // of this facility. List<KeyValue> kvs = new ArrayList<KeyValue>(); kvs.add(new KeyValue(HConstants.EMPTY_BYTE_ARRAY, HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER, Writables.getBytes(hri))); kvs.add(new KeyValue(HConstants.EMPTY_BYTE_ARRAY, HConstants.CATALOG_FAMILY, HConstants.SERVER_QUALIFIER, Bytes.toBytes(sn.getHostAndPort()))); kvs.add(new KeyValue(HConstants.EMPTY_BYTE_ARRAY, HConstants.CATALOG_FAMILY, HConstants.STARTCODE_QUALIFIER, Bytes.toBytes(sn.getStartcode()))); return new Result(kvs); }
protected HRegionInfo createRegion(Configuration conf, final HTable htbl, byte[] startKey, byte[] endKey) throws IOException { HTable meta = new HTable(conf, HConstants.META_TABLE_NAME); HTableDescriptor htd = htbl.getTableDescriptor(); HRegionInfo hri = new HRegionInfo(htbl.getTableName(), startKey, endKey); LOG.info("manually adding regioninfo and hdfs data: " + hri.toString()); Path rootDir = new Path(conf.get(HConstants.HBASE_DIR)); FileSystem fs = rootDir.getFileSystem(conf); Path p = new Path(rootDir + "/" + htd.getNameAsString(), hri.getEncodedName()); fs.mkdirs(p); Path riPath = new Path(p, HRegion.REGIONINFO_FILE); FSDataOutputStream out = fs.create(riPath); hri.write(out); out.close(); // add to meta. Put put = new Put(hri.getRegionName()); put.add(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER, Writables.getBytes(hri)); meta.put(put); meta.flushCommits(); return hri; }
@Test public void testPut2() throws Exception{ byte[] row = "testAbort,,1243116656250".getBytes(); byte[] fam = "historian".getBytes(); byte[] qf1 = "creation".getBytes(); long ts = 9223372036854775807L; byte[] val = "dont-care".getBytes(); Put put = new Put(row); put.add(fam, qf1, ts, val); byte[] sb = Writables.getBytes(put); Put desPut = (Put)Writables.getWritable(sb, new Put()); assertTrue(Bytes.equals(put.getRow(), desPut.getRow())); List<KeyValue> list = null; List<KeyValue> desList = null; for(Map.Entry<byte[], List<KeyValue>> entry : put.getFamilyMap().entrySet()){ assertTrue(desPut.getFamilyMap().containsKey(entry.getKey())); list = entry.getValue(); desList = desPut.getFamilyMap().get(entry.getKey()); for(int i=0; i<list.size(); i++){ assertTrue(list.get(i).equals(desList.get(i))); } } }
@Test public void testDelete() throws Exception{ byte[] row = "row".getBytes(); byte[] fam = "fam".getBytes(); byte[] qf1 = "qf1".getBytes(); long ts = System.currentTimeMillis(); Delete delete = new Delete(row); delete.deleteColumn(fam, qf1, ts); byte[] sb = Writables.getBytes(delete); Delete desDelete = (Delete)Writables.getWritable(sb, new Delete()); assertTrue(Bytes.equals(delete.getRow(), desDelete.getRow())); List<KeyValue> list = null; List<KeyValue> desList = null; for(Map.Entry<byte[], List<KeyValue>> entry : delete.getFamilyMap().entrySet()){ assertTrue(desDelete.getFamilyMap().containsKey(entry.getKey())); list = entry.getValue(); desList = desDelete.getFamilyMap().get(entry.getKey()); for(int i=0; i<list.size(); i++){ assertTrue(list.get(i).equals(desList.get(i))); } } }
@Test public void testKeyValue2() throws Exception { final String name = "testKeyValue2"; byte[] row = name.getBytes(); byte[] fam = "fam".getBytes(); byte[] qf = "qf".getBytes(); long ts = System.currentTimeMillis(); byte[] val = "val".getBytes(); KeyValue kv = new KeyValue(row, fam, qf, ts, val); byte [] mb = Writables.getBytes(kv); KeyValue deserializedKv = (KeyValue)Writables.getWritable(mb, new KeyValue()); assertTrue(Bytes.equals(kv.getBuffer(), deserializedKv.getBuffer())); assertEquals(kv.getOffset(), deserializedKv.getOffset()); assertEquals(kv.getLength(), deserializedKv.getLength()); }
@Override public ResultScanner getScanner() throws IOException { Scan scan = new Scan(); RangeList list = new RangeList(); FilterList filters = new FilterList(); for (Range r : ranges) { list.addRange(r); if (r.getStartValue() != null) { filters.addFilter(new SingleColumnValueFilter(Bytes.toBytes(TPCHConstants.FAMILY_NAME), r .getQualifier(), r.getStartType(), r.getStartValue())); } if (r.getStopValue() != null) { filters.addFilter(new SingleColumnValueFilter(Bytes.toBytes(TPCHConstants.FAMILY_NAME), r .getQualifier(), r.getStopType(), r.getStopValue())); } } scan.setFilter(filters); scan.setAttribute(IndexConstants.SCAN_WITH_INDEX, Writables.getBytes(list)); scan.setAttribute(IndexConstants.MAX_SCAN_SCALE, Bytes.toBytes(0.3)); scan.setCacheBlocks(false); return table.getScanner(scan); }
/** * @param bytes A pb serialized {@link HTableDescriptor} instance with pb magic prefix * @return An instance of {@link HTableDescriptor} made from <code>bytes</code> * @throws DeserializationException * @throws IOException * @see #toByteArray() */ public static HTableDescriptor parseFrom(final byte [] bytes) throws DeserializationException, IOException { if (!ProtobufUtil.isPBMagicPrefix(bytes)) { return (HTableDescriptor)Writables.getWritable(bytes, new HTableDescriptor()); } int pblen = ProtobufUtil.lengthOfPBMagic(); TableSchema.Builder builder = TableSchema.newBuilder(); TableSchema ts; try { ts = builder.mergeFrom(bytes, pblen, bytes.length - pblen).build(); } catch (InvalidProtocolBufferException e) { throw new DeserializationException(e); } return convert(ts); }
/** * Inserts a new region's meta information into the passed * <code>meta</code> region. Used by the HMaster bootstrap code adding * new table to ROOT table. * * @param meta META HRegion to be updated * @param r HRegion to add to <code>meta</code> * * @throws IOException */ public static void addRegionToMETA(HRegion meta, HRegion r) throws IOException { meta.checkResources(); // The row key is the region name byte[] row = r.getRegionName(); Integer lid = meta.obtainRowLock(row); try { final long now = EnvironmentEdgeManager.currentTimeMillis(); final List<KeyValue> edits = new ArrayList<KeyValue>(2); edits.add(new KeyValue(row, HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER, now, Writables.getBytes(r.getRegionInfo()))); // Set into the root table the version of the meta table. edits.add(new KeyValue(row, HConstants.CATALOG_FAMILY, HConstants.META_VERSION_QUALIFIER, now, Bytes.toBytes(HConstants.META_VERSION))); meta.put(HConstants.CATALOG_FAMILY, edits); } finally { meta.releaseRowLock(lid); } }