blob: 4d8d0e6f454777669d70508da7215069bd5fb88a [file] [log] [blame]
/*
* 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.geode.cache30;
import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
import static org.apache.geode.test.dunit.Assert.assertFalse;
import static org.apache.geode.test.dunit.Assert.assertNotNull;
import static org.apache.geode.test.dunit.Assert.fail;
import java.io.IOException;
import java.util.Iterator;
import java.util.Properties;
import org.apache.geode.cache.AttributesFactory;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.Declarable;
import org.apache.geode.cache.LoaderHelper;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionAttributes;
import org.apache.geode.cache.Scope;
import org.apache.geode.cache.client.Pool;
import org.apache.geode.cache.client.PoolFactory;
import org.apache.geode.cache.client.PoolManager;
import org.apache.geode.cache.server.CacheServer;
import org.apache.geode.distributed.DistributedMember;
import org.apache.geode.internal.AvailablePortHelper;
import org.apache.geode.test.dunit.DistributedTestUtils;
import org.apache.geode.test.dunit.VM;
import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase;
/**
* Provides helper methods for testing clients and servers. This test case was created by
* refactoring methods from ConnectionPoolDUnitTest into this class.
*
* @since GemFire 4.2.1
*/
public abstract class ClientServerTestCase extends JUnit4CacheTestCase {
public static String NON_EXISTENT_KEY = "NON_EXISTENT_KEY";
public static boolean AUTO_LOAD_BALANCE = false;
@Override
public final void postSetUp() throws Exception {
// this makes sure we don't have any connection left over from previous tests
disconnectAllFromDS();
postSetUpClientServerTestCase();
}
protected void postSetUpClientServerTestCase() throws Exception {}
@Override
public final void preTearDownCacheTestCase() throws Exception {
preTearDownClientServerTestCase();
// this makes sure we don't leave anything for the next tests
disconnectAllFromDS();
}
protected void preTearDownClientServerTestCase() throws Exception {}
/**
* Starts a cache server on the given port
*
* @since GemFire 4.0
*/
public int startBridgeServer(int port) throws IOException {
Cache cache = getCache();
CacheServer bridge = cache.addCacheServer();
bridge.setPort(port);
bridge.setMaxThreads(getMaxThreads());
bridge.start();
return bridge.getPort();
}
/**
* Defaults to 0 which means no selector in server. Subclasses can override setting this to a
* value > 0 to enable selector.
*/
protected int getMaxThreads() {
return 0;
}
/**
* Stops the cache server that serves up the given cache.
*
* @since GemFire 4.0
*/
public void stopBridgeServers(Cache cache) {
CacheServer bridge = null;
for (Iterator bsI = cache.getCacheServers().iterator(); bsI.hasNext();) {
bridge = (CacheServer) bsI.next();
bridge.stop();
assertFalse(bridge.isRunning());
}
}
/**
* Returns region attributes for a <code>LOCAL</code> region
*/
protected RegionAttributes getRegionAttributes() {
AttributesFactory factory = new AttributesFactory();
factory.setScope(Scope.LOCAL);
return factory.create();
}
public static Pool configureConnectionPool(AttributesFactory factory, String host, int port1,
int port2, boolean establish, int redundancy, int connectionsPerServer, String serverGroup,
int pingInterval, int idleTimeout, int lifetimeTimeout) {
int[] ports;
if (port2 != -1) {
ports = new int[] {port1, port2};
} else {
ports = new int[] {port1};
}
return configureConnectionPool(factory, host, ports, establish, redundancy,
connectionsPerServer, serverGroup, pingInterval, idleTimeout, lifetimeTimeout);
}
public static Pool configureConnectionPool(AttributesFactory factory, String host, int port1,
int port2, boolean establish, int redundancy, int connectionsPerServer, String serverGroup,
int pingInterval, int idleTimeout) {
return configureConnectionPool(factory, host, port1, port2, establish, redundancy,
connectionsPerServer, serverGroup, pingInterval, idleTimeout,
-2/* lifetimeTimeout */);
}
public static Pool configureConnectionPool(AttributesFactory factory, String host, int port1,
int port2, boolean establish, int redundancy, int connectionsPerServer, String serverGroup,
int pingInterval) {
return configureConnectionPool(factory, host, port1, port2, establish, redundancy,
connectionsPerServer, serverGroup, pingInterval, -1);
}
public static Pool configureConnectionPool(AttributesFactory factory, String host, int port1,
int port2, boolean establish, int redundancy, int connectionsPerServer, String serverGroup) {
return configureConnectionPool(factory, host, port1, port2, establish, redundancy,
connectionsPerServer, serverGroup, -1/* pingInterval */);
}
public static Pool configureConnectionPoolWithName(AttributesFactory factory, String host,
int[] ports, boolean establish, int redundancy, int connectionsPerServer, String serverGroup,
String poolName) {
return configureConnectionPoolWithNameAndFactory(factory, host, ports, establish, redundancy,
connectionsPerServer, serverGroup, poolName, PoolManager.createFactory(), -1, -1, -2,
-1);
}
public static Pool configureConnectionPoolWithName(AttributesFactory factory, String host,
int[] ports, boolean establish, int redundancy, int connectionsPerServer, String serverGroup,
String poolName, int pingInterval, int idleTimeout,
int lifetimeTimeout, int statisticInterval) {
return configureConnectionPoolWithNameAndFactory(factory, host, ports, establish, redundancy,
connectionsPerServer, serverGroup, poolName, PoolManager.createFactory(), pingInterval,
idleTimeout, lifetimeTimeout, statisticInterval);
}
public static Pool configureConnectionPoolWithNameAndFactory(AttributesFactory factory,
String host, int[] ports, boolean establish, int redundancy, int connectionsPerServer,
String serverGroup, String poolName, PoolFactory pf) {
return configureConnectionPoolWithNameAndFactory(factory, host, ports, establish, redundancy,
connectionsPerServer, serverGroup, poolName, pf, -1, -1, -2, -1);
}
/**
* this method creates a client connection pool and configures it. If the ports array is not empty
* it is used to configure the client pool. Otherwise the pool is configured to use the dunit
* locator.
*/
public static Pool configureConnectionPoolWithNameAndFactory(AttributesFactory factory,
String host, int[] ports, boolean establish, int redundancy, int connectionsPerServer,
String serverGroup, String poolName, PoolFactory pf, int pingInterval, int idleTimeout,
int lifetimeTimeout, int statisticInterval) {
if (AUTO_LOAD_BALANCE || ports.length == 0) {
pf.addLocator(host, DistributedTestUtils.getDUnitLocatorPort());
} else {
for (int z = 0; z < ports.length; z++) {
pf.addServer(host, ports[z]);
}
}
// TODO - probably should pass in minConnections rather than connecions per server
if (connectionsPerServer != -1 && ports != null) {
pf.setMinConnections(connectionsPerServer * ports.length);
}
if (pingInterval != -1) {
pf.setPingInterval(pingInterval);
}
if (idleTimeout != -1) {
pf.setIdleTimeout(idleTimeout);
}
if (statisticInterval != -1) {
pf.setStatisticInterval(statisticInterval);
}
if (lifetimeTimeout != -2) {
pf.setLoadConditioningInterval(lifetimeTimeout);
}
if (establish) {
pf.setSubscriptionEnabled(true);
pf.setSubscriptionRedundancy(redundancy);
pf.setSubscriptionAckInterval(1);
}
if (serverGroup != null) {
pf.setServerGroup(serverGroup);
}
String rpoolName = "testPool";
if (poolName != null) {
rpoolName = poolName;
}
Pool pool = pf.create(rpoolName);
if (factory != null) {
factory.setPoolName(rpoolName);
}
return pool;
}
public static Pool configureConnectionPool(AttributesFactory factory, String host, int[] ports,
boolean establish, int redundancy, int connectionsPerServer, String serverGroup) {
return configureConnectionPool(factory, host, ports, establish, redundancy,
connectionsPerServer, serverGroup, -1/* pingInterval */, -1/* idleTimeout */,
-2/* lifetimeTimeout */);
}
public static Pool configureConnectionPool(AttributesFactory factory, String host, int[] ports,
boolean establish, int redundancy, int connectionsPerServer, String serverGroup,
int pingInterval, int idleTimeout, int lifetimeTimeout) {
return configureConnectionPoolWithName(factory, host, ports, establish, redundancy,
connectionsPerServer, serverGroup, null/* poolName */, pingInterval, idleTimeout,
lifetimeTimeout, -1);
}
public static Pool configureConnectionPool(AttributesFactory factory, String host, int[] ports,
boolean establish, int redundancy, int connectionsPerServer, String serverGroup,
int pingInterval, int idleTimeout, int lifetimeTimeout, int statisticInterval) {
return configureConnectionPoolWithName(factory, host, ports, establish, redundancy,
connectionsPerServer, serverGroup, null/* poolName */, pingInterval, idleTimeout,
lifetimeTimeout, statisticInterval);
}
protected static DistributedMember getMemberId() {
await("Waiting for client to connect " + getSystemStatic().getMemberId())
.until(() -> getSystemStatic().getDistributedMember().getPort() > 0);
return getSystemStatic().getDistributedMember();
}
public static class CacheServerCacheLoader extends TestCacheLoader implements Declarable {
public CacheServerCacheLoader() {}
@Override
public Object load2(LoaderHelper helper) {
if (helper.getArgument() instanceof Integer) {
try {
Thread.sleep(((Integer) helper.getArgument()).intValue());
} catch (InterruptedException ugh) {
fail("interrupted");
}
}
Object ret = helper.getKey();
if (ret instanceof String) {
if (ret != null && ret.equals(NON_EXISTENT_KEY))
return null;// return null
}
return ret;
}
@Override
public void init(Properties props) {}
}
public static final String BridgeServerKey = "BridgeServerKey";
/**
* Create a server that has a value for every key queried and a unique key/value in the specified
* Region that uniquely identifies each instance.
*
* @param vm the VM on which to create the server
* @param rName the name of the Region to create on the server
* @param port the TCP port on which the server should listen
*/
public void createBridgeServer(VM vm, final String rName, final int port) {
vm.invoke(new CacheSerializableRunnable("Create Region on Server") {
@Override
public void run2() {
try {
AttributesFactory factory = new AttributesFactory();
factory.setScope(Scope.DISTRIBUTED_ACK); // can't be local since used with
// registerInterest
factory.setCacheLoader(new CacheServerCacheLoader());
beginCacheXml();
createRootRegion(rName, factory.create());
startBridgeServer(port);
finishCacheXml(rName + "-" + port);
Region region = getRootRegion(rName);
assertNotNull(region);
region.put(BridgeServerKey, new Integer(port)); // A unique key/value to identify the
// BridgeServer
} catch (Exception e) {
getSystem().getLogWriter().severe(e);
fail("Failed to start CacheServer " + e);
}
}
});
}
public static int[] createUniquePorts(int numToCreate) {
return AvailablePortHelper.getRandomAvailableTCPPorts(numToCreate);
}
}