/*
* Copyright 2008-2012 LinkedIn, Inc
*
* Licensed 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 voldemort.client;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import voldemort.ServerTestUtils;
import voldemort.VoldemortException;
import voldemort.client.protocol.admin.AdminClient;
import voldemort.cluster.Cluster;
import voldemort.serialization.DefaultSerializerFactory;
import voldemort.serialization.Serializer;
import voldemort.serialization.SerializerFactory;
import voldemort.server.VoldemortServer;
import voldemort.store.socket.SocketStoreFactory;
import voldemort.store.socket.clientrequest.ClientRequestExecutorPool;
import voldemort.store.system.SystemStoreConstants;
import voldemort.utils.ByteArray;
import voldemort.utils.Pair;
import voldemort.versioning.Versioned;
import com.google.common.collect.Lists;
@SuppressWarnings({ "unchecked" })
public class ClientRegistryTest {
public static final String SERVER_LOCAL_URL = "tcp://localhost:";
public static final String TEST_STORE_NAME = "test-store-eventual-1";
public static final String TEST_STORE_NAME2 = "test-store-eventual-2";
public static final String STORES_XML_FILE = "test/common/voldemort/config/stores.xml";
public static final String CLIENT_CONTEXT_NAME = "testClientRegistryHappyPath";
public static final String CLIENT_CONTEXT_NAME2 = "testClientRegistryUnhappyPath";
public static final int CLIENT_REGISTRY_REFRESH_INTERVAL = 1;
public static final int TOTAL_SERVERS = 2;
private SocketStoreFactory socketStoreFactory = new ClientRequestExecutorPool(TOTAL_SERVERS,
10000,
100000,
32 * 1024);
private static VoldemortServer[] servers = null;
private static int[] serverPorts = null;
private Cluster cluster = null;
private static AdminClient adminClient;
private SerializerFactory serializerFactory = new DefaultSerializerFactory();
private Serializer<Object> valueSerializer = (Serializer<Object>) serializerFactory.getSerializer(SystemStoreConstants.getSystemStoreDef(SystemStoreConstants.SystemStoreName.voldsys$_client_registry.name())
.getValueSerializer());
private long startTime;
@Before
public void setUp() throws Exception {
if(cluster == null) {
servers = new VoldemortServer[TOTAL_SERVERS];
int partitionMap[][] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 } };
cluster = ServerTestUtils.startVoldemortCluster(TOTAL_SERVERS,
servers,
partitionMap,
socketStoreFactory,
true, // useNio
null,
STORES_XML_FILE,
new Properties());
serverPorts = new int[TOTAL_SERVERS];
for(int i = 0; i < TOTAL_SERVERS; i++) {
serverPorts[i] = servers[i].getIdentityNode().getSocketPort();
}
adminClient = ServerTestUtils.getAdminClient(cluster);
}
startTime = System.currentTimeMillis();
}
@After
public void tearDown() throws Exception {
this.clearRegistryContent();
for(VoldemortServer server: servers) {
ServerTestUtils.stopVoldemortServer(server);
}
}
/*
* Tests that the client registry is populated correctly and that we can
* query using Admin Tool.
*/
@Test
public void testHappyPath() {
List<Integer> emptyPartitionList = Lists.newArrayList();
ClientConfig clientConfig = new ClientConfig().setMaxThreads(4)
.setMaxConnectionsPerNode(4)
.setBootstrapUrls(SERVER_LOCAL_URL
+ serverPorts[0])
.setClientContextName(CLIENT_CONTEXT_NAME)
.enableDefaultClient(false)
.setClientRegistryUpdateIntervalInSecs(CLIENT_REGISTRY_REFRESH_INTERVAL)
.setEnableLazy(false);
SocketStoreClientFactory socketFactory = new SocketStoreClientFactory(clientConfig);
StoreClient<String, String> client1 = socketFactory.getStoreClient(TEST_STORE_NAME);
client1.put("k", "v");
Iterator<Pair<ByteArray, Versioned<byte[]>>> it = adminClient.bulkFetchOps.fetchEntries(0,
SystemStoreConstants.SystemStoreName.voldsys$_client_registry.name(),
emptyPartitionList,
null,
false);
ArrayList<ClientInfo> infoList = getClientRegistryContent(it);
assertEquals(TEST_STORE_NAME, infoList.get(0).getStoreName());
assertEquals(CLIENT_CONTEXT_NAME, infoList.get(0).getContext());
assertEquals(0, infoList.get(0).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(0).getBootstrapTime());
assertNotNull("Client version is null", infoList.get(0).getReleaseVersion());
assertEquals(1, infoList.size());
it = adminClient.bulkFetchOps.fetchEntries(1,
SystemStoreConstants.SystemStoreName.voldsys$_client_registry.name(),
emptyPartitionList,
null,
false);
infoList = getClientRegistryContent(it);
assertEquals(TEST_STORE_NAME, infoList.get(0).getStoreName());
assertEquals(CLIENT_CONTEXT_NAME, infoList.get(0).getContext());
assertEquals(0, infoList.get(0).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(0).getBootstrapTime());
assertNotNull("Client version is null", infoList.get(0).getReleaseVersion());
assertEquals(1, infoList.size());
try {
Thread.sleep(CLIENT_REGISTRY_REFRESH_INTERVAL * 1000 * 5);
} catch(InterruptedException e) {}
// now the periodical update has gone through, it shall be higher than
// the bootstrap time
it = adminClient.bulkFetchOps.fetchEntries(1,
SystemStoreConstants.SystemStoreName.voldsys$_client_registry.name(),
emptyPartitionList,
null,
false);
infoList = getClientRegistryContent(it);
assertTrue("Client registry not updated.",
infoList.get(0).getBootstrapTime() < infoList.get(0).getUpdateTime());
assertTrue("Client Config received from the Client registry system store is incorrect.",
isConfigEqual(infoList.get(0).getClientConfig(), clientConfig));
socketFactory.close();
}
/*
* Test happy path for 2 clients created by the same factory, pointing to
* the same store
*/
@Test
public void testTwoClients() {
List<Integer> emptyPartitionList = Lists.newArrayList();
ClientConfig clientConfig = new ClientConfig().setMaxThreads(4)
.setMaxTotalConnections(4)
.setMaxConnectionsPerNode(4)
.setBootstrapUrls(SERVER_LOCAL_URL
+ serverPorts[0])
.setClientContextName(CLIENT_CONTEXT_NAME)
.enableDefaultClient(false)
.setClientRegistryUpdateIntervalInSecs(CLIENT_REGISTRY_REFRESH_INTERVAL)
.setEnableLazy(false)
.setCacheStoreClients(false);
SocketStoreClientFactory socketFactory = new SocketStoreClientFactory(clientConfig);
StoreClient<String, String> client1 = socketFactory.getStoreClient(TEST_STORE_NAME);
StoreClient<String, String> client2 = socketFactory.getStoreClient(TEST_STORE_NAME);
client1.put("k1", "v1");
client2.put("k2", "v2");
Iterator<Pair<ByteArray, Versioned<byte[]>>> it = adminClient.bulkFetchOps.fetchEntries(0,
SystemStoreConstants.SystemStoreName.voldsys$_client_registry.name(),
emptyPartitionList,
null,
false);
ArrayList<ClientInfo> infoList = getClientRegistryContent(it);
assertEquals(TEST_STORE_NAME, infoList.get(0).getStoreName());
assertEquals(CLIENT_CONTEXT_NAME, infoList.get(0).getContext());
assertTrue("Client registry sequence number incorrect", 1 >= infoList.get(0)
.getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(0).getBootstrapTime());
assertNotNull("Client version is null", infoList.get(0).getReleaseVersion());
assertEquals(TEST_STORE_NAME, infoList.get(1).getStoreName());
assertEquals(CLIENT_CONTEXT_NAME, infoList.get(1).getContext());
assertTrue("Client registry sequence number incorrect", 1 >= infoList.get(1)
.getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(1).getBootstrapTime());
assertNotNull("Client version is null", infoList.get(1).getReleaseVersion());
assertEquals(infoList.size(), 2);
it = adminClient.bulkFetchOps.fetchEntries(1,
SystemStoreConstants.SystemStoreName.voldsys$_client_registry.name(),
emptyPartitionList,
null,
false);
infoList = getClientRegistryContent(it);
assertEquals(TEST_STORE_NAME, infoList.get(0).getStoreName());
assertEquals(CLIENT_CONTEXT_NAME, infoList.get(0).getContext());
assertTrue("Client registry sequence number incorrect", 1 >= infoList.get(0)
.getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(0).getBootstrapTime());
assertNotNull("Client version is null", infoList.get(0).getReleaseVersion());
assertEquals(TEST_STORE_NAME, infoList.get(1).getStoreName());
assertEquals(CLIENT_CONTEXT_NAME, infoList.get(1).getContext());
assertTrue("Client registry sequence number incorrect", 1 >= infoList.get(1)
.getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(1).getBootstrapTime());
assertNotNull("Client version is null", infoList.get(1).getReleaseVersion());
assertEquals(infoList.size(), 2);
try {
Thread.sleep(CLIENT_REGISTRY_REFRESH_INTERVAL * 1000 * 5);
} catch(InterruptedException e) {}
// now the periodical update has gone through, it shall be higher than
// the bootstrap time
it = adminClient.bulkFetchOps.fetchEntries(1,
SystemStoreConstants.SystemStoreName.voldsys$_client_registry.name(),
emptyPartitionList,
null,
false);
infoList = getClientRegistryContent(it);
assertTrue("Client registry not updated.",
infoList.get(0).getBootstrapTime() < infoList.get(0).getUpdateTime());
assertTrue("Client registry not updated.",
infoList.get(1).getBootstrapTime() < infoList.get(1).getUpdateTime());
socketFactory.close();
}
/*
* Tests client registry for 2 clients created using the same factory,
* pointing to different stores
*/
@Test
public void testTwoStores() {
List<Integer> emptyPartitionList = Lists.newArrayList();
ClientConfig clientConfig = new ClientConfig().setMaxThreads(4)
.setMaxTotalConnections(4)
.setMaxConnectionsPerNode(4)
.setBootstrapUrls(SERVER_LOCAL_URL
+ serverPorts[0])
.setClientContextName(CLIENT_CONTEXT_NAME)
.enableDefaultClient(false)
.setClientRegistryUpdateIntervalInSecs(CLIENT_REGISTRY_REFRESH_INTERVAL)
.setEnableLazy(false);
SocketStoreClientFactory socketFactory = new SocketStoreClientFactory(clientConfig);
StoreClient<String, String> client1 = socketFactory.getStoreClient(TEST_STORE_NAME);
StoreClient<String, String> client2 = socketFactory.getStoreClient(TEST_STORE_NAME2);
client1.put("k1", "v1");
client2.put("k2", "v2");
Iterator<Pair<ByteArray, Versioned<byte[]>>> it = adminClient.bulkFetchOps.fetchEntries(0,
SystemStoreConstants.SystemStoreName.voldsys$_client_registry.name(),
emptyPartitionList,
null,
false);
ArrayList<ClientInfo> infoList = getClientRegistryContent(it);
assertEquals(CLIENT_CONTEXT_NAME, infoList.get(0).getContext());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(0).getBootstrapTime());
assertNotNull("Client version is null", infoList.get(0).getReleaseVersion());
assertEquals(CLIENT_CONTEXT_NAME, infoList.get(1).getContext());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(1).getBootstrapTime());
assertNotNull("Client version is null", infoList.get(1).getReleaseVersion());
if(infoList.get(0).getStoreName().equals(TEST_STORE_NAME)) {
assertEquals(0, infoList.get(0).getClientSequence());
assertEquals(TEST_STORE_NAME2, infoList.get(1).getStoreName());
assertEquals(1, infoList.get(1).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
infoList.get(1).getBootstrapTime() >= infoList.get(0).getBootstrapTime());
} else {
assertEquals(TEST_STORE_NAME2, infoList.get(0).getStoreName());
assertEquals(1, infoList.get(0).getClientSequence());
assertEquals(TEST_STORE_NAME, infoList.get(1).getStoreName());
assertEquals(0, infoList.get(1).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
infoList.get(0).getBootstrapTime() >= infoList.get(1).getBootstrapTime());
}
it = adminClient.bulkFetchOps.fetchEntries(1,
SystemStoreConstants.SystemStoreName.voldsys$_client_registry.name(),
emptyPartitionList,
null,
false);
infoList = getClientRegistryContent(it);
assertEquals(CLIENT_CONTEXT_NAME, infoList.get(0).getContext());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(0).getBootstrapTime());
assertNotNull("Client version is null", infoList.get(0).getReleaseVersion());
assertEquals(CLIENT_CONTEXT_NAME, infoList.get(1).getContext());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(1).getBootstrapTime());
assertNotNull("Client version is null", infoList.get(1).getReleaseVersion());
if(infoList.get(0).getStoreName().equals(TEST_STORE_NAME)) {
assertEquals(0, infoList.get(0).getClientSequence());
assertEquals(TEST_STORE_NAME2, infoList.get(1).getStoreName());
assertEquals(1, infoList.get(1).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
infoList.get(1).getBootstrapTime() >= infoList.get(0).getBootstrapTime());
} else {
assertEquals(TEST_STORE_NAME2, infoList.get(0).getStoreName());
assertEquals(1, infoList.get(0).getClientSequence());
assertEquals(TEST_STORE_NAME, infoList.get(1).getStoreName());
assertEquals(0, infoList.get(1).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
infoList.get(0).getBootstrapTime() >= infoList.get(1).getBootstrapTime());
}
try {
Thread.sleep(CLIENT_REGISTRY_REFRESH_INTERVAL * 1000 * 5);
} catch(InterruptedException e) {}
// now the periodical update has gone through, it shall be higher than
// the bootstrap time
it = adminClient.bulkFetchOps.fetchEntries(1,
SystemStoreConstants.SystemStoreName.voldsys$_client_registry.name(),
emptyPartitionList,
null,
false);
infoList = getClientRegistryContent(it);
assertTrue("Client registry not updated.",
infoList.get(0).getBootstrapTime() < infoList.get(0).getUpdateTime());
assertTrue("Client registry not updated.",
infoList.get(1).getBootstrapTime() < infoList.get(1).getUpdateTime());
socketFactory.close();
}
/*
* Tests client registry for 2 clients created using the different
* factories, pointing to different stores
*/
@Test
public void testTwoFactories() {
List<Integer> emptyPartitionList = Lists.newArrayList();
ClientConfig clientConfig = new ClientConfig().setMaxThreads(4)
.setMaxTotalConnections(4)
.setMaxConnectionsPerNode(4)
.setBootstrapUrls(SERVER_LOCAL_URL
+ serverPorts[0])
.setClientContextName(CLIENT_CONTEXT_NAME)
.enableDefaultClient(false)
.setClientRegistryUpdateIntervalInSecs(CLIENT_REGISTRY_REFRESH_INTERVAL)
.setEnableLazy(false);
SocketStoreClientFactory socketFactory1 = new SocketStoreClientFactory(clientConfig);
ClientConfig clientConfig2 = new ClientConfig().setMaxThreads(4)
.setMaxTotalConnections(4)
.setMaxConnectionsPerNode(4)
.setBootstrapUrls(SERVER_LOCAL_URL
+ serverPorts[0])
.setClientContextName(CLIENT_CONTEXT_NAME2)
.enableDefaultClient(false)
.setClientRegistryUpdateIntervalInSecs(CLIENT_REGISTRY_REFRESH_INTERVAL)
.setEnableLazy(false);
SocketStoreClientFactory socketFactory2 = new SocketStoreClientFactory(clientConfig2);
StoreClient<String, String> client1 = socketFactory1.getStoreClient(TEST_STORE_NAME);
StoreClient<String, String> client2 = socketFactory2.getStoreClient(TEST_STORE_NAME2);
client1.put("k1", "v1");
client2.put("k2", "v2");
Iterator<Pair<ByteArray, Versioned<byte[]>>> it = adminClient.bulkFetchOps.fetchEntries(0,
SystemStoreConstants.SystemStoreName.voldsys$_client_registry.name(),
emptyPartitionList,
null,
false);
ArrayList<ClientInfo> infoList = getClientRegistryContent(it);
assertNotNull("Client version is null", infoList.get(0).getReleaseVersion());
assertNotNull("Client version is null", infoList.get(1).getReleaseVersion());
if(infoList.get(0).getStoreName().equals(TEST_STORE_NAME)) {
assertEquals(CLIENT_CONTEXT_NAME, infoList.get(0).getContext());
assertEquals(0, infoList.get(0).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(0).getBootstrapTime());
assertEquals(TEST_STORE_NAME2, infoList.get(1).getStoreName());
assertEquals(CLIENT_CONTEXT_NAME2, infoList.get(1).getContext());
assertEquals(0, infoList.get(1).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(1).getBootstrapTime());
assertTrue("Client registry bootstrap time incorrect",
infoList.get(1).getBootstrapTime() >= infoList.get(0).getBootstrapTime());
} else {
assertEquals(TEST_STORE_NAME2, infoList.get(0).getStoreName());
assertEquals(CLIENT_CONTEXT_NAME2, infoList.get(0).getContext());
assertEquals(0, infoList.get(0).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(0).getBootstrapTime());
assertEquals(TEST_STORE_NAME, infoList.get(1).getStoreName());
assertEquals(CLIENT_CONTEXT_NAME, infoList.get(1).getContext());
assertEquals(0, infoList.get(1).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(1).getBootstrapTime());
assertTrue("Client registry bootstrap time incorrect",
infoList.get(0).getBootstrapTime() >= infoList.get(1).getBootstrapTime());
}
it = adminClient.bulkFetchOps.fetchEntries(1,
SystemStoreConstants.SystemStoreName.voldsys$_client_registry.name(),
emptyPartitionList,
null,
false);
infoList = getClientRegistryContent(it);
assertNotNull("Client version is null", infoList.get(0).getReleaseVersion());
assertNotNull("Client version is null", infoList.get(1).getReleaseVersion());
if(infoList.get(0).getStoreName().equals(TEST_STORE_NAME)) {
assertEquals(CLIENT_CONTEXT_NAME, infoList.get(0).getContext());
assertEquals(0, infoList.get(0).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(0).getBootstrapTime());
assertEquals(TEST_STORE_NAME2, infoList.get(1).getStoreName());
assertEquals(CLIENT_CONTEXT_NAME2, infoList.get(1).getContext());
assertEquals(0, infoList.get(1).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(1).getBootstrapTime());
assertTrue("Client registry bootstrap time incorrect",
infoList.get(1).getBootstrapTime() >= infoList.get(0).getBootstrapTime());
} else {
assertEquals(TEST_STORE_NAME2, infoList.get(0).getStoreName());
assertEquals(CLIENT_CONTEXT_NAME2, infoList.get(0).getContext());
assertEquals(0, infoList.get(0).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(0).getBootstrapTime());
assertEquals(TEST_STORE_NAME, infoList.get(1).getStoreName());
assertEquals(CLIENT_CONTEXT_NAME, infoList.get(1).getContext());
assertEquals(0, infoList.get(1).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(1).getBootstrapTime());
assertTrue("Client registry bootstrap time incorrect",
infoList.get(0).getBootstrapTime() >= infoList.get(1).getBootstrapTime());
}
try {
Thread.sleep(CLIENT_REGISTRY_REFRESH_INTERVAL * 1000 * 5);
} catch(InterruptedException e) {}
// now the periodical update has gone through, it shall be higher than
// the bootstrap time
it = adminClient.bulkFetchOps.fetchEntries(1,
SystemStoreConstants.SystemStoreName.voldsys$_client_registry.name(),
emptyPartitionList,
null,
false);
infoList = getClientRegistryContent(it);
assertTrue("Client registry not updated.",
infoList.get(0).getBootstrapTime() < infoList.get(0).getUpdateTime());
assertTrue("Client registry not updated.",
infoList.get(1).getBootstrapTime() < infoList.get(1).getUpdateTime());
socketFactory1.close();
socketFactory2.close();
}
/*
* Tests client registry for in the presence of 1 server failure.
*/
@Test
public void testOneServerFailure() {
// bring down one server before starting up the clients
servers[0].stop();
List<Integer> emptyPartitionList = Lists.newArrayList();
ClientConfig clientConfig = new ClientConfig().setMaxThreads(4)
.setMaxTotalConnections(4)
.setMaxConnectionsPerNode(4)
.setBootstrapUrls(SERVER_LOCAL_URL
+ serverPorts[1])
.setClientContextName(CLIENT_CONTEXT_NAME)
.enableDefaultClient(false)
.setClientRegistryUpdateIntervalInSecs(CLIENT_REGISTRY_REFRESH_INTERVAL)
.setEnableLazy(false);
SocketStoreClientFactory socketFactory1 = new SocketStoreClientFactory(clientConfig);
ClientConfig clientConfig2 = new ClientConfig().setMaxThreads(4)
.setMaxTotalConnections(4)
.setMaxConnectionsPerNode(4)
.setBootstrapUrls(SERVER_LOCAL_URL
+ serverPorts[1])
.setClientContextName(CLIENT_CONTEXT_NAME2)
.enableDefaultClient(false)
.setClientRegistryUpdateIntervalInSecs(CLIENT_REGISTRY_REFRESH_INTERVAL)
.setEnableLazy(false);
SocketStoreClientFactory socketFactory2 = new SocketStoreClientFactory(clientConfig2);
StoreClient<String, String> client1 = socketFactory1.getStoreClient(TEST_STORE_NAME);
StoreClient<String, String> client2 = socketFactory2.getStoreClient(TEST_STORE_NAME2);
client1.put("k1", "v1");
client2.put("k2", "v2");
Iterator<Pair<ByteArray, Versioned<byte[]>>> it = adminClient.bulkFetchOps.fetchEntries(1,
SystemStoreConstants.SystemStoreName.voldsys$_client_registry.name(),
emptyPartitionList,
null,
false);
ArrayList<ClientInfo> infoList = getClientRegistryContent(it);
assertNotNull("Client version is null", infoList.get(0).getReleaseVersion());
assertNotNull("Client version is null", infoList.get(1).getReleaseVersion());
if(infoList.get(0).getStoreName().equals(TEST_STORE_NAME)) {
assertEquals(CLIENT_CONTEXT_NAME, infoList.get(0).getContext());
assertEquals(0, infoList.get(0).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(0).getBootstrapTime());
assertEquals(TEST_STORE_NAME2, infoList.get(1).getStoreName());
assertEquals(CLIENT_CONTEXT_NAME2, infoList.get(1).getContext());
assertEquals(0, infoList.get(1).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(1).getBootstrapTime());
assertTrue("Client registry bootstrap time incorrect",
infoList.get(1).getBootstrapTime() >= infoList.get(0).getBootstrapTime());
} else {
assertEquals(TEST_STORE_NAME2, infoList.get(0).getStoreName());
assertEquals(CLIENT_CONTEXT_NAME2, infoList.get(0).getContext());
assertEquals(0, infoList.get(0).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(0).getBootstrapTime());
assertEquals(TEST_STORE_NAME, infoList.get(1).getStoreName());
assertEquals(CLIENT_CONTEXT_NAME, infoList.get(1).getContext());
assertEquals(0, infoList.get(1).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(1).getBootstrapTime());
assertTrue("Client registry bootstrap time incorrect",
infoList.get(0).getBootstrapTime() >= infoList.get(1).getBootstrapTime());
}
try {
Thread.sleep(CLIENT_REGISTRY_REFRESH_INTERVAL * 1000 * 5);
} catch(InterruptedException e) {}
// now the periodical update has gone through, it shall be higher than
// the bootstrap time
it = adminClient.bulkFetchOps.fetchEntries(1,
SystemStoreConstants.SystemStoreName.voldsys$_client_registry.name(),
emptyPartitionList,
null,
false);
infoList = getClientRegistryContent(it);
assertTrue("Client registry not updated.",
infoList.get(0).getBootstrapTime() < infoList.get(0).getUpdateTime());
assertTrue("Client registry not updated.",
infoList.get(1).getBootstrapTime() < infoList.get(1).getUpdateTime());
socketFactory1.close();
socketFactory2.close();
}
/*
* Test repeated client-registry setup due to client bounce.
*/
@Test
public void testRepeatRegistrationSameFactoryUnCached() {
testRepeatRegistrationSameFactory(false, 6);
}
@Test
public void testRepeatRegistrationSameFactoryCached() {
testRepeatRegistrationSameFactory(true, 2);
}
private void testRepeatRegistrationSameFactory(boolean cached, int expectedSize) {
List<Integer> emptyPartitionList = Lists.newArrayList();
ClientConfig clientConfig = new ClientConfig().setMaxThreads(4)
.setMaxTotalConnections(4)
.setMaxConnectionsPerNode(4)
.setBootstrapUrls(SERVER_LOCAL_URL
+ serverPorts[1])
.setClientContextName(CLIENT_CONTEXT_NAME)
.enableDefaultClient(false)
.setClientRegistryUpdateIntervalInSecs(CLIENT_REGISTRY_REFRESH_INTERVAL)
.setEnableLazy(false)
.setCacheStoreClients(cached);
SocketStoreClientFactory socketFactory1 = new SocketStoreClientFactory(clientConfig);
ClientConfig clientConfig2 = new ClientConfig().setMaxThreads(4)
.setMaxTotalConnections(4)
.setMaxConnectionsPerNode(4)
.setBootstrapUrls(SERVER_LOCAL_URL
+ serverPorts[1])
.setClientContextName(CLIENT_CONTEXT_NAME2)
.enableDefaultClient(false)
.setClientRegistryUpdateIntervalInSecs(CLIENT_REGISTRY_REFRESH_INTERVAL)
.setEnableLazy(false)
.setCacheStoreClients(cached);
SocketStoreClientFactory socketFactory2 = new SocketStoreClientFactory(clientConfig2);
for(int i = 0; i < 3; i++) {
StoreClient<String, String> client1 = socketFactory1.getStoreClient(TEST_STORE_NAME);
StoreClient<String, String> client2 = socketFactory2.getStoreClient(TEST_STORE_NAME2);
client1.put("k1", "v1");
client2.put("k2", "v2");
}
Iterator<Pair<ByteArray, Versioned<byte[]>>> it = adminClient.bulkFetchOps.fetchEntries(1,
SystemStoreConstants.SystemStoreName.voldsys$_client_registry.name(),
emptyPartitionList,
null,
false);
ArrayList<ClientInfo> infoList = getClientRegistryContent(it);
assertEquals("Incorrect # of entries created in client registry",
expectedSize,
infoList.size());
socketFactory1.close();
socketFactory2.close();
}
/*
* Test repeated client-registry setup due to client bounce and via a
* different factory.
*/
@Test
public void testRepeatRegistrationDifferentFactories() {
long client1LastBootstrapTime = 0;
long client2LastBootstrapTime = 0;
for(int i = 0; i < 3; i++) {
List<Integer> emptyPartitionList = Lists.newArrayList();
ClientConfig clientConfig = new ClientConfig().setMaxThreads(4)
.setMaxTotalConnections(4)
.setMaxConnectionsPerNode(4)
.setBootstrapUrls(SERVER_LOCAL_URL
+ serverPorts[1])
.setClientContextName(CLIENT_CONTEXT_NAME)
.enableDefaultClient(false)
.setClientRegistryUpdateIntervalInSecs(CLIENT_REGISTRY_REFRESH_INTERVAL)
.setEnableLazy(false);
SocketStoreClientFactory socketFactory1 = new SocketStoreClientFactory(clientConfig);
ClientConfig clientConfig2 = new ClientConfig().setMaxThreads(4)
.setMaxTotalConnections(4)
.setMaxConnectionsPerNode(4)
.setBootstrapUrls(SERVER_LOCAL_URL
+ serverPorts[1])
.setClientContextName(CLIENT_CONTEXT_NAME2)
.enableDefaultClient(false)
.setClientRegistryUpdateIntervalInSecs(CLIENT_REGISTRY_REFRESH_INTERVAL)
.setEnableLazy(false);
SocketStoreClientFactory socketFactory2 = new SocketStoreClientFactory(clientConfig2);
StoreClient<String, String> client1 = socketFactory1.getStoreClient(TEST_STORE_NAME);
StoreClient<String, String> client2 = socketFactory2.getStoreClient(TEST_STORE_NAME2);
client1.put("k1", "v1");
client2.put("k2", "v2");
Iterator<Pair<ByteArray, Versioned<byte[]>>> it = adminClient.bulkFetchOps.fetchEntries(1,
SystemStoreConstants.SystemStoreName.voldsys$_client_registry.name(),
emptyPartitionList,
null,
false);
ArrayList<ClientInfo> infoList = getClientRegistryContent(it);
assertEquals("Incorrect # of entries created in client registry", 2, infoList.size());
assertNotNull("Client version is null", infoList.get(0).getReleaseVersion());
assertNotNull("Client version is null", infoList.get(1).getReleaseVersion());
if(infoList.get(0).getStoreName().equals(TEST_STORE_NAME)) {
assertEquals(CLIENT_CONTEXT_NAME, infoList.get(0).getContext());
assertEquals(0, infoList.get(0).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(0).getBootstrapTime());
assertEquals(TEST_STORE_NAME2, infoList.get(1).getStoreName());
assertEquals(CLIENT_CONTEXT_NAME2, infoList.get(1).getContext());
assertEquals(0, infoList.get(1).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(1).getBootstrapTime());
assertTrue("Client registry bootstrap time incorrect",
infoList.get(1).getBootstrapTime() >= infoList.get(0).getBootstrapTime());
} else {
assertEquals(TEST_STORE_NAME2, infoList.get(0).getStoreName());
assertEquals(CLIENT_CONTEXT_NAME2, infoList.get(0).getContext());
assertEquals(0, infoList.get(0).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(0).getBootstrapTime());
assertEquals(TEST_STORE_NAME, infoList.get(1).getStoreName());
assertEquals(CLIENT_CONTEXT_NAME, infoList.get(1).getContext());
assertEquals(0, infoList.get(1).getClientSequence());
assertTrue("Client registry bootstrap time incorrect",
startTime <= infoList.get(1).getBootstrapTime());
assertTrue("Client registry bootstrap time incorrect",
infoList.get(0).getBootstrapTime() >= infoList.get(1).getBootstrapTime());
}
try {
Thread.sleep(CLIENT_REGISTRY_REFRESH_INTERVAL * 1000 * 5);
} catch(InterruptedException e) {}
// now the periodical update has gone through, it shall be higher
// than
// the bootstrap time
it = adminClient.bulkFetchOps.fetchEntries(1,
SystemStoreConstants.SystemStoreName.voldsys$_client_registry.name(),
emptyPartitionList,
null,
false);
infoList = getClientRegistryContent(it);
assertTrue("Client registry not updated.",
infoList.get(0).getBootstrapTime() < infoList.get(0).getUpdateTime());
assertTrue("Client registry not updated.",
infoList.get(1).getBootstrapTime() < infoList.get(1).getUpdateTime());
assertTrue("Bootstrap time does not increase client bounces",
infoList.get(0).getBootstrapTime() > client1LastBootstrapTime);
assertTrue("Bootstrap time does not increase client bounces",
infoList.get(1).getBootstrapTime() > client2LastBootstrapTime);
client1LastBootstrapTime = infoList.get(0).getBootstrapTime();
client2LastBootstrapTime = infoList.get(0).getBootstrapTime();
socketFactory1.close();
socketFactory2.close();
}
}
private ArrayList<ClientInfo> getClientRegistryContent(Iterator<Pair<ByteArray, Versioned<byte[]>>> it) {
ArrayList<ClientInfo> infoList = Lists.newArrayList();
while(it.hasNext()) {
String clientInfoString = (String) valueSerializer.toObject(it.next()
.getSecond()
.getValue());
Properties props = new Properties();
try {
props.load(new ByteArrayInputStream(clientInfoString.getBytes()));
} catch(IOException ex) {
throw new VoldemortException("Error loading clientInfo " + props.toString(), ex);
}
ClientConfig clientConfig = new ClientConfig();
clientConfig.setMaxConnectionsPerNode(Integer.parseInt(props.getProperty("max_connections")))
.setRoutingTimeout(Integer.parseInt(props.getProperty("routing_timeout_ms")),
TimeUnit.MILLISECONDS)
.setConnectionTimeout(Integer.parseInt(props.getProperty("connection_timeout_ms")),
TimeUnit.MILLISECONDS)
.setSocketTimeout(Integer.parseInt(props.getProperty("socket_timeout_ms")),
TimeUnit.MILLISECONDS)
.setClientZoneId(Integer.parseInt(props.getProperty("client_zone_id")))
.setFailureDetectorImplementation(props.getProperty("failuredetector_implementation"));
ClientInfo cInfo = new ClientInfo(props.getProperty("storeName"),
props.getProperty("context"),
Integer.parseInt(props.getProperty("sequence")),
Long.parseLong(props.getProperty("bootstrapTime")),
props.getProperty("releaseVersion"),
clientConfig);
cInfo.setUpdateTime(Long.parseLong(props.getProperty("updateTime")));
cInfo.setDeploymentPath(props.getProperty("deploymentPath"));
cInfo.setLocalHostName(props.getProperty("localHostName"));
infoList.add(cInfo);
}
return infoList;
}
private void clearRegistryContent() {
for(int i = 0; i < TOTAL_SERVERS; i++) {
servers[i].getStoreRepository()
.getStorageEngine(SystemStoreConstants.SystemStoreName.voldsys$_client_registry.name())
.truncate();
}
}
private boolean isConfigEqual(ClientConfig received, ClientConfig expected) {
return (received.getMaxConnectionsPerNode() == expected.getMaxConnectionsPerNode()
&& received.getRoutingTimeout(TimeUnit.MILLISECONDS) == expected.getRoutingTimeout(TimeUnit.MILLISECONDS)
&& received.getSocketTimeout(TimeUnit.MILLISECONDS) == expected.getSocketTimeout(TimeUnit.MILLISECONDS)
&& received.getConnectionTimeout(TimeUnit.MILLISECONDS) == expected.getConnectionTimeout(TimeUnit.MILLISECONDS)
&& received.getClientZoneId() == expected.getClientZoneId() && received.getFailureDetectorImplementation()
.equals(expected.getFailureDetectorImplementation()));
}
}