Skip to content

Commit

Permalink
JBQA-12631 - Create tests for Remote Script Execution
Browse files Browse the repository at this point in the history
  • Loading branch information
andyuk1986 authored and Sebastian Laskawiec committed Feb 29, 2016
1 parent 681be28 commit 2aa4676
Show file tree
Hide file tree
Showing 25 changed files with 1,164 additions and 242 deletions.
Expand Up @@ -40,7 +40,7 @@ protected EmbeddedCacheManager createCacheManager() throws Exception {
return cacheManager; return cacheManager;
} }


private ConfigurationBuilder initServerAndClient() { protected ConfigurationBuilder initServerAndClient() {
hotrodServer = new HotRodServer(); hotrodServer = new HotRodServer();
HotRodServerConfigurationBuilder serverBuilder = HotRodTestingUtil.getDefaultHotRodConfiguration(); HotRodServerConfigurationBuilder serverBuilder = HotRodTestingUtil.getDefaultHotRodConfiguration();
SimpleServerAuthenticationProvider sap = new SimpleServerAuthenticationProvider(); SimpleServerAuthenticationProvider sap = new SimpleServerAuthenticationProvider();
Expand Down
Expand Up @@ -7,19 +7,28 @@
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.Serializable;
import java.nio.Buffer; import java.nio.Buffer;
import java.nio.CharBuffer; import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;


import org.infinispan.client.hotrod.exceptions.HotRodClientException;
import org.infinispan.client.hotrod.test.MultiHotRodServersTest; import org.infinispan.client.hotrod.test.MultiHotRodServersTest;
import org.infinispan.commons.CacheException;
import org.infinispan.commons.api.BasicCache; import org.infinispan.commons.api.BasicCache;
import org.infinispan.commons.equivalence.AnyServerEquivalence; import org.infinispan.commons.equivalence.AnyServerEquivalence;
import org.infinispan.commons.marshall.jboss.GenericJBossMarshaller; import org.infinispan.commons.marshall.jboss.GenericJBossMarshaller;
import org.infinispan.configuration.cache.CacheMode; import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.cache.ConfigurationBuilder; import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.scripting.ScriptingManager; import org.infinispan.scripting.ScriptingManager;
import org.infinispan.stream.CacheCollectors;
import org.infinispan.test.TestingUtil; import org.infinispan.test.TestingUtil;
import org.testng.annotations.Test; import org.testng.annotations.Test;


Expand All @@ -41,6 +50,11 @@ protected void createCacheManagers() throws Throwable {
createHotRodServers(NUM_SERVERS, new ConfigurationBuilder()); createHotRodServers(NUM_SERVERS, new ConfigurationBuilder());
} }


@Test(expectedExceptions = HotRodClientException.class, expectedExceptionsMessageRegExp = ".*Unknown task 'nonExistent\\.js'.*")
public void testRemovingNonExistentScript() {
clients.get(0).getCache().execute("nonExistent.js", new HashMap<>());
}

public void testEmbeddedScriptRemoteExecution() throws IOException { public void testEmbeddedScriptRemoteExecution() throws IOException {
String cacheName = "testEmbeddedScriptRemoteExecution"; String cacheName = "testEmbeddedScriptRemoteExecution";
ConfigurationBuilder builder = getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, true); ConfigurationBuilder builder = getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, true);
Expand Down Expand Up @@ -98,11 +112,69 @@ public void testRemoteMapReduce() throws Exception {
loadScript(scriptCache, "/wordCountMapper.js"); loadScript(scriptCache, "/wordCountMapper.js");
loadScript(scriptCache, "/wordCountReducer.js"); loadScript(scriptCache, "/wordCountReducer.js");
loadScript(scriptCache, "/wordCountCollator.js"); loadScript(scriptCache, "/wordCountCollator.js");
LinkedHashMap<String, Double> results = cache.execute("wordCountMapper.js", new HashMap<String, String>()); Map<String, Double> results = cache.execute("wordCountMapper.js", new HashMap<String, String>());
assertEquals(20, results.size()); assertEquals(20, results.size());
assertTrue(results.get("macbeth").equals(Double.valueOf(287))); assertTrue(results.get("macbeth").equals(Double.valueOf(287)));
} }


