HBASE-7331. Add access control for region open and close, and stopping the regionserver (Vandana Ayyalasomayajula)

git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1422094 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andrew Kyle Purtell 2012-12-14 21:12:36 +00:00
parent 5dbff1427d
commit 1ef0621695
10 changed files with 364 additions and 44 deletions

View File

@ -62,14 +62,14 @@ public abstract class BaseRegionObserver implements RegionObserver {
public void stop(CoprocessorEnvironment e) throws IOException { }
@Override
public void preOpen(ObserverContext<RegionCoprocessorEnvironment> e) { }
public void preOpen(ObserverContext<RegionCoprocessorEnvironment> e) throws IOException { }
@Override
public void postOpen(ObserverContext<RegionCoprocessorEnvironment> e) { }
@Override
public void preClose(ObserverContext<RegionCoprocessorEnvironment> e,
boolean abortRequested) { }
public void preClose(ObserverContext<RegionCoprocessorEnvironment> c, boolean abortRequested)
throws IOException { }
@Override
public void postClose(ObserverContext<RegionCoprocessorEnvironment> e,

View File

@ -64,6 +64,8 @@ import java.util.jar.JarFile;
public abstract class CoprocessorHost<E extends CoprocessorEnvironment> {
public static final String REGION_COPROCESSOR_CONF_KEY =
"hbase.coprocessor.region.classes";
public static final String REGIONSERVER_COPROCESSOR_CONF_KEY =
"hbase.coprocessor.regionserver.classes";
public static final String USER_REGION_COPROCESSOR_CONF_KEY =
"hbase.coprocessor.user.region.classes";
public static final String MASTER_COPROCESSOR_CONF_KEY =

View File

@ -58,8 +58,9 @@ public interface RegionObserver extends Coprocessor {
/**
* Called before the region is reported as open to the master.
* @param c the environment provided by the region server
* @throws IOException if an error occurred on the coprocessor
*/
void preOpen(final ObserverContext<RegionCoprocessorEnvironment> c);
void preOpen(final ObserverContext<RegionCoprocessorEnvironment> c) throws IOException;
/**
* Called after the region is reported as open to the master.
@ -261,9 +262,10 @@ public interface RegionObserver extends Coprocessor {
* Called before the region is reported as closed to the master.
* @param c the environment provided by the region server
* @param abortRequested true if the region server is aborting
* @throws IOException
*/
void preClose(final ObserverContext<RegionCoprocessorEnvironment> c,
boolean abortRequested);
boolean abortRequested) throws IOException;
/**
* Called after the region is reported as closed to the master.

View File

@ -0,0 +1,31 @@
/**
*
* 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.
*/
package org.apache.hadoop.hbase.coprocessor;
import org.apache.hadoop.hbase.CoprocessorEnvironment;
import org.apache.hadoop.hbase.regionserver.RegionServerServices;
public interface RegionServerCoprocessorEnvironment extends CoprocessorEnvironment {
/**
* Gets the region server services.
*
* @return the region server services
*/
RegionServerServices getRegionServerServices();
}

View File

@ -0,0 +1,35 @@
/**
*
* 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.
*/
package org.apache.hadoop.hbase.coprocessor;
import java.io.IOException;
import org.apache.hadoop.hbase.Coprocessor;
public interface RegionServerObserver extends Coprocessor {
/**
* Called before stopping region server.
* @param env An instance of RegionServerCoprocessorEnvironment
* @throws IOException Signals that an I/O exception has occurred.
*/
void preStopRegionServer(
final ObserverContext<RegionServerCoprocessorEnvironment> env)
throws IOException;
}

View File

@ -433,6 +433,8 @@ public class HRegionServer implements ClientProtocol,
*/
private final QosFunction qosFunction;
private RegionServerCoprocessorHost rsHost;
/**
* Starts a HRegionServer at the default location
*
@ -517,6 +519,7 @@ public class HRegionServer implements ClientProtocol,
"hbase.regionserver.kerberos.principal", this.isa.getHostName());
regionServerAccounting = new RegionServerAccounting();
cacheConfig = new CacheConfig(conf);
this.rsHost = new RegionServerCoprocessorHost(this, this.conf);
}
/**
@ -1574,10 +1577,15 @@ public class HRegionServer implements ClientProtocol,
@Override
public void stop(final String msg) {
try {
this.rsHost.preStop(msg);
this.stopped = true;
LOG.info("STOPPED: " + msg);
// Wakes run() if it is sleeping
sleeper.skipSleepCycle();
} catch (IOException exp) {
LOG.warn("The region server did not stop", exp);
}
}
public void waitForServerOnline(){
@ -2098,6 +2106,10 @@ public class HRegionServer implements ClientProtocol,
return this.zooKeeper;
}
public RegionServerCoprocessorHost getCoprocessorHost(){
return this.rsHost;
}
public ConcurrentSkipListMap<byte[], Boolean> getRegionsInTransitionInRS() {
return this.regionsInTransitionInRS;
@ -2398,6 +2410,17 @@ public class HRegionServer implements ClientProtocol,
*/
protected boolean closeRegion(HRegionInfo region, final boolean abort,
final boolean zk, final int versionOfClosingNode, ServerName sn) {
//Check for permissions to close.
HRegion actualRegion = this.getFromOnlineRegions(region.getEncodedName());
if ((actualRegion != null) && (actualRegion.getCoprocessorHost() != null)) {
try {
actualRegion.getCoprocessorHost().preClose(false);
} catch (IOException exp) {
LOG.warn("Unable to close region", exp);
return false;
}
}
if (this.regionsInTransitionInRS.containsKey(region.getEncodedNameAsBytes())) {
LOG.warn("Received close for region we are already opening or closing; " +
region.getEncodedName());
@ -3380,6 +3403,10 @@ public class HRegionServer implements ClientProtocol,
checkIfRegionInTransition(region.getEncodedNameAsBytes(), OPEN);
HRegion onlineRegion = getFromOnlineRegions(region.getEncodedName());
if (null != onlineRegion) {
//Check if the region can actually be opened.
if( onlineRegion.getCoprocessorHost() != null){
onlineRegion.getCoprocessorHost().preOpen();
}
// See HBASE-5094. Cross check with META if still this RS is owning
// the region.
Pair<HRegionInfo, ServerName> p = MetaReader.getRegion(
@ -3459,6 +3486,10 @@ public class HRegionServer implements ClientProtocol,
String encodedRegionName =
ProtobufUtil.getRegionEncodedName(request.getRegion());
byte[] encodedName = Bytes.toBytes(encodedRegionName);
HRegion region = getRegionByEncodedName(encodedRegionName);
if(region.getCoprocessorHost() != null){
region.getCoprocessorHost().preClose(false);
}
Boolean openAction = regionsInTransitionInRS.get(encodedName);
if (openAction != null) {
if (openAction.booleanValue()) {
@ -3466,7 +3497,7 @@ public class HRegionServer implements ClientProtocol,
}
checkIfRegionInTransition(encodedName, CLOSE);
}
HRegion region = getRegionByEncodedName(encodedRegionName);
requestCount.increment();
LOG.info("Received close region: " + region.getRegionNameAsString() +
". Version of ZK closing node:" + versionOfClosingNode +

View File

@ -36,7 +36,6 @@ import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.Coprocessor;
import org.apache.hadoop.hbase.CoprocessorEnvironment;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HTableDescriptor;
@ -53,8 +52,8 @@ import org.apache.hadoop.hbase.coprocessor.CoprocessorService;
import org.apache.hadoop.hbase.coprocessor.ObserverContext;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
import org.apache.hadoop.hbase.coprocessor.RegionObserver;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.filter.ByteArrayComparable;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.ipc.CoprocessorProtocol;
import org.apache.hadoop.hbase.regionserver.wal.HLogKey;
@ -267,17 +266,19 @@ public class RegionCoprocessorHost
}
/**
* Invoked before a region open
* Invoked before a region open.
*
* @throws IOException Signals that an I/O exception has occurred.
*/
public void preOpen() {
public void preOpen() throws IOException {
ObserverContext<RegionCoprocessorEnvironment> ctx = null;
for (RegionEnvironment env: coprocessors) {
if (env.getInstance() instanceof RegionObserver) {
ctx = ObserverContext.createAndPrepare(env, ctx);
try {
((RegionObserver)env.getInstance()).preOpen(ctx);
((RegionObserver) env.getInstance()).preOpen(ctx);
} catch (Throwable e) {
handleCoprocessorThrowableNoRethrow(env, e);
handleCoprocessorThrowable(env, e);
}
if (ctx.shouldComplete()) {
break;
@ -295,7 +296,7 @@ public class RegionCoprocessorHost
if (env.getInstance() instanceof RegionObserver) {
ctx = ObserverContext.createAndPrepare(env, ctx);
try {
((RegionObserver)env.getInstance()).postOpen(ctx);
((RegionObserver) env.getInstance()).postOpen(ctx);
} catch (Throwable e) {
handleCoprocessorThrowableNoRethrow(env, e);
}
@ -310,15 +311,15 @@ public class RegionCoprocessorHost
* Invoked before a region is closed
* @param abortRequested true if the server is aborting
*/
public void preClose(boolean abortRequested) {
public void preClose(boolean abortRequested) throws IOException {
ObserverContext<RegionCoprocessorEnvironment> ctx = null;
for (RegionEnvironment env: coprocessors) {
if (env.getInstance() instanceof RegionObserver) {
ctx = ObserverContext.createAndPrepare(env, ctx);
try {
((RegionObserver)env.getInstance()).preClose(ctx, abortRequested);
((RegionObserver) env.getInstance()).preClose(ctx, abortRequested);
} catch (Throwable e) {
handleCoprocessorThrowableNoRethrow(env, e);
handleCoprocessorThrowable(env, e);
}
}
}
@ -334,7 +335,7 @@ public class RegionCoprocessorHost
if (env.getInstance() instanceof RegionObserver) {
ctx = ObserverContext.createAndPrepare(env, ctx);
try {
((RegionObserver)env.getInstance()).postClose(ctx, abortRequested);
((RegionObserver) env.getInstance()).postClose(ctx, abortRequested);
} catch (Throwable e) {
handleCoprocessorThrowableNoRethrow(env, e);
}

View File

@ -0,0 +1,108 @@
/**
*
* 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.
*/
package org.apache.hadoop.hbase.regionserver;
import java.io.IOException;
import java.util.Comparator;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Coprocessor;
import org.apache.hadoop.hbase.CoprocessorEnvironment;
import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
import org.apache.hadoop.hbase.coprocessor.ObserverContext;
import org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment;
import org.apache.hadoop.hbase.coprocessor.RegionServerObserver;
public class RegionServerCoprocessorHost extends
CoprocessorHost<RegionServerCoprocessorHost.RegionServerEnvironment> {
private RegionServerServices rsServices;
public RegionServerCoprocessorHost(RegionServerServices rsServices,
Configuration conf) {
this.rsServices = rsServices;
this.conf = conf;
// load system default cp's from configuration.
loadSystemCoprocessors(conf, REGIONSERVER_COPROCESSOR_CONF_KEY);
}
@Override
public RegionServerEnvironment createEnvironment(Class<?> implClass,
Coprocessor instance, int priority, int sequence, Configuration conf) {
return new RegionServerEnvironment(implClass, instance, priority,
sequence, conf, this.rsServices);
}
public void preStop(String message) throws IOException {
ObserverContext<RegionServerCoprocessorEnvironment> ctx = null;
for (RegionServerEnvironment env : coprocessors) {
if (env.getInstance() instanceof RegionServerObserver) {
ctx = ObserverContext.createAndPrepare(env, ctx);
((RegionServerObserver) env.getInstance()).preStopRegionServer(ctx);
if (ctx.shouldComplete()) {
break;
}
}
}
}
/**
* Coprocessor environment extension providing access to region server
* related services.
*/
static class RegionServerEnvironment extends CoprocessorHost.Environment
implements RegionServerCoprocessorEnvironment {
private RegionServerServices regionServerServices;
public RegionServerEnvironment(final Class<?> implClass,
final Coprocessor impl, final int priority, final int seq,
final Configuration conf, final RegionServerServices services) {
super(impl, priority, seq, conf);
this.regionServerServices = services;
}
@Override
public RegionServerServices getRegionServerServices() {
return regionServerServices;
}
}
/**
* Environment priority comparator. Coprocessors are chained in sorted
* order.
*/
static class EnvironmentPriorityComparator implements
Comparator<CoprocessorEnvironment> {
public int compare(final CoprocessorEnvironment env1,
final CoprocessorEnvironment env2) {
if (env1.getPriority() < env2.getPriority()) {
return -1;
} else if (env1.getPriority() > env2.getPriority()) {
return 1;
}
if (env1.getLoadSequence() < env2.getLoadSequence()) {
return -1;
} else if (env1.getLoadSequence() > env2.getLoadSequence()) {
return 1;
}
return 0;
}
}
}

View File

@ -64,6 +64,7 @@ import org.apache.hadoop.hbase.security.AccessDeniedException;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.security.access.Permission.Action;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
@ -105,7 +106,7 @@ import static org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.Acc
* </p>
*/
public class AccessController extends BaseRegionObserver
implements MasterObserver, AccessControllerProtocol,
implements MasterObserver, RegionServerObserver, AccessControllerProtocol,
AccessControlService.Interface, CoprocessorService {
/**
* Represents the result of an authorization check for logging and error
@ -514,17 +515,31 @@ public class AccessController extends BaseRegionObserver
/* ---- MasterObserver implementation ---- */
public void start(CoprocessorEnvironment env) throws IOException {
// if running on HMaster
ZooKeeperWatcher zk = null;
if (env instanceof MasterCoprocessorEnvironment) {
MasterCoprocessorEnvironment e = (MasterCoprocessorEnvironment)env;
this.authManager = TableAuthManager.get(
e.getMasterServices().getZooKeeper(),
e.getConfiguration());
// if running on HMaster
MasterCoprocessorEnvironment mEnv = (MasterCoprocessorEnvironment) env;
zk = mEnv.getMasterServices().getZooKeeper();
} else if (env instanceof RegionServerCoprocessorEnvironment) {
RegionServerCoprocessorEnvironment rsEnv = (RegionServerCoprocessorEnvironment) env;
zk = rsEnv.getRegionServerServices().getZooKeeper();
} else if (env instanceof RegionCoprocessorEnvironment) {
// if running at region
regionEnv = (RegionCoprocessorEnvironment) env;
zk = regionEnv.getRegionServerServices().getZooKeeper();
}
// if running at region
if (env instanceof RegionCoprocessorEnvironment) {
regionEnv = (RegionCoprocessorEnvironment)env;
// If zk is null or IOException while obtaining auth manager,
// throw RuntimeException so that the coprocessor is unloaded.
if (zk != null) {
try {
this.authManager = TableAuthManager.get(zk, env.getConfiguration());
} catch (IOException ioe) {
throw new RuntimeException("Error obtaining TableAuthManager", ioe);
}
} else {
throw new RuntimeException("Error obtaining TableAuthManager, zk found null.");
}
}
@ -763,28 +778,36 @@ public class AccessController extends BaseRegionObserver
/* ---- RegionObserver implementation ---- */
@Override
public void preOpen(ObserverContext<RegionCoprocessorEnvironment> e)
throws IOException {
RegionCoprocessorEnvironment env = e.getEnvironment();
final HRegion region = env.getRegion();
if (region == null) {
LOG.error("NULL region from RegionCoprocessorEnvironment in preOpen()");
return;
} else {
HRegionInfo regionInfo = region.getRegionInfo();
if (isSpecialTable(regionInfo)) {
isSystemOrSuperUser(regionEnv.getConfiguration());
} else {
requirePermission(Action.ADMIN);
}
}
}
@Override
public void postOpen(ObserverContext<RegionCoprocessorEnvironment> c) {
RegionCoprocessorEnvironment e = c.getEnvironment();
final HRegion region = e.getRegion();
RegionCoprocessorEnvironment env = c.getEnvironment();
final HRegion region = env.getRegion();
if (region == null) {
LOG.error("NULL region from RegionCoprocessorEnvironment in postOpen()");
return;
}
try {
this.authManager = TableAuthManager.get(
e.getRegionServerServices().getZooKeeper(),
regionEnv.getConfiguration());
} catch (IOException ioe) {
// pass along as a RuntimeException, so that the coprocessor is unloaded
throw new RuntimeException("Error obtaining TableAuthManager", ioe);
}
if (AccessControlLists.isAclRegion(region)) {
aclRegion = true;
try {
initialize(e);
initialize(env);
} catch (IOException ex) {
// if we can't obtain permissions, it's better to fail
// than perform checks incorrectly
@ -1269,4 +1292,43 @@ public class AccessController extends BaseRegionObserver
}
return tableName;
}
@Override
public void preClose(ObserverContext<RegionCoprocessorEnvironment> e, boolean abortRequested)
throws IOException {
requirePermission(Action.ADMIN);
}
private void isSystemOrSuperUser(Configuration conf) throws IOException {
User user = User.getCurrent();
if (user == null) {
throw new IOException("Unable to obtain the current user, " +
"authorization checks for internal operations will not work correctly!");
}
String currentUser = user.getShortName();
List<String> superusers = Lists.asList(currentUser, conf.getStrings(
AccessControlLists.SUPERUSER_CONF_KEY, new String[0]));
User activeUser = getActiveUser();
if (!(superusers.contains(activeUser.getShortName()))) {
throw new AccessDeniedException("User '" + (user != null ? user.getShortName() : "null") +
"is not system or super user.");
}
}
private boolean isSpecialTable(HRegionInfo regionInfo) {
byte[] tableName = regionInfo.getTableName();
return tableName.equals(AccessControlLists.ACL_TABLE_NAME)
|| tableName.equals(Bytes.toBytes("-ROOT-"))
|| tableName.equals(Bytes.toBytes(".META."));
}
@Override
public void preStopRegionServer(
ObserverContext<RegionServerCoprocessorEnvironment> env)
throws IOException {
requirePermission(Permission.Action.ADMIN);
}
}

View File

@ -35,6 +35,7 @@ import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.LargeTests;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.UnknownRowLockException;
import org.apache.hadoop.hbase.client.Append;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
@ -49,6 +50,7 @@ import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
import org.apache.hadoop.hbase.coprocessor.ObserverContext;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
import org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment;
import org.apache.hadoop.hbase.master.MasterCoprocessorHost;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos;
@ -56,6 +58,7 @@ import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessCont
import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.CheckPermissionsRequest;
import org.apache.hadoop.hbase.regionserver.HRegion;
import org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost;
import org.apache.hadoop.hbase.regionserver.RegionServerCoprocessorHost;
import org.apache.hadoop.hbase.security.AccessDeniedException;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.security.access.Permission.Action;
@ -84,7 +87,7 @@ public class TestAccessController {
private static User SUPERUSER;
// user granted with all global permission
private static User USER_ADMIN;
// user with rw permissions
// user with rw permissions on column family.
private static User USER_RW;
// user with read-only permissions
private static User USER_RO;
@ -100,6 +103,7 @@ public class TestAccessController {
private static MasterCoprocessorEnvironment CP_ENV;
private static RegionCoprocessorEnvironment RCP_ENV;
private static RegionServerCoprocessorEnvironment RSCP_ENV;
private static AccessController ACCESS_CONTROLLER;
@BeforeClass
@ -114,6 +118,10 @@ public class TestAccessController {
ACCESS_CONTROLLER = (AccessController) cpHost.findCoprocessor(AccessController.class.getName());
CP_ENV = cpHost.createEnvironment(AccessController.class, ACCESS_CONTROLLER,
Coprocessor.PRIORITY_HIGHEST, 1, conf);
RegionServerCoprocessorHost rsHost = TEST_UTIL.getMiniHBaseCluster().getRegionServer(0)
.getCoprocessorHost();
RSCP_ENV = rsHost.createEnvironment(AccessController.class, ACCESS_CONTROLLER,
Coprocessor.PRIORITY_HIGHEST, 1, conf);
// Wait for the ACL table to become available
TEST_UTIL.waitTableAvailable(AccessControlLists.ACL_TABLE_NAME, 5000);
@ -1363,4 +1371,44 @@ public class TestAccessController {
}
}
@Test
public void testStopRegionServer() throws Exception {
PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
public Object run() throws Exception {
ACCESS_CONTROLLER.preStopRegionServer(ObserverContext.createAndPrepare(RSCP_ENV, null));
return null;
}
};
verifyAllowed(action, SUPERUSER, USER_ADMIN);
verifyDenied(action, USER_CREATE, USER_OWNER, USER_RW, USER_RO, USER_NONE);
}
@Test
public void testOpenRegion() throws Exception {
PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
public Object run() throws Exception {
ACCESS_CONTROLLER.preOpen(ObserverContext.createAndPrepare(RCP_ENV, null));
return null;
}
};
verifyAllowed(action, SUPERUSER, USER_ADMIN);
verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER);
}
@Test
public void testCloseRegion() throws Exception {
PrivilegedExceptionAction action = new PrivilegedExceptionAction() {
public Object run() throws Exception {
ACCESS_CONTROLLER.preClose(ObserverContext.createAndPrepare(RCP_ENV, null), false);
return null;
}
};
verifyAllowed(action, SUPERUSER, USER_ADMIN);
verifyDenied(action, USER_CREATE, USER_RW, USER_RO, USER_NONE, USER_OWNER);
}
}