You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by je...@apache.org on 2016/02/11 16:27:24 UTC
[60/62] [abbrv] incubator-geode git commit: Merge branch 'develop'
into feature/GEODE-17
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c39f8a5f/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/CommandTestBase.java
----------------------------------------------------------------------
diff --cc gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/CommandTestBase.java
index a7e8139,0000000..3c7b0da
mode 100644,000000..100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/CommandTestBase.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/CommandTestBase.java
@@@ -1,602 -1,0 +1,603 @@@
+package com.gemstone.gemfire.management.internal.security;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
++import com.gemstone.gemfire.management.internal.cli.HeadlessGfsh;
++import com.gemstone.gemfire.test.dunit.LogWriterUtils;
+import util.TestException;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache30.CacheTestCase;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.internal.AvailablePortHelper;
+import com.gemstone.gemfire.management.ManagementService;
+import com.gemstone.gemfire.management.internal.cli.CommandManager;
+import com.gemstone.gemfire.management.internal.cli.i18n.CliStrings;
+import com.gemstone.gemfire.management.internal.cli.parser.CommandTarget;
+import com.gemstone.gemfire.management.internal.cli.result.CommandResult;
+import com.gemstone.gemfire.management.internal.cli.shell.Gfsh;
+import com.gemstone.gemfire.management.internal.cli.util.CommandStringBuilder;
+
- import dunit.Host;
- import dunit.SerializableCallable;
- import dunit.SerializableRunnable;
++import com.gemstone.gemfire.test.dunit.Host;
++import com.gemstone.gemfire.test.dunit.SerializableCallable;
++import com.gemstone.gemfire.test.dunit.SerializableRunnable;
+
+/**
+ * Base class for all the CLI/gfsh command dunit tests. Derived from CliCommandTestBase but not using
+ * TestableGfsh but HeadlessGfsh
+ *
+ * @author Tushar Khairnar
+ */
+public class CommandTestBase extends CacheTestCase {
+
+ private static final long serialVersionUID = 1L;
+
+ protected static final String USE_HTTP_SYSTEM_PROPERTY = "useHTTP";
+
+ private ManagementService managementService;
+
+ private transient HeadlessGfsh shell;
+
+ private boolean useHttpOnConnect = Boolean.getBoolean("useHTTP");
+
+ private int httpPort;
+ private int jmxPort;
+
+ private String jmxHost;
+
+ protected String securityFile = null;
+ protected String userName = null;
+ protected String password = null;
+ protected String commandError = null;
+
+ public CommandTestBase(String name) {
+ super(name);
+ }
+
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
- public void tearDown2() throws Exception {
++ public void postTearDownCacheTestCase() throws Exception {
+ destroyDefaultSetup();
- super.tearDown2();
+ }
+
+ protected void setUseHttpOnConnect(boolean useHttpOnConnect){
+ this.useHttpOnConnect = useHttpOnConnect;
+ }
+
+ /**
+ * Create all of the components necessary for the default setup. The provided properties will be used when creating
+ * the default cache. This will create GFSH in the controller VM (VM[4]) (no cache) and the manager in VM[0] (with
+ * cache). When adding regions, functions, keys, whatever to your cache for tests, you'll need to use
+ * Host.getHost(0).getVM(0).invoke(new SerializableRunnable() { public void run() { ... } } in order to have this
+ * setup run in the same VM as the manager.
+ * <p/>
+ * @param props the Properties used when creating the cache for this default setup.
+ * @return the default testable GemFire shell.
+ */
+ @SuppressWarnings("serial")
+ protected final HeadlessGfsh createDefaultSetup(final Properties props) {
+ Object[] result = (Object[]) Host.getHost(0).getVM(0).invoke(new SerializableCallable() {
+ public Object call() {
+ final Object[] result = new Object[3];
+ final Properties localProps = (props != null ? props : new Properties());
+
+ try {
+ jmxHost = InetAddress.getLocalHost().getHostName();
+ }
+ catch (UnknownHostException ignore) {
+ jmxHost = "localhost";
+ }
+
+ if (!localProps.containsKey(DistributionConfig.NAME_NAME)) {
+ localProps.setProperty(DistributionConfig.NAME_NAME, "Manager");
+ }
+
+ final int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2);
+
+ jmxPort = ports[0];
+ httpPort = ports[1];
+
+ localProps.setProperty(DistributionConfig.JMX_MANAGER_NAME, "true");
+ localProps.setProperty(DistributionConfig.JMX_MANAGER_START_NAME, "true");
+ localProps.setProperty(DistributionConfig.JMX_MANAGER_BIND_ADDRESS_NAME, String.valueOf(jmxHost));
+ localProps.setProperty(DistributionConfig.JMX_MANAGER_PORT_NAME, String.valueOf(jmxPort));
+ localProps.setProperty(DistributionConfig.HTTP_SERVICE_PORT_NAME, String.valueOf(httpPort));
+
+ getSystem(localProps);
+ verifyManagementServiceStarted(getCache());
+
+ result[0] = jmxHost;
+ result[1] = jmxPort;
+ result[2] = httpPort;
+
+ return result;
+ }
+ });
+
+ this.jmxHost = (String) result[0];
+ this.jmxPort = (Integer) result[1];
+ this.httpPort = (Integer) result[2];
+
+ return defaultShellConnect();
+ }
+
+ protected boolean useHTTPByTest(){
+ return false;
+ }
+
+ /**
+ * Destroy all of the components created for the default setup.
+ */
+ @SuppressWarnings("serial")
+ protected final void destroyDefaultSetup() {
+ if (this.shell != null) {
+
+ if(shell.isConnectedAndReady()){
+ executeCommand(shell, "disconnect");
+ }
+
+ // Note: HeadlessGfsh doesn't use Launcher & code that does System.exit()
+ // for gfsh is in Launcher. This is just to ensure cleanup.
+ executeCommand(shell, "exit");
+
+ this.shell.terminate();
+ this.shell = null;
+ }
+
+ disconnectAllFromDS();
+
+ Host.getHost(0).getVM(0).invoke(new SerializableRunnable() {
+ public void run() {
+ verifyManagementServiceStopped();
+ }
+ });
+ }
+
+ /**
+ * Start the default management service using the provided Cache.
+ *
+ * @param cache
+ * Cache to use when creating the management service
+ */
+ private void verifyManagementServiceStarted(Cache cache) {
+ assert(cache != null);
+
+ this.managementService = ManagementService.getExistingManagementService(cache);
+ assertNotNull(this.managementService);
+ assertTrue(this.managementService.isManager());
+ assertTrue(checkIfCommandsAreLoadedOrNot());
+ }
+
+ public static boolean checkIfCommandsAreLoadedOrNot(){
+ CommandManager manager;
+ try {
+ manager = CommandManager.getInstance();
+ Map<String,CommandTarget> commands = manager.getCommands();
+ Set set = commands.keySet();
+ if(commands.size() < 1 ){
+ return false;
+ }
+ return true;
+ } catch (ClassNotFoundException | IOException e) {
+ throw new RuntimeException("Could not load commands", e);
+ }
+}
+
+ /**
+ * Stop the default management service.
+ */
+ private void verifyManagementServiceStopped() {
+ if (this.managementService != null) {
+ assertFalse(this.managementService.isManager());
+ this.managementService = null;
+ }
+ }
+
+ /**
+ * Connect the default shell to the default JMX server.
+ *
+ * @return The default shell.
+ */
+ protected HeadlessGfsh defaultShellConnect() {
+ HeadlessGfsh shell = getDefaultShell();
+ shellConnect(this.jmxHost, this.jmxPort, this.httpPort, shell);
+ return shell;
+ }
+
+ /**
+ * Connect a shell to the JMX server at the given host and port
+ *
+ * @param host
+ * Host of the JMX server
+ * @param jmxPort
+ * Port of the JMX server
+ * @param shell
+ * Shell to connect
+ */
+ protected void shellConnect(final String host, final int jmxPort, final int httpPort, HeadlessGfsh shell) {
+ assert(host != null);
+ assert(shell != null);
+
+ final CommandStringBuilder command = new CommandStringBuilder(CliStrings.CONNECT);
+ String endpoint;
+
+ if (useHttpOnConnect) {
+ endpoint = "http://" + host + ":" + httpPort + "/gemfire/v1";
+ command.addOption(CliStrings.CONNECT__USE_HTTP, Boolean.TRUE.toString());
+ command.addOption(CliStrings.CONNECT__URL, endpoint);
+
+ }
+ else {
+ endpoint = host + "[" + jmxPort + "]";
+ command.addOption(CliStrings.CONNECT__JMX_MANAGER, endpoint);
+ }
+
+ if(this.securityFile != null){
+ command.addOption(CliStrings.CONNECT__SECURITY_PROPERTIES, securityFile);
+ }
+
+ if(this.userName!=null) {
+ command.addOption(CliStrings.CONNECT__USERNAME, userName);
+ }
+
+ if(this.password!=null) {
+ command.addOption(CliStrings.CONNECT__PASSWORD, password);
+ }
+
+ CommandResult result = executeCommand(shell, command.toString());
+
+ if (!shell.isConnectedAndReady()) {
+ throw new TestException("Connect command failed to connect to manager " + endpoint + " result=" + commandResultToString(result));
+ }
+
+ info("Successfully connected to managing node using " + (useHttpOnConnect ? "HTTP" : "JMX"));
+ assertEquals(true, shell.isConnectedAndReady());
+ }
+
+ /**
+ * Get the default shell (will create one if it doesn't already exist).
+ *
+ * @return The default shell
+ */
+ protected synchronized final HeadlessGfsh getDefaultShell() {
+ if (this.shell == null) {
+ this.shell = createShell();
+ }
+
+ return this.shell;
+ }
+
+ /**
+ * Create a TestableGfsh object.
+ *
+ * @return The created shell.
+ */
+ protected HeadlessGfsh createShell() {
+ try {
+ Gfsh.SUPPORT_MUTLIPLESHELL = true;
+ String shellId = getClass().getSimpleName()+"_"+getName();
+ HeadlessGfsh shell = new HeadlessGfsh(shellId, 300);
+
+ //Various command use ThreadLocal instance. following call makes
+ //HeadlessGfsh available to all the commands
+ shell.setThreadLocalInstance();
+
+ //Added to avoid trimming of the columns. Not needed for non-interactive shell
+ //shell.setEnvProperty(Gfsh.ENV_APP_RESULT_VIEWER, "non-basic");
+ //shell.start();
+ info("Started headless shell: " + shell);
+ return shell;
+ } catch (ClassNotFoundException e) {
+ throw new TestException(getStackTrace(e));
+ } catch (IOException e) {
+ throw new TestException(getStackTrace(e));
+ }
+ }
+
+ /**
+ * Execute a command using the default shell and clear the shell events before returning.
+ *
+ * @param command
+ * Command to execute
+ * @return The result of the command execution
+ */
+ protected CommandResult executeCommand(String command) {
+ assert(command != null);
+
+ return executeCommand(getDefaultShell(), command);
+ }
+
+ /**
+ * Execute a command in the provided shell and clear the shell events before returning.
+ *
+ * @param shell
+ * Shell in which to execute the command.
+ * @param command
+ * Command to execute
+ * @return The result of the command execution
+ */
+ protected CommandResult executeCommand(HeadlessGfsh shell, String command) {
+ assert(shell != null);
+ assert(command != null);
+ CommandResult commandResult = executeCommandWithoutClear(shell, command);
+ shell.clear();
+ return commandResult;
+ }
+
+ /**
+ * Execute a command using the default shell. Useful for getting additional information from the shell after the
+ * command has been executed (using getDefaultShell().???). Caller is responsible for calling
+ * getDefaultShell().clearEvents() when done.
+ *
+ * @param command
+ * Command to execute
+ * @return The result of the command execution
+ */
+ @SuppressWarnings("unused")
+ protected CommandResult executeCommandWithoutClear(String command) {
+ assert(command != null);
+
+ return executeCommandWithoutClear(getDefaultShell(), command);
+ }
+
+ /**
+ * Execute a command in the provided shell. Useful for getting additional information from the shell after the command
+ * has been executed (using getDefaultShell().???). Caller is responsible for calling getDefaultShell().clearEvents()
+ * when done.
+ *
+ * @param shell
+ * Shell in which to execute the command.
+ * @param command
+ * Command to execute
+ * @return The result of the command execution
+ */
+ protected CommandResult executeCommandWithoutClear(HeadlessGfsh shell, String command) {
+ assert(shell != null);
+ assert(command != null);
+
+ try {
+ info("Executing command " + command + " with command Mgr " + CommandManager.getInstance());
+ } catch (ClassNotFoundException cnfex) {
+ throw new TestException(getStackTrace(cnfex));
+ } catch (IOException ioex) {
+ throw new TestException(getStackTrace(ioex));
+ }
+
+ Object result =null;
+
+ try {
+
+ boolean status = shell.executeCommand(command);
+ info("Waiting for result");
+ result = shell.getResult();
+ info("Got the Result");
+ info("CommandExecutionSuccess=" + status );
+ info("Status=" + shell.getCommandExecutionStatus());
+ info("ShellOutputString=<" + shell.outputString + ">");
+ info("ErrorString=<" + shell.getErrorString() + ">");
+
+ if (shell.hasError() || shell.getCommandExecutionStatus() == -1) {
+ error("executeCommand completed with error : " + shell.getErrorString() + " output=<" + shell.outputString
+ + ">");
+ }
+
+ if(result == null || result.equals(HeadlessGfsh.ERROR_RESULT))
+ return null;
+
+ } catch (InterruptedException e) {
+ throw new TestException(getStackTrace(e));
+ }
+
+ return (CommandResult)result;
+ }
+
+ /**
+ * Utility method for viewing the results of a command.
+ *
+ * @param commandResult
+ * Results to dump
+ * @param printStream
+ * Stream to dump the results to
+ */
+ protected void printResult(final CommandResult commandResult, PrintStream printStream) {
+ assert(commandResult != null);
+ assert(printStream != null);
+ commandResult.resetToFirstLine();
+ printStream.print(commandResultToString(commandResult));
+ }
+
+ protected String commandResultToString(final CommandResult commandResult) {
+ assertNotNull(commandResult);
+ commandResult.resetToFirstLine();
+ StringBuilder buffer = new StringBuilder(commandResult.getHeader());
+ while (commandResult.hasNextLine()) {
+ buffer.append(commandResult.nextLine());
+ }
+ buffer.append(commandResult.getFooter());
+ return buffer.toString();
+ }
+
+ /**
+ * Utility method for finding the CommandResult object in the Map of CommandOutput objects.
+ *
+ * @param commandOutput
+ * CommandOutput Map to search
+ * @return The CommandResult object or null if not found.
+ */
+ protected CommandResult extractCommandResult(Map<String, Object> commandOutput) {
+ assert(commandOutput != null);
+
+ for (Object resultObject : commandOutput.values()) {
+ if (resultObject instanceof CommandResult) {
+ CommandResult result = (CommandResult) resultObject;
+ result.resetToFirstLine();
+ return result;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Utility method to determine how many times a string occurs in another string. Note that when looking for matches
+ * substrings of other matches will be counted as a match. For example, looking for "AA" in the string "AAAA" will
+ * result in a return value of 3.
+ *
+ * @param stringToSearch
+ * String to search
+ * @param stringToCount
+ * String to look for and count
+ * @return The number of matches.
+ */
+ protected int countMatchesInString(final String stringToSearch, final String stringToCount) {
+ assert(stringToSearch != null);
+ assert(stringToCount != null);
+
+ int length = stringToSearch.length();
+ int count = 0;
+ for (int i = 0; i < length; i++) {
+ if (stringToSearch.substring(i).startsWith(stringToCount)) {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ /**
+ * Determines if a string contains a trimmed line that matches the pattern. So, any single line whose leading and
+ * trailing spaces have been removed which contains a string that exactly matches the given pattern will be considered
+ * a match.
+ *
+ * @param stringToSearch
+ * String to search
+ * @param stringPattern
+ * Pattern to search for
+ * @return True if a match is found, false otherwise
+ */
+ protected boolean stringContainsLine(final String stringToSearch, final String stringPattern) {
+ assert(stringToSearch != null);
+ assert(stringPattern != null);
+
+ Pattern pattern = Pattern.compile("^\\s*" + stringPattern + "\\s*$", Pattern.MULTILINE);
+ Matcher matcher = pattern.matcher(stringToSearch);
+ return matcher.find();
+ }
+
+ /**
+ * Counts the number of distinct lines in a String.
+ *
+ * @param stringToSearch
+ * String to search for lines.
+ * @param countBlankLines
+ * Whether to count blank lines (true to count)
+ * @return The number of lines found.
+ */
+ protected int countLinesInString(final String stringToSearch, final boolean countBlankLines) {
+ assert(stringToSearch != null);
+
+ int length = stringToSearch.length();
+ int count = 0;
+ char character = 0;
+ boolean foundNonSpaceChar = false;
+
+ for (int i = 0; i < length; i++) {
+ character = stringToSearch.charAt(i);
+ if (character == '\n' || character == '\r') {
+ if (countBlankLines) {
+ count++;
+ } else {
+ if (foundNonSpaceChar) {
+ count++;
+ }
+ }
+ foundNonSpaceChar = false;
+ } else if (character != ' ' && character != '\t') {
+ foundNonSpaceChar = true;
+ }
+ }
+
+ // Even if the last line isn't terminated, it still counts as a line
+ if (character != '\n' && character != '\r') {
+ count++;
+ }
+
+ return count;
+ }
+
+ /**
+ * Get a specific line from the string (using \n or \r as a line separator).
+ *
+ * @param stringToSearch String to get the line from
+ * @param lineNumber Line number to get
+ * @return The line
+ */
+ protected String getLineFromString(final String stringToSearch, final int lineNumber) {
+ assert(stringToSearch != null);
+ assert(lineNumber > 0);
+
+ int length = stringToSearch.length();
+ int count = 0;
+ int startIndex = 0;
+ char character;
+ int endIndex = length;
+
+ for (int i = 0; i < length; i++) {
+ character = stringToSearch.charAt(i);
+ if (character == '\n' || character == '\r') {
+ if (lineNumber == 1) {
+ endIndex = i;
+ break;
+ }
+ if (++count == lineNumber-1) {
+ startIndex = i+1;
+ } else if (count >= lineNumber) {
+ endIndex = i;
+ break;
+ }
+ }
+ }
+
+ return stringToSearch.substring(startIndex, endIndex);
+ }
+
+ protected void info(String string) {
- getLogWriter().info(string);
++ LogWriterUtils.getLogWriter().info(string);
+ }
+
+ protected void debug(String string) {
- getLogWriter().fine(string);
++ LogWriterUtils.getLogWriter().fine(string);
+ }
+
+ protected void error(String string) {
+ commandError = string;
- getLogWriter().error(string);
++ LogWriterUtils.getLogWriter().error(string);
+ }
+
+ protected void error(String string, Throwable e) {
+ commandError = string;
- getLogWriter().error(string, e);
++ LogWriterUtils.getLogWriter().error(string, e);
+ }
+
+ protected Object[] getJMXEndPoint(){
+ return new Object[] {jmxHost, jmxPort };
+ }
+
+ public static String getStackTrace(Throwable aThrowable) {
+ StringWriter sw = new StringWriter();
+ aThrowable.printStackTrace(new PrintWriter(sw, true));
+ return sw.toString();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c39f8a5f/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/IntegratedSecDUnitTest.java
----------------------------------------------------------------------
diff --cc gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/IntegratedSecDUnitTest.java
index 8e63524,0000000..4fa0804
mode 100644,000000..100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/IntegratedSecDUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/IntegratedSecDUnitTest.java
@@@ -1,698 -1,0 +1,705 @@@
+package com.gemstone.gemfire.management.internal.security;
+
+//import hydra.Log;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
++import java.util.concurrent.TimeUnit;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+
++import com.gemstone.gemfire.management.internal.cli.HeadlessGfsh;
++import com.gemstone.gemfire.test.dunit.DistributedTestCase;
++import com.gemstone.gemfire.test.dunit.Host;
++import com.gemstone.gemfire.test.dunit.SerializableRunnable;
++import com.gemstone.gemfire.test.dunit.VM;
++import com.gemstone.gemfire.test.dunit.WaitCriterion;
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.LogWriter;
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionFactory;
+import com.gemstone.gemfire.cache.RegionService;
+import com.gemstone.gemfire.cache.RegionShortcut;
+import com.gemstone.gemfire.cache.client.ClientCache;
+import com.gemstone.gemfire.cache.client.ClientCacheFactory;
+import com.gemstone.gemfire.cache.client.ClientRegionFactory;
+import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
+import com.gemstone.gemfire.cache.operations.OperationContext.OperationCode;
+import com.gemstone.gemfire.cache.server.CacheServer;
+import com.gemstone.gemfire.distributed.DistributedMember;
+import com.gemstone.gemfire.distributed.DistributedSystem;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.internal.AvailablePortHelper;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.management.DistributedRegionMXBean;
+import com.gemstone.gemfire.management.ManagementService;
+import com.gemstone.gemfire.management.ManagerMXBean;
+import com.gemstone.gemfire.management.internal.MBeanJMXAdapter;
+import com.gemstone.gemfire.management.internal.cli.domain.DataCommandRequest;
+import com.gemstone.gemfire.management.internal.cli.result.CommandResult;
+import com.gemstone.gemfire.management.internal.cli.result.CompositeResultData;
+import com.gemstone.gemfire.management.internal.cli.result.CompositeResultData.SectionResultData;
+import com.gemstone.gemfire.management.internal.cli.result.ErrorResultData;
+import com.gemstone.gemfire.management.internal.cli.result.ResultData;
+import com.gemstone.gemfire.management.internal.security.ResourceOperationContext.ResourceOperationCode;
+import com.gemstone.gemfire.security.AuthInitialize;
+import com.gemstone.gemfire.security.AuthenticationFailedException;
+
- import dunit.DistributedTestCase;
- import dunit.Host;
- import dunit.SerializableRunnable;
- import dunit.VM;
++import static com.jayway.awaitility.Awaitility.waitAtMost;
++import static org.hamcrest.Matchers.equalTo;
++import static org.hamcrest.Matchers.is;
++import static org.hamcrest.Matchers.not;
++
++//import dunit.DistributedTestCase;
++//import dunit.Host;
++//import dunit.SerializableRunnable;
++//import dunit.VM;
+
+/**
+ * @author tushark
+ *
+ */
+public class IntegratedSecDUnitTest extends CommandTestBase {
+
+ private static Logger logger = LogService.getLogger();
+
+ public static class AuthInitializer implements AuthInitialize {
+
+ public static AuthInitialize create() {
+ return new AuthInitializer();
+ }
+
+ public void init(LogWriter systemLogger, LogWriter securityLogger) throws AuthenticationFailedException {
+ }
+
+ public Properties getCredentials(Properties p, DistributedMember server, boolean isPeer)
+ throws AuthenticationFailedException {
+ return p;
+ }
+
+ public void close() {
+ }
+ }
+
+ private static final long serialVersionUID = 1L;
+ private static IntegratedSecDUnitTest instance = new IntegratedSecDUnitTest("IntegratedSecDUnitTest");
+
+ private Cache cache;
+ private DistributedSystem ds;
+ private CacheServer cacheServer;
+ private ClientCache clientCache;
+ private int cacheServerPort;
+ private String hostName;
+
+ public IntegratedSecDUnitTest(String name) {
+ super(name);
+ }
+
+ public Cache createCache(Properties props) throws Exception {
+ ds = getSystem(props);
+ cache = CacheFactory.create(ds);
+ if (cache == null) {
+ throw new Exception("CacheFactory.create() returned null ");
+ }
+ return cache;
+ }
+
+ private void createServer() throws IOException {
+ cacheServerPort = AvailablePortHelper.getRandomAvailableTCPPort();
+ cacheServer = cache.addCacheServer();
+ cacheServer.setPort(cacheServerPort);
+ cacheServer.start();
+ hostName = cacheServer.getHostnameForClients();
+ }
+
+ public int getCacheServerPort() {
+ return cacheServerPort;
+ }
+
+ public String getCacheServerHost() {
+ return hostName;
+ }
+
+ public void stopCacheServer() {
+ this.cacheServer.stop();
+ }
+
+ @SuppressWarnings("rawtypes")
+ public void setUpServerVM(Properties gemFireProps) throws Exception {
+ logger.info("Creating server vm cache with props =" + gemFireProps);
- gemFireProps.setProperty(DistributionConfig.NAME_NAME, testName + "Server");
++ gemFireProps.setProperty(DistributionConfig.NAME_NAME, getTestMethodName() + "Server");
+ createCache(gemFireProps);
+ RegionFactory factory = cache.createRegionFactory(RegionShortcut.REPLICATE);
+ Region r = factory.create("serverRegion");
+ assertNotNull(r);
+ r.put("serverkey", "servervalue");
+ assertEquals(1,r.size());
+ logger.info("Created serverRegion with 1 key=serverKey");
+ }
+
+ public void setUpClientVM(Properties gemFireProps, String host, int port, String user, String password) {
- gemFireProps.setProperty(DistributionConfig.NAME_NAME, testName + "Client");
++ gemFireProps.setProperty(DistributionConfig.NAME_NAME, getTestMethodName() + "Client");
+ gemFireProps.setProperty("security-client-auth-init",
+ "com.gemstone.gemfire.management.internal.security.IntegratedSecDUnitTest$AuthInitializer.create");
+ logger.info("Creating client cache with props =" + gemFireProps);
+ ClientCacheFactory clientCacheFactory = new ClientCacheFactory(gemFireProps);
+ clientCacheFactory.addPoolServer(host, port);
+ clientCacheFactory.setPoolMultiuserAuthentication(true);
+ clientCache = clientCacheFactory.create();
+ ClientRegionFactory<String, String> regionFactory = clientCache
+ .createClientRegionFactory(ClientRegionShortcut.PROXY);
+
+ Region<String, String> region = regionFactory.create("serverRegion");
+ assertNotNull(region);
+
+ Properties properties = new Properties();
+ properties.setProperty("security-username", user);
+ properties.setProperty("security-password", password);
+ RegionService regionService = instance.clientCache.createAuthenticatedView(properties);
+ Region secRegion = regionService.getRegion("serverRegion");
+ assertNotNull(secRegion.get("serverkey"));
+ }
+
+ public static void setUpServerVMTask(Properties props) throws Exception {
+ instance.setUpServerVM(props);
+ }
+
+ public static void createServerTask() throws Exception {
+ instance.createServer();
+ }
+
+ public static void setUpClientVMTask(Properties gemFireProps, String host, int port, String user, String password)
+ throws Exception {
+ instance.setUpClientVM(gemFireProps, host, port, user, password);
+ }
+
+ public static Object[] getCacheServerEndPointTask() {
+ Object[] array = new Object[2];
+ array[0] = instance.getCacheServerHost();
+ array[1] = instance.getCacheServerPort();
+ return array;
+ }
+
+ public static void closeCacheTask() {
+ instance.cache.close();
+ }
+
+ public static void closeClientCacheTask() {
+ instance.clientCache.close();
+ }
+
+ /**
+ *
+ * VM0 -> Manager
+ * VM1 -> Server
+ * Vm2 -> CacheClient
+ *
+ * @param testName
+ * @throws IOException
+ */
+
+ @SuppressWarnings("serial")
+ void setup(String testName) throws IOException {
+
+ configureIntSecDescriptor();
+
+ Properties props = new Properties();
+
+ props.put(DistributionConfig.SECURITY_CLIENT_AUTHENTICATOR_NAME,
+ "com.gemstone.gemfire.management.internal.security.TestAuthenticator.create");
+ props.put(DistributionConfig.SECURITY_CLIENT_ACCESSOR_NAME,
+ "com.gemstone.gemfire.management.internal.security.TestAccessControl.create");
+ props.put(DistributionConfig.SECURITY_CLIENT_ACCESSOR_PP_NAME,
+ "com.gemstone.gemfire.management.internal.security.TestAccessControl.create");
+ props.setProperty(DistributionConfig.NAME_NAME, "Manager");
+ HeadlessGfsh gfsh = createDefaultSetup(props);
+ assertNotNull(gfsh);
+ assertEquals(true, gfsh.isConnectedAndReady());
+
+ props.list(System.out);
+
+ final Host host = Host.getHost(0);
+ VM serverVM = host.getVM(1);
+ VM clientVM = host.getVM(2);
+ VM managerVM = host.getVM(0);
+ serverVM.invoke(IntegratedSecDUnitTest.class, "setUpServerVMTask", new Object[] { props });
+ serverVM.invoke(IntegratedSecDUnitTest.class, "createServerTask");
+
+ Object array[] = (Object[]) serverVM.invoke(IntegratedSecDUnitTest.class, "getCacheServerEndPointTask");
+ String hostName = (String) array[0];
+ int port = (Integer) array[1];
+ Object params[] = new Object[] { props, hostName, port, "tushark", "password123" };
+ logger.info("Starting client with server endpoint " + hostName + ":" + port);
+ clientVM.invoke(IntegratedSecDUnitTest.class, "setUpClientVMTask", params);
+
+ SerializableRunnable checkRegionMBeans = new SerializableRunnable() {
+ @Override
+ public void run() {
+ Cache cache = getCache();
+ final ManagementService service = ManagementService.getManagementService(cache);
+
- final WaitCriterion waitForMaangerMBean = new WaitCriterion() {
- @Override
- public boolean done() {
- ManagerMXBean bean1 = service.getManagerMXBean();
- DistributedRegionMXBean bean2 = service.getDistributedRegionMXBean("/serverRegion");
- if (bean1 == null) {
- logger.info("Still probing for ManagerMBean");
- return false;
- } else {
- logger.info("Still probing for DistributedRegionMXBean=" + bean2);
- return (bean2 != null);
- }
- }
-
- @Override
- public String description() {
- return "Probing for DistributedRegionMXBean for serverRegion";
- }
- };
-
- DistributedTestCase.waitForCriterion(waitForMaangerMBean, 30000, 2000, true);
++// final WaitCriterion waitForMaangerMBean = new WaitCriterion() {
++// @Override
++// public boolean done() {
++// ManagerMXBean bean1 = service.getManagerMXBean();
++// DistributedRegionMXBean bean2 = service.getDistributedRegionMXBean("/serverRegion");
++// if (bean1 == null) {
++// logger.info("Still probing for ManagerMBean");
++// return false;
++// } else {
++// logger.info("Still probing for DistributedRegionMXBean=" + bean2);
++// return (bean2 != null);
++// }
++// }
++//
++// @Override
++// public String description() {
++// return "Probing for DistributedRegionMXBean for serverRegion";
++// }
++// };
++
++// DistributedTestCase.waitForCriterion(waitForMaangerMBean, 30000, 2000, true);
++ waitAtMost(30, TimeUnit.SECONDS).untilCall(service.getManagerMXBean(), is(not(null)));
++ waitAtMost(30, TimeUnit.SECONDS).untilCall(service.getDistributedRegionMXBean("/serverRegion"), is(not(null)));
+
+ assertNotNull(service.getMemberMXBean());
+ assertNotNull(service.getManagerMXBean());
+ DistributedRegionMXBean bean = service.getDistributedRegionMXBean("/serverRegion");
+ assertNotNull(bean);
+ }
+ };
+ managerVM.invoke(checkRegionMBeans);
+ }
+
+ @SuppressWarnings("serial")
+ private void configureIntSecDescriptor() {
+ this.userName = "tushark";
+ this.password = "password123";
+
+ final Host host = Host.getHost(0);
+ final VM serverVM = host.getVM(1);
+ final VM clientVM = host.getVM(2);
+ final VM managerVM = host.getVM(0);
+ SerializableRunnable grantOpsUser1Runnable = new SerializableRunnable() {
+ @Override
+ public void run() {
+ TestAuthenticator.addUser("tushark", "password123");
+ TestAuthenticator.addUser("dataRead", "password123");
+ TestAuthenticator.addUser("dataWrite", "password123");
+ TestAuthenticator.addUser("monitor", "password123");
+ TestAuthenticator.addUser("admin", "password123");
+ TestAuthenticator.addUser("custom", "password123");
+
+ TestAccessControl.grantCacheOp("tushark", OperationCode.GET);
+ TestAccessControl.grantCacheOp("tushark", OperationCode.PUT);
+ TestAccessControl.grantCacheOp("tushark", OperationCode.DESTROY);
+ TestAccessControl.grantCacheOp("tushark", OperationCode.REMOVEALL);
+ TestAccessControl.grantCacheOp("tushark", OperationCode.EXECUTE_FUNCTION);
+ TestAccessControl.grantCacheOp("tushark", OperationCode.QUERY);
+
+ TestAccessControl.grantResourceOp("tushark", ResourceOperationCode.DATA_READ);
+ TestAccessControl.grantResourceOp("tushark", ResourceOperationCode.DATA_WRITE);
+ TestAccessControl.grantResourceOp("tushark", ResourceOperationCode.MONITOR);
+ TestAccessControl.grantResourceOp("tushark", ResourceOperationCode.CHANGE_ALERT_LEVEL);
+
+ TestAccessControl.grantCacheOp("dataRead", OperationCode.GET);
+ TestAccessControl.grantResourceOp("dataRead", ResourceOperationCode.DATA_READ);
+
+ TestAccessControl.grantCacheOp("dataWrite", OperationCode.GET);
+ TestAccessControl.grantCacheOp("dataWrite", OperationCode.PUT);
+ TestAccessControl.grantCacheOp("dataWrite", OperationCode.DESTROY);
+ TestAccessControl.grantCacheOp("dataWrite", OperationCode.REGION_CREATE);
+ TestAccessControl.grantCacheOp("dataWrite", OperationCode.REGION_DESTROY);
+ TestAccessControl.grantResourceOp("dataWrite", ResourceOperationCode.DATA_WRITE);
+
+ TestAccessControl.grantResourceOp("monitor", ResourceOperationCode.DATA_READ);
+ TestAccessControl.grantResourceOp("monitor", ResourceOperationCode.MONITOR);
+
+ TestAccessControl.grantResourceOp("admin", ResourceOperationCode.ADMIN);
+
+ TestAccessControl.grantResourceOp("custom", ResourceOperationCode.DATA_READ);
+ TestAccessControl.grantResourceOp("custom", ResourceOperationCode.SHOW_DEADLOCKS);
+ TestAccessControl.grantResourceOp("custom", ResourceOperationCode.CREATE_REGION);
+ TestAccessControl.grantCacheOp("custom", OperationCode.REGION_CREATE);
+ }
+ };
+ managerVM.invoke(grantOpsUser1Runnable);
+ serverVM.invoke(grantOpsUser1Runnable);
+ }
+
+ @SuppressWarnings("serial")
+ public static void grantCacheOp(final String user, final String code) {
+ final Host host = Host.getHost(0);
+ final VM serverVM = host.getVM(1);
+ final VM managerVM = host.getVM(0);
+ SerializableRunnable grantOpsUser1Runnable = new SerializableRunnable() {
+ @Override
+ public void run() {
+ TestAccessControl.grantCacheOp(user, OperationCode.parse(code));
+ }
+ };
+ managerVM.invoke(grantOpsUser1Runnable);
+ serverVM.invoke(grantOpsUser1Runnable);
+ }
+
+ @SuppressWarnings("serial")
+ public static void revokeCacheOp(final String user, final String code) {
+ final Host host = Host.getHost(0);
+ final VM serverVM = host.getVM(1);
+ final VM managerVM = host.getVM(0);
+ SerializableRunnable grantOpsUser1Runnable = new SerializableRunnable() {
+ @Override
+ public void run() {
+ TestAccessControl.revokeCacheOp(user, OperationCode.parse(code));
+ }
+ };
+ managerVM.invoke(grantOpsUser1Runnable);
+ serverVM.invoke(grantOpsUser1Runnable);
+ }
+
+ @SuppressWarnings("serial")
+ public static void grantResourceOp(final String user, final String code) {
+ final Host host = Host.getHost(0);
+ final VM serverVM = host.getVM(1);
+ final VM managerVM = host.getVM(0);
+ SerializableRunnable grantOpsUser1Runnable = new SerializableRunnable() {
+ @Override
+ public void run() {
+ TestAccessControl.grantResourceOp(user, ResourceOperationCode.parse(code));
+ }
+ };
+ managerVM.invoke(grantOpsUser1Runnable);
+ serverVM.invoke(grantOpsUser1Runnable);
+ }
+
+ @SuppressWarnings("serial")
+ public static void revokeResourceOp(final String user, final String code) {
+ final Host host = Host.getHost(0);
+ final VM serverVM = host.getVM(1);
+ final VM managerVM = host.getVM(0);
+ SerializableRunnable grantOpsUser1Runnable = new SerializableRunnable() {
+ @Override
+ public void run() {
+ TestAccessControl.revokeResourceOp(user, ResourceOperationCode.parse(code));
+ }
+ };
+ managerVM.invoke(grantOpsUser1Runnable);
+ serverVM.invoke(grantOpsUser1Runnable);
+ }
+
+
+ public static void doPutUsingClientCache(final String regionPath, final String key, final String value,
+ final boolean expectSuccess, String user, String password) {
+ try {
+ Properties properties = new Properties();
+ properties.setProperty("security-username", user);
+ properties.setProperty("security-password", password);
+ RegionService regionService = instance.clientCache.createAuthenticatedView(properties);
+ Region region = regionService.getRegion(regionPath);
+ assertNotNull(region);
+ Object oldValue = region.put(key, value);
+ logger.info("doPutUsingClientCache : Put key=" + key + " for user="+ user+" newValue="+ value + " oldValue="+ oldValue + " expectSuccess="+expectSuccess);
+ if (!expectSuccess)
+ fail("Region Put was expected to fail");
+ } catch (Exception e) {
+ if (!expectSuccess) {
+ logger.info("expectSuccess=false => " + e.getMessage());
+ } else {
+ logger.error("Unexpected error", e);
+ fail("Unknown reason " + e.getMessage());
+ }
+ }
+ }
+
+ public void doPutUsingGfsh(final String regionPath, final String key, final String value,
+ final boolean expectSuccess, String user, String password) {
+ String command = "put --region=" + regionPath + " --key=" + key + " --value=" + value;
+ changeGfshUser(user, password);
+ CommandResult result = executeCommand(command);
+ logger.info("CommandResult " + result);
+ if (expectSuccess) {
+ validateGfshResult(result, expectSuccess);
+ printCommandOutput(result);
+ }
+ else {
+ logger.info("Error line :" + this.commandError);
+ assertTrue(this.commandError.contains("Access Denied"));
+ this.commandError = null;
+ // validateGfshResultError(result);
+ }
+ }
+
+ private static void validateGfshResultError(CommandResult result) {
+ if (result.getType().equals(ResultData.TYPE_ERROR)) {
+ ErrorResultData data = (ErrorResultData) result.getResultData();
+ logger.info("Error resultData : " + data.toString());
+ } else
+ fail("Unexpected result type " + result.getType());
+ }
+
+ private static void validateGfshResult(CommandResult cmdResult, boolean expected) {
+ if (ResultData.TYPE_COMPOSITE.equals(cmdResult.getType())) {
+ CompositeResultData rd = (CompositeResultData) cmdResult.getResultData();
+ SectionResultData section = rd.retrieveSectionByIndex(0);
+ boolean result = (Boolean) section.retrieveObject("Result");
+ assertEquals(expected, result);
+ } else
+ fail("Expected CompositeResult Returned Result Type " + cmdResult.getType());
+ }
+
+ public static void doGetUsingClientCache(final String regionPath, final String key, final boolean expectSuccess,
+ String user, String password) {
+ try {
+ Properties properties = new Properties();
+ properties.setProperty("security-username", user);
+ properties.setProperty("security-password", password);
+ RegionService regionService = instance.clientCache.createAuthenticatedView(properties);
+ Region region = regionService.getRegion(regionPath);
+ assertNotNull(region);
+ Object value = region.get(key);
+ logger.info("doGetUsingClientCache : Get key=" + key + " for user="+ user+" value="+ value + " expectSuccess="+expectSuccess);
+ assertNotNull(value);
+ if (!expectSuccess)
+ fail("Region Get was expected to fail");
+ } catch (Exception e) {
+ if (!expectSuccess) {
+ logger.info("expectSuccess=true => " + e.getMessage());
+ } else {
+ logger.error("Unexpected error", e);
+ fail("Unknown reason " + e.getMessage());
+ }
+ }
+ }
+
+ public void doGetUsingGfsh(final String regionPath, final String key, final boolean expectSuccess, String user,
+ String password) {
+ String command = "get --region=" + regionPath + " --key=" + key;
+ changeGfshUser(user, password);
+ CommandResult result = executeCommand(command);
+ if (expectSuccess) {
+ printCommandOutput(result);
+ validateGfshResult(result, expectSuccess);
+ }
+ else {
+ logger.info("Error line :" + this.commandError);
+ assertTrue(this.commandError.contains("Access Denied"));
+ this.commandError = null;
+ }
+ }
+
+ private void changeGfshUser(String user, String password) {
+ if (!this.userName.equals(user)) {
+ executeCommand("disconnect");
+ this.userName = user;
+ this.password = password;
+ defaultShellConnect();
+ }
+ }
+
+ public void doCommandUsingGfsh(String command, final boolean expectSuccess, String user, String password) {
+ changeGfshUser(user, password);
+ CommandResult result = executeCommand(command);
+ if (expectSuccess) {
+ assertNotNull(result);
+ printCommandOutput(result);
+ //assertFalse(result.getType().equals(ResultData.TYPE_ERROR));
+ }
+ else {
+ logger.info("Error line :" + this.commandError);
+ assertTrue(this.commandError.contains("Access Denied"));
+ this.commandError = null;
+ }
+ }
+
+ private static void printCommandOutput(CommandResult cmdResult) {
+ assertNotNull(cmdResult);
+ logger.info("Command Output : ");
+ StringBuilder sb = new StringBuilder();
+ cmdResult.resetToFirstLine();
+ while (cmdResult.hasNextLine()) {
+ sb.append(cmdResult.nextLine()).append(DataCommandRequest.NEW_LINE);
+ }
+ logger.info(sb.toString());
+ logger.info("");
+ }
+
+ private void doShowLogUsingJMX(boolean expectSuccess, String user, String password) {
+ Object[] endPoint = getJMXEndPoint();
+ String[] creds = new String[] { user, password };
+ try {
+ JMXConnector connector = _getGemfireMBeanServer((Integer) endPoint[1], creds);
+ MBeanServerConnection mbeanServer = connector.getMBeanServerConnection();
+ ObjectName memberON = (ObjectName)mbeanServer.invoke(MBeanJMXAdapter.getDistributedSystemName(), "fetchMemberObjectName",
+ new Object[]{"Manager"}, new String[]{String.class.getCanonicalName()});
+ String logs = (String) mbeanServer.invoke(memberON, "showLog", new Object[]{60}, new String[]{int.class.toString()});
+ logger.info("JMX Output :" + logs);
+ connector.close();
+ if(!expectSuccess)
+ fail("Expected Access Denied...");
+ } catch (InstanceNotFoundException e) {
+ logger.error("Unexpected Error", e);
+ fail("Unexpected Error " + e.getMessage());
+ } catch (MBeanException e) {
+ logger.error("Unexpected Error", e);
+ fail("Unexpected Error " + e.getMessage());
+ } catch (ReflectionException e) {
+ logger.error("Unexpected Error", e);
+ fail("Unexpected Error " + e.getMessage());
+ } catch (IOException e) {
+ logger.error("Unexpected Error", e);
+ fail("Unexpected Error " + e.getMessage());
+ } catch (SecurityException e) {
+ if(expectSuccess){
+ fail("Expected successful jmx execution");
+ } else {
+ //expected
+ }
+ }
+ }
+
+
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private JMXConnector _getGemfireMBeanServer(int port, Object creds) {
+ JMXServiceURL url;
+ try {
+ url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:" + port + "/jmxrmi");
+ if (creds != null) {
+ Map env = new HashMap();
+ env.put(JMXConnector.CREDENTIALS, creds);
+ JMXConnector jmxc = JMXConnectorFactory.connect(url, env);
+ return jmxc;
+ } else {
+ JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
+ return jmxc;
+ }
+ } catch (MalformedURLException e) {
+ fail("Error connecting to port=" + port + " " + e.getMessage());
+ } catch (IOException e) {
+ fail("Error connecting to port=" + port + " " + e.getMessage());
+ }
+ return null;
+ }
+
+ public void testDataCommandsFromDifferentClients() throws IOException {
+ final Host host = Host.getHost(0);
+ final VM clientVM = host.getVM(2);
+
+ setup("testDataCommandsFromDifferentClients");
+ executeCommand("list members");
+ changeGfshUser("dataRead", "password123");
+ executeCommand("list members");
+
+ // check tushark can execute get/put/delete/execute function/query operation from cacheclient and through
+ // data-commands
+ String region = "serverRegion";
+ clientVM.invoke(IntegratedSecDUnitTest.class, "doPutUsingClientCache", new Object[] { region, "myk1", "myv1", true,
+ "tushark", "password123" });
+ doGetUsingGfsh(region, "myk1", true, "tushark", "password123");
+ doPutUsingGfsh(region, "myk2", "myv2", true, "tushark", "password123");
+ clientVM.invoke(IntegratedSecDUnitTest.class, "doGetUsingClientCache", new Object[] { region, "myk2", true,
+ "tushark", "password123" });
+ revokeCacheOp("tushark", "PUT");
+ clientVM.invoke(IntegratedSecDUnitTest.class, "doPutUsingClientCache", new Object[] { region, "myk1", "myv1",
+ false, "tushark", "password123" });
+ doPutUsingGfsh(region, "myk2", "myv2", false, "tushark", "password123");
+ grantCacheOp("tushark", "PUT");
+ clientVM.invoke(IntegratedSecDUnitTest.class, "doPutUsingClientCache", new Object[] { region, "myk1", "myv1", true,
+ "tushark", "password123" });
+ doPutUsingGfsh(region, "myk2", "myv2", true, "tushark", "password123");
+
+
+ //dataRead Role
+ clientVM.invoke(IntegratedSecDUnitTest.class, "doPutUsingClientCache", new Object[] { region, "myk1", "myv1", false,
+ "dataRead", "password123" });
+ doPutUsingGfsh(region, "myk2", "myv2", false, "dataRead", "password123");
+ doGetUsingGfsh(region, "myk1", true, "dataRead", "password123");
+ clientVM.invoke(IntegratedSecDUnitTest.class, "doGetUsingClientCache", new Object[] { region, "myk2", true,
+ "dataRead", "password123" });
+
+ //dataWrite Role
+ clientVM.invoke(IntegratedSecDUnitTest.class, "doPutUsingClientCache", new Object[] { region, "myk1", "myv1", true,
+ "dataWrite", "password123" });
+ doPutUsingGfsh(region, "myk2", "myv2", true, "dataWrite", "password123");
+ doGetUsingGfsh(region, "myk1", true, "dataWrite", "password123");
+ clientVM.invoke(IntegratedSecDUnitTest.class, "doGetUsingClientCache", new Object[] { region, "myk2", true,
+ "dataWrite", "password123" });
+
+
+
+ //admin and monitor and custom roles can not execute get-put commands
+ clientVM.invoke(IntegratedSecDUnitTest.class, "doPutUsingClientCache", new Object[] { region, "myk1", "myv1", false,
+ "admin", "password123" });
+ doPutUsingGfsh(region, "myk2", "myv2", false, "admin", "password123");
+ doGetUsingGfsh(region, "myk1", false, "admin", "password123");
+ clientVM.invoke(IntegratedSecDUnitTest.class, "doGetUsingClientCache", new Object[] { region, "myk2", false,
+ "admin", "password123" });
+
+ clientVM.invoke(IntegratedSecDUnitTest.class, "doPutUsingClientCache", new Object[] { region, "myk1", "myv1", false,
+ "monitor", "password123" });
+ doPutUsingGfsh(region, "myk2", "myv2", false, "monitor", "password123");
+ doGetUsingGfsh(region, "myk1", false, "monitor", "password123");
+ clientVM.invoke(IntegratedSecDUnitTest.class, "doGetUsingClientCache", new Object[] { region, "myk2", false,
+ "monitor", "password123" });
+
+ clientVM.invoke(IntegratedSecDUnitTest.class, "doPutUsingClientCache", new Object[] { region, "myk1", "myv1", false,
+ "custom", "password123" });
+ doPutUsingGfsh(region, "myk2", "myv2", false, "custom", "password123");
+ doGetUsingGfsh(region, "myk1", false, "custom", "password123");
+ clientVM.invoke(IntegratedSecDUnitTest.class, "doGetUsingClientCache", new Object[] { region, "myk2", false,
+ "custom", "password123" });
+
+ // tushark can execute monitor command but not region create
+ doCommandUsingGfsh("show metrics", true, "monitor", "password123");
+ doCommandUsingGfsh("show dead-locks --file=deadlocks_monitor.txt", true, "monitor", "password123");
+
+ // dataWrite can execute create region
+ doCommandUsingGfsh("create region --type=REPLICATE --name=dataWriteRegion", true, "dataWrite", "password123");
+ doCommandUsingGfsh("create region --type=REPLICATE --name=dataReadRegion", false, "dataRead", "password123");
+
+ // custom can create region create but not put region
+ doCommandUsingGfsh("create region --type=REPLICATE --name=customRegion", true, "custom", "password123");
+ doPutUsingGfsh("customRegion", "key", "value", false, "custom", "password123");
+
+ // custom can execute show deadlocks - revoke it check again
+ doCommandUsingGfsh("show metrics", false, "custom", "password123");
+ doCommandUsingGfsh("show dead-locks --file=deadlocks_custom_1.txt", true, "custom", "password123");
+ revokeResourceOp("custom", ResourceOperationCode.SHOW_DEADLOCKS.toString());
+ grantResourceOp("custom", ResourceOperationCode.SHOW_METRICS.toString());
+ doCommandUsingGfsh("show metrics", true, "custom", "password123");
+ doCommandUsingGfsh("show dead-locks --file=deadlocks_custom_2.txt", false, "custom", "password123");
+ grantResourceOp("custom", ResourceOperationCode.SHOW_DEADLOCKS.toString());
+ doCommandUsingGfsh("show metrics", true, "custom", "password123");
+ doCommandUsingGfsh("show dead-locks --file=deadlocks_custom_3.txt", true, "custom", "password123");
+
+ /* Commented due to error with gradle but was working with ant build earlier
+ Error string is : TailLogRequest/Response processed in application vm with shared logging
+ //check jmx and gfsh
+ doCommandUsingGfsh("show log --member=Manager", true, "monitor", "password123");
+ doCommandUsingGfsh("show log --member=Manager", false, "dataWrite", "password123");
+ doCommandUsingGfsh("show log --member=Manager", false, "custom", "password123");
+
+
+ doShowLogUsingJMX(true, "monitor", "password123");
+ doShowLogUsingJMX(false, "dataWrite", "password123");
+ doShowLogUsingJMX(false, "custom", "password123");
+
+
+ grantResourceOp("custom", ResourceOperationCode.SHOW_LOG.toString());
+ doCommandUsingGfsh("show log --member=Manager", true, "custom", "password123");
+ doShowLogUsingJMX(true, "custom", "password123");*/
+ }
-
-
-
- public void tearDown2() throws Exception {
- super.tearDown2();
- }
-
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c39f8a5f/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/OperationCodesForDataCommandsIntegrationTest.java
----------------------------------------------------------------------
diff --cc gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/OperationCodesForDataCommandsIntegrationTest.java
index 0000000,b8c1c9d..bda4642
mode 000000,100755..100755
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/OperationCodesForDataCommandsIntegrationTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/OperationCodesForDataCommandsIntegrationTest.java
@@@ -1,0 -1,101 +1,101 @@@
+ /*
+ * 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 com.gemstone.gemfire.management.internal.security;
+
+ import static org.assertj.core.api.Assertions.assertThat;
+
+ import java.io.IOException;
+ import java.util.HashMap;
+ import java.util.Map;
+ import java.util.Properties;
+
+ import org.junit.After;
+ import org.junit.Before;
+ import org.junit.Rule;
+ import org.junit.Test;
+ import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+ import org.junit.experimental.categories.Category;
+ import org.junit.rules.TestName;
+
+ import com.gemstone.gemfire.cache.CacheFactory;
+ import com.gemstone.gemfire.distributed.DistributedSystem;
+ import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+ import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+ import com.gemstone.gemfire.management.internal.security.ResourceOperationContext.ResourceOperationCode;
+ import com.gemstone.gemfire.management.internal.security.AuthorizeOperationForMBeansIntegrationTest.TestAccessControl;
+ import com.gemstone.gemfire.management.internal.security.AuthorizeOperationForMBeansIntegrationTest.TestAuthenticator;
+ import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
+
+ /**
+ * Tests operation codes for data commands.
+ */
+ @Category(IntegrationTest.class)
+ @SuppressWarnings("deprecation")
+ public class OperationCodesForDataCommandsIntegrationTest {
+
+ private GemFireCacheImpl cache;
+ private DistributedSystem ds;
+ private Map<String, ResourceOperationCode> commands = new HashMap<String, ResourceOperationCode>();
+
+ @Rule
+ public TestName testName = new TestName();
+
+ @Rule
+ public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
+
+ @Before
+ public void setUp() {
+ System.setProperty("resource-auth-accessor", TestAccessControl.class.getName());
+ System.setProperty("resource-authenticator", TestAuthenticator.class.getName());
+
+ Properties properties = new Properties();
+ properties.put("name", testName.getMethodName());
+ properties.put(DistributionConfig.LOCATORS_NAME, "");
+ properties.put(DistributionConfig.MCAST_PORT_NAME, "0");
+ properties.put(DistributionConfig.HTTP_SERVICE_PORT_NAME, "0");
+
+ this.ds = DistributedSystem.connect(properties);
+ this.cache = (GemFireCacheImpl) CacheFactory.create(ds);
+
- this.commands.put("put --key=k1 --value=v1 --region=/region1", ResourceOperationCode.PUT_REGION);
- this.commands.put("locate entry --key=k1 --region=/region1", ResourceOperationCode.LOCATE_ENTRY_REGION);
- this.commands.put("query --query=\"select * from /region1\"", ResourceOperationCode.QUERYDATA_DS);
- this.commands.put("export data --region=value --file=value --member=value", ResourceOperationCode.EXPORT_DATA_REGION);
- this.commands.put("import data --region=value --file=value --member=value", ResourceOperationCode.IMPORT_DATA_REGION);
- this.commands.put("rebalance", ResourceOperationCode.REBALANCE_DS);
++ this.commands.put("put --key=k1 --value=v1 --region=/region1", ResourceOperationCode.PUT);
++ this.commands.put("locate entry --key=k1 --region=/region1", ResourceOperationCode.LOCATE_ENTRY);
++ this.commands.put("query --query=\"select * from /region1\"", ResourceOperationCode.QUERY);
++ this.commands.put("export data --region=value --file=value --member=value", ResourceOperationCode.EXPORT_DATA);
++ this.commands.put("import data --region=value --file=value --member=value", ResourceOperationCode.IMPORT_DATA);
++ this.commands.put("rebalance", ResourceOperationCode.REBALANCE);
+ }
+
+ @After
+ public void tearDown() throws IOException {
+ if (this.cache != null) {
+ this.cache.close();
+ this.cache = null;
+ }
+ if (this.ds != null) {
+ this.ds.disconnect();
+ this.ds = null;
+ }
+ }
+
+ @Test
+ public void commandsShouldMapToCorrectResourceCodes() throws Exception {
+ for (String command : this.commands.keySet()) {
+ CLIOperationContext ctx = new CLIOperationContext(command);
+ assertThat(ctx.getResourceOperationCode()).isEqualTo(this.commands.get(command));
+ }
+ }
+ }
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c39f8a5f/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/OperationCodesForDistributedSystemMXBeanTest.java
----------------------------------------------------------------------
diff --cc gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/OperationCodesForDistributedSystemMXBeanTest.java
index 0000000,8b7edbf..65fcf56
mode 000000,100755..100755
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/OperationCodesForDistributedSystemMXBeanTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/OperationCodesForDistributedSystemMXBeanTest.java
@@@ -1,0 -1,76 +1,76 @@@
+ /*
+ * 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 com.gemstone.gemfire.management.internal.security;
+
+ import static org.assertj.core.api.Assertions.assertThat;
+
+ import javax.management.ObjectName;
+
+ import org.junit.Test;
+ import org.junit.experimental.categories.Category;
+
+ import com.gemstone.gemfire.cache.operations.OperationContext.OperationCode;
+ import com.gemstone.gemfire.management.internal.MBeanJMXAdapter;
+ import com.gemstone.gemfire.management.internal.security.ResourceOperationContext.ResourceOperationCode;
+ import com.gemstone.gemfire.test.junit.categories.UnitTest;
+
+ /**
+ * Tests operation codes for DistributedSystemMXBean operations.
+ */
+ @Category(UnitTest.class)
+ public class OperationCodesForDistributedSystemMXBeanTest {
+
+ private final String[] distributedSystemMXBeanOperations = {
+ "listCacheServerObjectNames",
+ "viewRemoteClusterStatus",
+ "getTotalHeapSize",
+ "setQueryCollectionsDepth",
+ "getQueryCollectionsDepth",
+ "changeAlertLevel",
+ "backupAllMembers",
+ "revokeMissingDiskStores",
+ "shutDownAllMembers",
+ "queryData",
+ "queryDataForCompressedResult",
+ "setQueryResultSetLimit"
+ };
+
+ private final ResourceOperationCode[] distributedSystemResourceOperationCodes = {
+ ResourceOperationCode.LIST_DS,
+ ResourceOperationCode.LIST_DS,
- ResourceOperationCode.READ_DS,
- ResourceOperationCode.QUERYDATA_DS,
- ResourceOperationCode.READ_DS,
- ResourceOperationCode.CHANGE_ALERT_LEVEL_DS,
- ResourceOperationCode.BACKUP_DS,
- ResourceOperationCode.REMOVE_DISKSTORE_DS,
- ResourceOperationCode.SHUTDOWN_DS,
- ResourceOperationCode.QUERYDATA_DS,
- ResourceOperationCode.QUERYDATA_DS,
- ResourceOperationCode.QUERYDATA_DS
++ ResourceOperationCode.GET,
++ ResourceOperationCode.QUERY,
++ ResourceOperationCode.GET,
++ ResourceOperationCode.CHANGE_ALERT_LEVEL,
++ ResourceOperationCode.BACKUP_MEMBERS,
++ ResourceOperationCode.REVOKE_MISSING_DISKSTORE,
++ ResourceOperationCode.SHUTDOWN,
++ ResourceOperationCode.QUERY,
++ ResourceOperationCode.QUERY,
++ ResourceOperationCode.QUERY
+ };
+
+ @Test
+ public void operationsShouldMapToCodes() {
+ ObjectName objectName = MBeanJMXAdapter.getDistributedSystemName();
+ for (int i = 0; i < distributedSystemMXBeanOperations.length; i++) {
+ JMXOperationContext context = new JMXOperationContext(objectName, distributedSystemMXBeanOperations[i]);
+ assertThat(context.getResourceOperationCode()).isEqualTo(distributedSystemResourceOperationCodes[i]);
+ assertThat(context.getOperationCode()).isEqualTo(OperationCode.RESOURCE);
+ }
+ }
+ }
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c39f8a5f/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/RESTAdminAPISecurityDUnitTest.java
----------------------------------------------------------------------
diff --cc gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/RESTAdminAPISecurityDUnitTest.java
index 5481ff7,0000000..cd7b4c9
mode 100644,000000..100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/RESTAdminAPISecurityDUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/RESTAdminAPISecurityDUnitTest.java
@@@ -1,26 -1,0 +1,22 @@@
+package com.gemstone.gemfire.management.internal.security;
+
- import dunit.Host;
- import dunit.SerializableCallable;
-
+public class RESTAdminAPISecurityDUnitTest extends CLISecurityDUnitTest {
+
+ private static final long serialVersionUID = 1L;
+
+ public RESTAdminAPISecurityDUnitTest(String name) {
+ super(name);
+ }
+
+ public void setUp() throws Exception {
+ super.setUp();
+ this.setUseHttpOnConnect(true);
+ }
+
+
+ @Override
- public void tearDown2() throws Exception {
- super.tearDown2();
++ public void preTearDownCacheTestCase() throws Exception {
+ this.setUseHttpOnConnect(false);
+ }
+
+}