public void testRemoteMapReduceWithStreams() throws Exception {
String cacheName = "testRemoteMapReduce_Streams";
ConfigurationBuilder builder = getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, true);
builder.dataContainer().keyEquivalence(new AnyServerEquivalence()).valueEquivalence(new AnyServerEquivalence()).compatibility().enable().marshaller(new GenericJBossMarshaller());
defineInAll(cacheName, builder);
RemoteCache<String, String> cache = clients.get(0).getCache(cacheName);
RemoteCache<String, String> scriptCache = clients.get(0).getCache(SCRIPT_CACHE);
loadData(cache, "/macbeth.txt");
loadScript(scriptCache, "/wordCountStream.js");

Map<String, Long> results = cache.execute("wordCountStream.js", new HashMap<String, String>());
assertEquals(3209, results.size());
assertTrue(results.get("macbeth").equals(Long.valueOf(287)));
}

public void testRemoteMapReduceWithStreams_DistributedMode() throws Exception {
String cacheName = "testRemoteMapReduce_Streams_dist";
ConfigurationBuilder builder = getDefaultClusteredCacheConfig(CacheMode.REPL_SYNC, true);
builder.dataContainer().keyEquivalence(new AnyServerEquivalence()).valueEquivalence(new AnyServerEquivalence())
.compatibility().enable().marshaller(new GenericJBossMarshaller());
defineInAll(cacheName, builder);
waitForClusterToForm(cacheName);

RemoteCache<String, String> cache = clients.get(0).getCache(cacheName);
RemoteCache<String, String> scriptCache = clients.get(1).getCache(SCRIPT_CACHE);
loadData(cache, "/macbeth.txt");
loadScript(scriptCache, "/wordCountStream_dist.js");

ArrayList<Map<String, Long>> results = cache.execute("wordCountStream_dist.js", new HashMap<String, String>());
assertEquals(2, results.size());
assertEquals(3209, results.get(0).size());
assertEquals(3209, results.get(1).size());
assertTrue(results.get(0).get("macbeth").equals(Long.valueOf(287)));
assertTrue(results.get(1).get("macbeth").equals(Long.valueOf(287)));
}

@Test(enabled = false, description = "Disabling this test until the distributed scripts in DIST mode are fixed - ISPN-6173")
public void testRemoteMapReduceWithStreams_DistributedMode1() throws Exception {
String cacheName = "testRemoteMapReduce_Streams_dist1";
ConfigurationBuilder builder = getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, true);
builder.dataContainer().keyEquivalence(new AnyServerEquivalence()).valueEquivalence(new AnyServerEquivalence())
.compatibility().enable().marshaller(new GenericJBossMarshaller());
defineInAll(cacheName, builder);
waitForClusterToForm(cacheName);

RemoteCache<String, String> cache = clients.get(1).getCache(cacheName);
RemoteCache<String, String> scriptCache = clients.get(1).getCache(SCRIPT_CACHE);
loadData(cache, "/macbeth.txt");
loadScript(scriptCache, "/wordCountStream_dist.js");
waitForClusterToForm();

ArrayList<Map<String, Long>> results = cache.execute("wordCountStream_dist.js", new HashMap<String, String>());
assertEquals(2, results.size());
assertEquals(3209, results.get(0).size());
assertEquals(3209, results.get(1).size());
assertTrue(results.get(0).get("macbeth").equals(Long.valueOf(287)));
}

