@Test (timeout=180000) public void testTableCreate() throws Exception { AccessTestAction createTable = new AccessTestAction() { @Override public Object run() throws Exception { HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("testnewtable")); htd.addFamily(new HColumnDescriptor(TEST_FAMILY)); ACCESS_CONTROLLER.preCreateTable(ObserverContext.createAndPrepare(CP_ENV, null), htd, null); return null; } }; // verify that superuser can create tables verifyAllowed(createTable, SUPERUSER, USER_ADMIN, USER_GROUP_CREATE); // all others should be denied verifyDenied(createTable, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_ADMIN, USER_GROUP_READ, USER_GROUP_WRITE); }
/****************************** Region related hooks ******************************/ @Override public void postOpen(ObserverContext<RegionCoprocessorEnvironment> e) { // Read the entire labels table and populate the zk if (e.getEnvironment().getRegion().getRegionInfo().getTable().equals(LABELS_TABLE_NAME)) { this.labelsRegion = true; synchronized (this) { this.accessControllerAvailable = CoprocessorHost.getLoadedCoprocessors() .contains(AccessController.class.getName()); } // Defer the init of VisibilityLabelService on labels region until it is in recovering state. if (!e.getEnvironment().getRegion().isRecovering()) { initVisibilityLabelService(e.getEnvironment()); } } else { checkAuths = e.getEnvironment().getConfiguration() .getBoolean(VisibilityConstants.CHECK_AUTHS_FOR_MUTATION, false); initVisibilityLabelService(e.getEnvironment()); } }
@Override public DeleteTracker postInstantiateDeleteTracker( ObserverContext<RegionCoprocessorEnvironment> ctx, DeleteTracker delTracker) throws IOException { // Nothing to do if we are not filtering by visibility if (!authorizationEnabled) { return delTracker; } Region region = ctx.getEnvironment().getRegion(); TableName table = region.getRegionInfo().getTable(); if (table.isSystemTable()) { return delTracker; } // We are creating a new type of delete tracker here which is able to track // the timestamps and also the // visibility tags per cell. The covering cells are determined not only // based on the delete type and ts // but also on the visibility expression matching. return new VisibilityScanDeleteTracker(); }
@Test (timeout=180000) public void testPrepareAndCleanBulkLoad() throws Exception { AccessTestAction prepareBulkLoadAction = new AccessTestAction() { @Override public Object run() throws Exception { ACCESS_CONTROLLER.prePrepareBulkLoad(ObserverContext.createAndPrepare(RCP_ENV, null), null); return null; } }; AccessTestAction cleanupBulkLoadAction = new AccessTestAction() { @Override public Object run() throws Exception { ACCESS_CONTROLLER.preCleanupBulkLoad(ObserverContext.createAndPrepare(RCP_ENV, null), null); return null; } }; verifyAnyCreate(prepareBulkLoadAction); verifyAnyCreate(cleanupBulkLoadAction); }
@Override public void preTruncateTable(ObserverContext<MasterCoprocessorEnvironment> c, final TableName tableName) throws IOException { requirePermission("truncateTable", tableName, null, null, Action.ADMIN, Action.CREATE); final Configuration conf = c.getEnvironment().getConfiguration(); User.runAsLoginUser(new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { List<UserPermission> acls = AccessControlLists.getUserTablePermissions(conf, tableName); if (acls != null) { tableAcls.put(tableName, acls); } return null; } }); }
@Override public void postTruncateTable(ObserverContext<MasterCoprocessorEnvironment> ctx, final TableName tableName) throws IOException { final Configuration conf = ctx.getEnvironment().getConfiguration(); User.runAsLoginUser(new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { List<UserPermission> perms = tableAcls.get(tableName); if (perms != null) { for (UserPermission perm : perms) { AccessControlLists.addUserPermission(conf, perm); } } tableAcls.remove(tableName); return null; } }); }
@Test public void testModifyNamespace() throws Exception { AccessTestAction modifyNamespace = new AccessTestAction() { @Override public Object run() throws Exception { ACCESS_CONTROLLER.preModifyNamespace(ObserverContext.createAndPrepare(CP_ENV, null), NamespaceDescriptor.create(TEST_NAMESPACE).addConfiguration("abc", "156").build()); return null; } }; // modifyNamespace: superuser | global(A) | NS(A) verifyAllowed(modifyNamespace, SUPERUSER, USER_GLOBAL_ADMIN, USER_GROUP_ADMIN); verifyDenied(modifyNamespace, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ, USER_GLOBAL_EXEC, USER_NS_ADMIN, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE); }
@Test (timeout=180000) public void testAssign() throws Exception { List<HRegionLocation> regions; try (RegionLocator locator = systemUserConnection.getRegionLocator(TEST_TABLE)) { regions = locator.getAllRegionLocations(); } HRegionLocation location = regions.get(0); final HRegionInfo hri = location.getRegionInfo(); AccessTestAction action = new AccessTestAction() { @Override public Object run() throws Exception { ACCESS_CONTROLLER.preAssign(ObserverContext.createAndPrepare(CP_ENV, null), hri); return null; } }; verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE); }
private void slowdownCode(final ObserverContext<RegionCoprocessorEnvironment> e) { if (e.getEnvironment().getRegion().getRegionInfo().getReplicaId() == 0) { CountDownLatch latch = getCdl().get(); try { if (sleepTime.get() > 0) { LOG.info("Sleeping for " + sleepTime.get() + " ms"); Thread.sleep(sleepTime.get()); } else if (latch.getCount() > 0) { LOG.info("Waiting for the counterCountDownLatch"); latch.await(2, TimeUnit.MINUTES); // To help the tests to finish. if (latch.getCount() > 0) { throw new RuntimeException("Can't wait more"); } } } catch (InterruptedException e1) { LOG.error(e1); } } else { LOG.info("We're not the primary replicas."); } }
@Test (timeout=180000) public void testMergeRegions() throws Exception { final TableName tname = TableName.valueOf("testMergeRegions"); createTestTable(tname); try { final List<HRegion> regions = TEST_UTIL.getHBaseCluster().findRegionsForTable(tname); assertTrue("not enough regions: " + regions.size(), regions.size() >= 2); AccessTestAction action = new AccessTestAction() { @Override public Object run() throws Exception { ACCESS_CONTROLLER.preMerge(ObserverContext.createAndPrepare(RSCP_ENV, null), regions.get(0), regions.get(1)); return null; } }; verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE); } finally { deleteTable(TEST_UTIL, tname); } }
@Test (timeout=180000) public void testMove() throws Exception { List<HRegionLocation> regions; try (RegionLocator locator = systemUserConnection.getRegionLocator(TEST_TABLE)) { regions = locator.getAllRegionLocations(); } HRegionLocation location = regions.get(0); final HRegionInfo hri = location.getRegionInfo(); final ServerName server = location.getServerName(); AccessTestAction action = new AccessTestAction() { @Override public Object run() throws Exception { ACCESS_CONTROLLER.preMove(ObserverContext.createAndPrepare(CP_ENV, null), hri, server, server); return null; } }; verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE); }
@Test (timeout=180000) public void testReplicateLogEntries() throws Exception { AccessTestAction replicateLogEntriesAction = new AccessTestAction() { @Override public Object run() throws Exception { ACCESS_CONTROLLER.preReplicateLogEntries(ObserverContext.createAndPrepare(RSCP_ENV, null), null, null); ACCESS_CONTROLLER.postReplicateLogEntries(ObserverContext.createAndPrepare(RSCP_ENV, null), null, null); return null; } }; verifyAllowed(replicateLogEntriesAction, SUPERUSER, USER_ADMIN, USER_GROUP_WRITE); verifyDenied(replicateLogEntriesAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER, USER_GROUP_READ, USER_GROUP_ADMIN, USER_GROUP_CREATE); }
@Override public InternalScanner preFlushScannerOpen( final ObserverContext<RegionCoprocessorEnvironment> c, Store store, KeyValueScanner memstoreScanner, InternalScanner s) throws IOException { Long newTtl = ttls.get(store.getTableName()); if (newTtl != null) { System.out.println("PreFlush:" + newTtl); } Integer newVersions = versions.get(store.getTableName()); ScanInfo oldSI = store.getScanInfo(); HColumnDescriptor family = store.getFamily(); ScanInfo scanInfo = new ScanInfo(TEST_UTIL.getConfiguration(), family.getName(), family.getMinVersions(), newVersions == null ? family.getMaxVersions() : newVersions, newTtl == null ? oldSI.getTtl() : newTtl, family.getKeepDeletedCells(), oldSI.getTimeToPurgeDeletes(), oldSI.getComparator()); Scan scan = new Scan(); scan.setMaxVersions(newVersions == null ? oldSI.getMaxVersions() : newVersions); return new StoreScanner(store, scanInfo, scan, Collections.singletonList(memstoreScanner), ScanType.COMPACT_RETAIN_DELETES, store.getSmallestReadPoint(), HConstants.OLDEST_TIMESTAMP); }
@Test (timeout=180000) public void testAddColumn() throws Exception { final HColumnDescriptor hcd = new HColumnDescriptor("fam_new"); AccessTestAction action = new AccessTestAction() { @Override public Object run() throws Exception { ACCESS_CONTROLLER.preAddColumn(ObserverContext.createAndPrepare(CP_ENV, null), TEST_TABLE, hcd); return null; } }; verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_CREATE, USER_OWNER, USER_GROUP_CREATE, USER_GROUP_ADMIN); verifyDenied(action, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE); }
@Override public Result preAppendAfterRowLock(final ObserverContext<RegionCoprocessorEnvironment> c, final Append append) throws IOException { if (append.getAttribute(CHECK_COVERING_PERM) != null) { // We had failure with table, cf and q perm checks and now giving a chance for cell // perm check TableName table = c.getEnvironment().getRegion().getRegionInfo().getTable(); AuthResult authResult = null; if (checkCoveringPermission(OpType.APPEND, c.getEnvironment(), append.getRow(), append.getFamilyCellMap(), HConstants.LATEST_TIMESTAMP, Action.WRITE)) { authResult = AuthResult.allow(OpType.APPEND.toString(), "Covering cell set", getActiveUser(), Action.WRITE, table, append.getFamilyCellMap()); } else { authResult = AuthResult.deny(OpType.APPEND.toString(), "Covering cell set", getActiveUser(), Action.WRITE, table, append.getFamilyCellMap()); } logResult(authResult); if (authorizationEnabled && !authResult.isAllowed()) { throw new AccessDeniedException("Insufficient permissions " + authResult.toContextString()); } } return null; }
@Test (timeout=180000) public void testRegionOffline() throws Exception { List<HRegionLocation> regions; try (RegionLocator locator = systemUserConnection.getRegionLocator(TEST_TABLE)) { regions = locator.getAllRegionLocations(); } HRegionLocation location = regions.get(0); final HRegionInfo hri = location.getRegionInfo(); AccessTestAction action = new AccessTestAction() { @Override public Object run() throws Exception { ACCESS_CONTROLLER.preRegionOffline(ObserverContext.createAndPrepare(CP_ENV, null), hri); return null; } }; verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_GROUP_ADMIN); verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE); }
/** * @param info * @param logKey * @param logEdit * @throws IOException */ public void postWALRestore(final HRegionInfo info, final WALKey logKey, final WALEdit logEdit) throws IOException { execOperation(coprocessors.isEmpty() ? null : new RegionOperation() { @Override public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException { // Once we don't need to support the legacy call, replace RegionOperation with a version // that's ObserverContext<RegionEnvironment> and avoid this cast. final RegionEnvironment env = (RegionEnvironment)ctx.getEnvironment(); if (env.useLegacyPost) { if (logKey instanceof HLogKey) { oserver.postWALRestore(ctx, info, (HLogKey)logKey, logEdit); } else { legacyWarning(oserver.getClass(), "There are wal keys present that are not HLogKey."); } } else { oserver.postWALRestore(ctx, info, logKey, logEdit); } } }); }
@Test public void testGetNamespaceDescriptor() throws Exception { AccessTestAction getNamespaceAction = new AccessTestAction() { @Override public Object run() throws Exception { ACCESS_CONTROLLER.preGetNamespaceDescriptor(ObserverContext.createAndPrepare(CP_ENV, null), TEST_NAMESPACE); return null; } }; // getNamespaceDescriptor : superuser | global(A) | NS(A) verifyAllowed(getNamespaceAction, SUPERUSER, USER_GLOBAL_ADMIN, USER_NS_ADMIN, USER_GROUP_ADMIN); verifyDenied(getNamespaceAction, USER_GLOBAL_CREATE, USER_GLOBAL_WRITE, USER_GLOBAL_READ, USER_GLOBAL_EXEC, USER_NS_CREATE, USER_NS_WRITE, USER_NS_READ, USER_NS_EXEC, USER_TABLE_CREATE, USER_TABLE_WRITE, USER_GROUP_READ, USER_GROUP_WRITE, USER_GROUP_CREATE); }
@Override public void preSplitAfterPONR(ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException { RegionCoprocessorEnvironment environment = ctx.getEnvironment(); HRegionServer rs = (HRegionServer) environment.getRegionServerServices(); st.stepsAfterPONR(rs, rs, daughterRegions, null); }
public void postRollBackMerge(final HRegion regionA, final HRegion regionB) throws IOException { execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { @Override public void call(RegionServerObserver oserver, ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException { oserver.postRollBackMerge(ctx, regionA, regionB); } }); }
/** * @param familyPaths pairs of { CF, file path } submitted for bulk load * @param hasLoaded whether load was successful or not * @return the possibly modified value of hasLoaded * @throws IOException */ public boolean postBulkLoadHFile(final List<Pair<byte[], String>> familyPaths, boolean hasLoaded) throws IOException { return execOperationWithResult(hasLoaded, coprocessors.isEmpty() ? null : new RegionOperationWithResult<Boolean>() { @Override public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException { setResult(oserver.postBulkLoadHFile(ctx, familyPaths, getResult())); } }); }
@Override public void preDeleteColumn(ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName, byte[] c) throws IOException { if (!authorizationEnabled) { return; } if (LABELS_TABLE_NAME.equals(tableName)) { throw new ConstraintException("Cannot alter " + LABELS_TABLE_NAME); } }
@Test (timeout=180000) public void testCompact() throws Exception { AccessTestAction action = new AccessTestAction() { @Override public Object run() throws Exception { ACCESS_CONTROLLER.preCompact(ObserverContext.createAndPrepare(RCP_ENV, null), null, null, ScanType.COMPACT_RETAIN_DELETES); return null; } }; verifyAllowed(action, SUPERUSER, USER_ADMIN, USER_OWNER, USER_CREATE, USER_GROUP_CREATE, USER_GROUP_ADMIN); verifyDenied(action, USER_RW, USER_RO, USER_NONE, USER_GROUP_READ, USER_GROUP_WRITE); }
@Override public RegionScanner preScannerOpen(ObserverContext<RegionCoprocessorEnvironment> e, Scan scan, RegionScanner s) throws IOException { if (!initialized) { throw new VisibilityControllerNotReadyException("VisibilityController not yet initialized!"); } // Nothing to do if authorization is not enabled if (!authorizationEnabled) { return s; } Region region = e.getEnvironment().getRegion(); Authorizations authorizations = null; try { authorizations = scan.getAuthorizations(); } catch (DeserializationException de) { throw new IOException(de); } if (authorizations == null) { // No Authorizations present for this scan/Get! // In case of system tables other than "labels" just scan with out visibility check and // filtering. Checking visibility labels for META and NAMESPACE table is not needed. TableName table = region.getRegionInfo().getTable(); if (table.isSystemTable() && !table.equals(LABELS_TABLE_NAME)) { return s; } } Filter visibilityLabelFilter = VisibilityUtils.createVisibilityLabelFilter(region, authorizations); if (visibilityLabelFilter != null) { Filter filter = scan.getFilter(); if (filter != null) { scan.setFilter(new FilterList(filter, visibilityLabelFilter)); } else { scan.setFilter(visibilityLabelFilter); } } return s; }
@Override public void postWALWrite(ObserverContext<? extends WALCoprocessorEnvironment> ctx, HRegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException { // only keep primary region's edits if (logKey.getTablename().equals(tableName) && info.getReplicaId() == 0) { entries.add(new Entry(logKey, logEdit)); } }
@Override public boolean preScannerNext(final ObserverContext<RegionCoprocessorEnvironment> c, final InternalScanner s, final List<Result> result, final int limit, final boolean hasNext) throws IOException { requireScannerOwner(s); return hasNext; }
/** * Called prior to selecting the {@link StoreFile}s for compaction from the list of currently * available candidates. * @param store The store where compaction is being requested * @param candidates The currently available store files * @param request custom compaction request * @return If {@code true}, skip the normal selection process and use the current list * @throws IOException */ public boolean preCompactSelection(final Store store, final List<StoreFile> candidates, final CompactionRequest request) throws IOException { return execOperation(coprocessors.isEmpty() ? null : new RegionOperation() { @Override public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException { oserver.preCompactSelection(ctx, store, candidates, request); } }); }
@Override public RegionScanner preScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> e, final Scan scan, final RegionScanner s) throws IOException { if (countOfOpen.incrementAndGet() == 2) { //slowdown openScanner randomly slowdownCode(e); } return s; }
/** * @param row row to check * @param family column family * @param qualifier column qualifier * @param compareOp the comparison operation * @param comparator the comparator * @param put data to put if check succeeds * @return true or false to return to client if default processing should * be bypassed, or null otherwise * @throws IOException e */ public Boolean preCheckAndPutAfterRowLock(final byte[] row, final byte[] family, final byte[] qualifier, final CompareOp compareOp, final ByteArrayComparable comparator, final Put put) throws IOException { return execOperationWithResult(true, false, coprocessors.isEmpty() ? null : new RegionOperationWithResult<Boolean>() { @Override public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException { setResult(oserver.preCheckAndPutAfterRowLock(ctx, row, family, qualifier, compareOp, comparator, put, getResult())); } }); }
@Override public boolean preScannerNext(final ObserverContext<RegionCoprocessorEnvironment> e, final InternalScanner s, final List<Result> results, final int limit, final boolean hasMore) throws IOException { //this will slow down a certain next operation if the conditions are met. The slowness //will allow the call to go to a replica countOfNext.incrementAndGet(); if (countOfNext.get() == 0 || countOfNext.get() == 4) { slowdownCode(e); } return true; }
@Override public Result preIncrement(ObserverContext<RegionCoprocessorEnvironment> e, Increment increment) throws IOException { // If authorization is not enabled, we don't care about reserved tags if (!authorizationEnabled) { return null; } for (CellScanner cellScanner = increment.cellScanner(); cellScanner.advance();) { if (!checkForReservedVisibilityTagPresence(cellScanner.current())) { throw new FailedSanityCheckException("Increment contains cell with reserved type tag"); } } return null; }
public boolean preMerge(final HRegion regionA, final HRegion regionB) throws IOException { return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { @Override public void call(RegionServerObserver oserver, ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException { oserver.preMerge(ctx, regionA, regionB); } }); }
@Override public void postAddColumnHandler(ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName, HColumnDescriptor column) throws IOException { Threads.sleep(6000); try { ctx.getEnvironment().getMasterServices().checkTableModifiable(tableName); } catch(TableNotDisabledException expected) { //pass return; } catch(IOException ex) { } fail("was expecting the table to be enabled"); }
/** * Invoked before a region is closed * @param abortRequested true if the server is aborting */ public void preClose(final boolean abortRequested) throws IOException { execOperation(false, new RegionOperation() { @Override public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException { oserver.preClose(ctx, abortRequested); } }); }
public void postBatchMutateIndispensably( final MiniBatchOperationInProgress<Mutation> miniBatchOp, final boolean success) throws IOException { execOperation(coprocessors.isEmpty() ? null : new RegionOperation() { @Override public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException { oserver.postBatchMutateIndispensably(ctx, miniBatchOp, success); } }); }
/** * @param row row to check * @param family column family * @param qualifier column qualifier * @param compareOp the comparison operation * @param comparator the comparator * @param delete delete to commit if check succeeds * @throws IOException e */ public boolean postCheckAndDelete(final byte [] row, final byte [] family, final byte [] qualifier, final CompareOp compareOp, final ByteArrayComparable comparator, final Delete delete, boolean result) throws IOException { return execOperationWithResult(result, coprocessors.isEmpty() ? null : new RegionOperationWithResult<Boolean>() { @Override public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException { setResult(oserver.postCheckAndDelete(ctx, row, family, qualifier, compareOp, comparator, delete, getResult())); } }); }
/** * @param delete The Delete object * @param edit The WALEdit object. * @param durability The durability used * @return true if default processing should be bypassed * @exception IOException Exception */ public boolean preDelete(final Delete delete, final WALEdit edit, final Durability durability) throws IOException { return execOperation(coprocessors.isEmpty() ? null : new RegionOperation() { @Override public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException { oserver.preDelete(ctx, delete, edit, durability); } }); }
@Override public void postDeleteColumn(ObserverContext<MasterCoprocessorEnvironment> c, final TableName tableName, final byte[] col) throws IOException { final Configuration conf = c.getEnvironment().getConfiguration(); User.runAsLoginUser(new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { AccessControlLists.removeTablePermissions(conf, tableName, col); return null; } }); }
/** * Called prior to rewriting the store files selected for compaction * @param store the store being compacted * @param scanner the scanner used to read store data during compaction * @param scanType type of Scan * @param request the compaction that will be executed * @throws IOException */ public InternalScanner preCompact(final Store store, final InternalScanner scanner, final ScanType scanType, final CompactionRequest request) throws IOException { return execOperationWithResult(false, scanner, coprocessors.isEmpty() ? null : new RegionOperationWithResult<InternalScanner>() { @Override public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException { setResult(oserver.preCompact(ctx, store, getResult(), scanType, request)); } }); }
@Override public void preDisableTable(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName) throws IOException { if (Bytes.equals(tableName.getName(), AccessControlLists.ACL_GLOBAL_NAME)) { // We have to unconditionally disallow disable of the ACL table when we are installed, // even if not enforcing authorizations. We are still allowing grants and revocations, // checking permissions and logging audit messages, etc. If the ACL table is not // available we will fail random actions all over the place. throw new AccessDeniedException("Not allowed to disable " + AccessControlLists.ACL_TABLE_NAME + " table with AccessController installed"); } requirePermission("disableTable", tableName, null, null, Action.ADMIN, Action.CREATE); }