@Override protected HashCode hash(HashFunction hashFunction, Key k) { Hasher hasher = hashFunction.newHasher(); if (row) { putByteSquence(k.getRowData(), hasher); } if (family) { putByteSquence(k.getColumnFamilyData(), hasher); } if (qualifier) { putByteSquence(k.getColumnQualifierData(), hasher); } if (visibility) { putByteSquence(k.getColumnVisibilityData(), hasher); } return hasher.hash(); }
public static Entry<Key, Value> checkColumn( Environment env, IteratorSetting iterConf, Bytes row, Column col) { Span span = Span.exact(row, col); Scanner scanner; try { // TODO reuse or share scanner scanner = env.getConnector().createScanner(env.getTable(), env.getAuthorizations()); } catch (TableNotFoundException e) { // TODO proper exception handling throw new RuntimeException(e); } scanner.setRange(SpanUtil.toRange(span)); scanner.addScanIterator(iterConf); Iterator<Entry<Key, Value>> iter = scanner.iterator(); if (iter.hasNext()) { Entry<Key, Value> entry = iter.next(); Key k = entry.getKey(); Bytes r = Bytes.of(k.getRowData().toArray()); Bytes cf = Bytes.of(k.getColumnFamilyData().toArray()); Bytes cq = Bytes.of(k.getColumnQualifierData().toArray()); Bytes cv = Bytes.of(k.getColumnVisibilityData().toArray()); if (r.equals(row) && cf.equals(col.getFamily()) && cq.equals(col.getQualifier()) && cv.equals(col.getVisibility())) { return entry; } else { throw new RuntimeException("unexpected key " + k + " " + row + " " + col); } } return null; }
@Override public void visit(State state, Properties props) throws Exception { boolean userExists = SecurityHelper.getTabUserExists(state); Connector conn; try { conn = state .getInstance() .getConnector( SecurityHelper.getTabUserName(state), SecurityHelper.getTabUserPass(state)); } catch (AccumuloSecurityException ae) { if (ae.getErrorCode().equals(SecurityErrorCode.BAD_CREDENTIALS)) { if (userExists) throw new AccumuloException( "User didn't exist when they should (or worse- password mismatch)", ae); else return; } throw new AccumuloException("Unexpected exception!", ae); } String action = props.getProperty("action", "_random"); TablePermission tp; if ("_random".equalsIgnoreCase(action)) { Random r = new Random(); tp = TablePermission.values()[r.nextInt(TablePermission.values().length)]; } else { tp = TablePermission.valueOf(action); } boolean tableExists = SecurityHelper.getTableExists(state); boolean hasPerm = SecurityHelper.getTabPerm(state, SecurityHelper.getTabUserName(state), tp); String tableName = state.getString("secTableName"); switch (tp) { case READ: Authorizations auths = SecurityHelper.getUserAuths(state, SecurityHelper.getTabUserName(state)); boolean canRead = SecurityHelper.getTabPerm( state, SecurityHelper.getTabUserName(state), TablePermission.READ); try { Scanner scan = conn.createScanner( tableName, conn.securityOperations() .getUserAuthorizations(SecurityHelper.getTabUserName(state))); int seen = 0; Iterator<Entry<Key, Value>> iter = scan.iterator(); while (iter.hasNext()) { Entry<Key, Value> entry = iter.next(); Key k = entry.getKey(); seen++; if (!auths.contains(k.getColumnVisibilityData())) throw new AccumuloException( "Got data I should not be capable of seeing: " + k + " table " + tableName); } if (!canRead) throw new AccumuloException( "Was able to read when I shouldn't have had the perm with connection user " + conn.whoami() + " table " + tableName); for (Entry<String, Integer> entry : SecurityHelper.getAuthsMap(state).entrySet()) { if (auths.contains(entry.getKey().getBytes())) seen = seen - entry.getValue(); } if (seen != 0) throw new AccumuloException("Got mismatched amounts of data"); } catch (TableNotFoundException tnfe) { if (tableExists) throw new AccumuloException( "Accumulo and test suite out of sync: table " + tableName, tnfe); return; } catch (AccumuloSecurityException ae) { if (ae.getErrorCode().equals(SecurityErrorCode.PERMISSION_DENIED)) { if (canRead) throw new AccumuloException( "Table read permission out of sync with Accumulo: table " + tableName, ae); else return; } throw new AccumuloException("Unexpected exception!", ae); } catch (RuntimeException re) { if (re.getCause() instanceof AccumuloSecurityException && ((AccumuloSecurityException) re.getCause()) .getErrorCode() .equals(SecurityErrorCode.PERMISSION_DENIED)) { if (canRead) throw new AccumuloException( "Table read permission out of sync with Accumulo: table " + tableName, re.getCause()); else return; } throw new AccumuloException("Unexpected exception!", re); } break; case WRITE: String key = SecurityHelper.getLastKey(state) + "1"; Mutation m = new Mutation(new Text(key)); for (String s : SecurityHelper.getAuthsArray()) { m.put(new Text(), new Text(), new ColumnVisibility(s), new Value("value".getBytes())); } BatchWriter writer; try { writer = conn.createBatchWriter(tableName, 9000l, 0l, 1); } catch (TableNotFoundException tnfe) { if (tableExists) throw new AccumuloException("Table didn't exist when it should have: " + tableName); return; } boolean works = true; try { writer.addMutation(m); } catch (MutationsRejectedException mre) { throw new AccumuloException("Mutation exception!", mre); } if (works) for (String s : SecurityHelper.getAuthsArray()) SecurityHelper.increaseAuthMap(state, s, 1); break; case BULK_IMPORT: key = SecurityHelper.getLastKey(state) + "1"; SortedSet<Key> keys = new TreeSet<Key>(); for (String s : SecurityHelper.getAuthsArray()) { Key k = new Key(key, "", "", s); keys.add(k); } Path dir = new Path("/tmp", "bulk_" + UUID.randomUUID().toString()); Path fail = new Path(dir.toString() + "_fail"); FileSystem fs = SecurityHelper.getFs(state); FileSKVWriter f = FileOperations.getInstance() .openWriter( dir + "/securityBulk." + RFile.EXTENSION, fs, fs.getConf(), AccumuloConfiguration.getDefaultConfiguration()); f.startDefaultLocalityGroup(); fs.mkdirs(fail); for (Key k : keys) f.append(k, new Value("Value".getBytes())); f.close(); try { conn.tableOperations().importDirectory(tableName, dir.toString(), fail.toString(), true); } catch (TableNotFoundException tnfe) { if (tableExists) throw new AccumuloException("Table didn't exist when it should have: " + tableName); return; } catch (AccumuloSecurityException ae) { if (ae.getErrorCode().equals(SecurityErrorCode.PERMISSION_DENIED)) { if (hasPerm) throw new AccumuloException( "Bulk Import failed when it should have worked: " + tableName); return; } throw new AccumuloException("Unexpected exception!", ae); } for (String s : SecurityHelper.getAuthsArray()) SecurityHelper.increaseAuthMap(state, s, 1); fs.delete(dir, true); fs.delete(fail, true); if (!hasPerm) throw new AccumuloException( "Bulk Import succeeded when it should have failed: " + dir + " table " + tableName); break; case ALTER_TABLE: AlterTable.renameTable(conn, state, tableName, tableName + "plus", hasPerm, tableExists); break; case GRANT: props.setProperty("task", "grant"); props.setProperty("perm", "random"); props.setProperty("source", "table"); props.setProperty("target", "system"); AlterTablePerm.alter(state, props); break; case DROP_TABLE: props.setProperty("source", "table"); DropTable.dropTable(state, props); break; } }
public static Column convert(Key k) { Bytes f = ByteUtil.toBytes(k.getColumnFamilyData()); Bytes q = ByteUtil.toBytes(k.getColumnQualifierData()); Bytes v = ByteUtil.toBytes(k.getColumnVisibilityData()); return new Column(f, q, v); }
/** * Create a copy of key with all fields except the ones specified cleared. * * @param key The key to copy * @param pk What fields to retain from the key * @return A new Key object pointing to new copies of fields specified by pk; other fields are * empty/default. */ public static Key keyCopy(Key key, PartialKey pk) { if (key == null || pk == null) return null; switch (pk) { case ROW: return new Key( key.getRowData().getBackingArray(), EMPTY_BYTES, EMPTY_BYTES, EMPTY_BYTES, Long.MAX_VALUE, false, true); case ROW_COLFAM: return new Key( key.getRowData().getBackingArray(), key.getColumnFamilyData().getBackingArray(), EMPTY_BYTES, EMPTY_BYTES, Long.MAX_VALUE, false, true); case ROW_COLFAM_COLQUAL: return new Key( key.getRowData().getBackingArray(), key.getColumnFamilyData().getBackingArray(), key.getColumnQualifierData().getBackingArray(), EMPTY_BYTES, Long.MAX_VALUE, false, true); case ROW_COLFAM_COLQUAL_COLVIS: return new Key( key.getRowData().getBackingArray(), key.getColumnFamilyData().getBackingArray(), key.getColumnQualifierData().getBackingArray(), key.getColumnVisibilityData().getBackingArray(), Long.MAX_VALUE, false, true); case ROW_COLFAM_COLQUAL_COLVIS_TIME: return new Key( key.getRowData().getBackingArray(), key.getColumnFamilyData().getBackingArray(), key.getColumnQualifierData().getBackingArray(), key.getColumnVisibilityData().getBackingArray(), key.getTimestamp(), false, true); case ROW_COLFAM_COLQUAL_COLVIS_TIME_DEL: return new Key( key.getRowData().getBackingArray(), key.getColumnFamilyData().getBackingArray(), key.getColumnQualifierData().getBackingArray(), key.getColumnVisibilityData().getBackingArray(), key.getTimestamp(), key.isDeleted(), true); default: throw new AssertionError("unknown pk: " + pk); } }