private void loadData(BasicCache<String, String> cache, String fileName) throws IOException { private void loadData(BasicCache<String, String> cache, String fileName) throws IOException {
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(this.getClass().getResourceAsStream(fileName)))) { try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(this.getClass().getResourceAsStream(fileName)))) {
int chunkSize = 10; int chunkSize = 10;
Expand Down
@@ -0,0 +1,159 @@
package org.infinispan.client.hotrod;

import org.infinispan.client.hotrod.configuration.Configuration;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.configuration.global.GlobalAuthorizationConfigurationBuilder;
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.scripting.ScriptingManager;
import org.infinispan.scripting.impl.ScriptingManagerImpl;
import org.infinispan.security.AuthorizationPermission;
import org.infinispan.security.Security;
import org.infinispan.security.impl.IdentityRoleMapper;
import org.infinispan.server.hotrod.test.TestCallbackHandler;
import org.infinispan.test.TestingUtil;
import org.infinispan.test.fwk.CleanupAfterMethod;
import org.infinispan.test.fwk.TestCacheManagerFactory;
import org.junit.Ignore;
import org.testng.annotations.Test;

import javax.security.auth.Subject;
import java.io.IOException;
import java.io.InputStream;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.HashMap;
import java.util.Map;

import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
import static org.testng.AssertJUnit.assertEquals;

/**
* Tests verifying script execution over HotRod Client with enabled authentication.
*
* @author Anna Manukyan
*/
@Test(testName = "client.hotrod.SecureExecTest", groups = "functional")
@CleanupAfterMethod
public class SecureExecTest extends AuthenticationTest {
static final Subject ADMIN = TestingUtil.makeSubject("admin", ScriptingManagerImpl.SCRIPT_MANAGER_ROLE);
static final Subject RUNNER = TestingUtil.makeSubject("runner", "runner");
static final Subject PHEIDIPPIDES = TestingUtil.makeSubject("pheidippides", "pheidippides");

private RemoteCacheManager remoteCacheManager;

@Override
protected EmbeddedCacheManager createCacheManager() throws Exception {
GlobalConfigurationBuilder global = new GlobalConfigurationBuilder();
GlobalAuthorizationConfigurationBuilder globalRoles = global.security().authorization().enable().principalRoleMapper(new IdentityRoleMapper());
globalRoles
.role("runner")
.permission(AuthorizationPermission.EXEC)
.permission(AuthorizationPermission.READ)
.permission(AuthorizationPermission.WRITE)
.permission(AuthorizationPermission.ADMIN)
.role("pheidippides")
.permission(AuthorizationPermission.READ)
.permission(AuthorizationPermission.WRITE)
.permission(AuthorizationPermission.ADMIN)
.role("admin")
.permission(AuthorizationPermission.ALL);

ConfigurationBuilder config = TestCacheManagerFactory.getDefaultCacheConfiguration(true);
config.security().authorization().enable().role("runner").role("pheidippides").role("admin");
cacheManager = TestCacheManagerFactory.createCacheManager(global, hotRodCacheConfiguration());
cacheManager.getCache();

return cacheManager;
}

@Override
protected void setup() throws Exception {
Security.doAs(ADMIN, new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
SecureExecTest.super.setup();
return null;
}
});
}

@Override
protected void teardown() {
Security.doAs(ADMIN, new PrivilegedAction<Void>() {
@Override
public Void run() {
SecureExecTest.super.teardown();
return null;
}
});
}

@Override
protected void clearContent() {
Security.doAs(ADMIN, new PrivilegedAction<Void>() {
@Override
public Void run() {
cacheManager.getCache().clear();
return null;
}
});
}

protected org.infinispan.client.hotrod.configuration.ConfigurationBuilder initServerAndClient() {
return Security.doAs(ADMIN, new PrivilegedAction<org.infinispan.client.hotrod.configuration.ConfigurationBuilder>() {
@Override
public org.infinispan.client.hotrod.configuration.ConfigurationBuilder run() {
return SecureExecTest.super.initServerAndClient();
}
});
}

@Test(enabled = false, description = "Disabled until issue ISPN-6210 is fixed.")
public void testSimpleScriptExecutionWithValidAuth() throws IOException, PrivilegedActionException {
org.infinispan.client.hotrod.configuration.ConfigurationBuilder clientBuilder = initServerAndClient();
clientBuilder.security().authentication().callbackHandler(new TestCallbackHandler("user", "realm", "password".toCharArray()));

runTestWithGivenConfig(clientBuilder.build(), RUNNER);
}

@Test(enabled = false, description = "Disabled until issue ISPN-6210 is fixed.")
public void testSimpleScriptExecutionWithInValidAuth() throws IOException, PrivilegedActionException {
org.infinispan.client.hotrod.configuration.ConfigurationBuilder clientBuilder = initServerAndClient();
clientBuilder.security().authentication().callbackHandler(new TestCallbackHandler("user", "realm", "password".toCharArray()));

runTestWithGivenConfig(clientBuilder.build(), PHEIDIPPIDES);
}

private void runTestWithGivenConfig(Configuration config, Subject subject) throws IOException, PrivilegedActionException {
remoteCacheManager = new RemoteCacheManager(config);
Map<String, String> params = new HashMap<>();
params.put("a", "guinness");

Security.doAs(ADMIN, new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
ScriptingManager scriptingManager = hotrodServer.getCacheManager().getGlobalComponentRegistry().getComponent(ScriptingManager.class);

try (InputStream is = this.getClass().getResourceAsStream("/testRole.js")) {
String script = TestingUtil.loadFileAsString(is);
scriptingManager.addScript("testRole.js", script);
}

return null;
}
});

Security.doAs(subject, new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
Integer result = remoteCacheManager.getCache().execute("testRole.js", params);
assertEquals("guinness", remoteCacheManager.getCache().get("a"));

return null;
}
});
}

}

0 comments on commit 2aa4676

Please sign in to comment.