Search in sources :

Example 11 with ZooKeeperConnectionManager

use of com.linkedin.d2.balancer.servers.ZooKeeperConnectionManager in project rest.li by linkedin.

the class SharedZkConnectionProviderTest method startConnectionManagers.

private void startConnectionManagers(List<ZooKeeperConnectionManager> managers) throws Exception {
    FutureCallback<None> markupCallback = new FutureCallback<>();
    Callback<None> markupMultiCallback = Callbacks.countDown(markupCallback, managers.size());
    for (ZooKeeperConnectionManager manager : managers) {
        _threadPoolExecutor.submit(() -> {
            try {
                // Using random sleep to introduce delay to simulate uncertainty during real environment.
                Thread.sleep(Math.abs(new Random().nextInt()) % 100);
                manager.start(markupMultiCallback);
            } catch (Exception e) {
                markupMultiCallback.onError(new RuntimeException("Announcing failed for host: " + manager.getAnnouncers()[0].getUri() + " due to: " + e.getMessage(), e));
            }
        });
    }
    markupCallback.get(BLOCKING_CALL_TIMEOUT, TimeUnit.MILLISECONDS);
}
Also used : ZooKeeperConnectionManager(com.linkedin.d2.balancer.servers.ZooKeeperConnectionManager) Random(java.util.Random) None(com.linkedin.common.util.None) FutureCallback(com.linkedin.common.callback.FutureCallback) TimeoutException(java.util.concurrent.TimeoutException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException)

Example 12 with ZooKeeperConnectionManager

use of com.linkedin.d2.balancer.servers.ZooKeeperConnectionManager in project rest.li by linkedin.

the class SharedZkConnectionProviderTest method testAnnouncerAndClientSharing.

/**
 * Testing sharing connections between announcers and d2client
 * @throws Exception
 */
@Test(groups = "needZk")
public void testAnnouncerAndClientSharing() throws Exception {
    // connection shared to announcers
    List<URI> hostNames = prepareHostNames(20, "testAnnouncerAndClientSharing");
    List<ZooKeeperConnectionManager> connectionManagers = prepareConnectionManagers(hostNames);
    int l = 1;
    // set up a mock transport client
    Map<String, TransportClientFactory> transportClientMap = new HashMap<>();
    TestTransportClientFactory testClientFactory = new TestTransportClientFactory();
    transportClientMap.put("http", testClientFactory);
    // connection shared to d2client
    D2Client client = getD2Client(transportClientMap);
    // there should only be one connection
    assertEquals(_provider.getZkConnectionCount(), 1);
    // start both announcers and client
    FutureCallback<None> startUpCallback = new FutureCallback<>();
    Callback<None> startUpMultiCallback = Callbacks.countDown(startUpCallback, connectionManagers.size() + 1);
    _threadPoolExecutor.submit(() -> client.start(startUpMultiCallback));
    for (ZooKeeperConnectionManager manager : connectionManagers) {
        _threadPoolExecutor.submit(() -> manager.start(startUpMultiCallback));
    }
    startUpCallback.get(BLOCKING_CALL_TIMEOUT, TimeUnit.MILLISECONDS);
    // verify zookeeper is updated
    UriProperties properties = _verificationStore.get(CLUSTER_NAME);
    assertNotNull(properties);
    assertEquals(properties.Uris().size(), 20);
    // fire some requests to make sure announcement is successful and hosts properties can be retrieved successfully.
    int requestRepeat = 1000;
    FutureCallback<None> reqCallback = new FutureCallback<>();
    fireTestRequests(client, requestRepeat, reqCallback);
    reqCallback.get(BLOCKING_CALL_TIMEOUT, TimeUnit.MILLISECONDS);
    // verify d2client received the changes
    HostSet hosts = client.getFacilities().getKeyMapper().getAllPartitionsMultipleHosts(new URI("d2://testService"), 20);
    Assert.assertEquals(hosts.getAllHosts().size(), 20);
    Assert.assertEquals(testClientFactory.requestCount.get(), 1000);
    // Markdown half of the hosts and test the results
    FutureCallback<None> hostsMarkdownCallback = new FutureCallback<>();
    Callback<None> hostsMarkdownMultiCallback = Callbacks.countDown(hostsMarkdownCallback, 10);
    for (ZooKeeperConnectionManager manager : connectionManagers.subList(0, 10)) {
        _threadPoolExecutor.submit(() -> manager.getAnnouncers()[0].markDown(hostsMarkdownMultiCallback));
    }
    hostsMarkdownCallback.get(BLOCKING_CALL_TIMEOUT, TimeUnit.MILLISECONDS);
    // verify zookeeper is updated
    properties = _verificationStore.get(CLUSTER_NAME);
    assertNotNull(properties);
    assertEquals(properties.Uris().size(), 10);
    // fire some requests to make sure announcement is successful and hosts properties can be retrieved successfully.
    FutureCallback<None> secondReqCallback = new FutureCallback<>();
    fireTestRequests(client, requestRepeat, secondReqCallback);
    secondReqCallback.get(BLOCKING_CALL_TIMEOUT, TimeUnit.MILLISECONDS);
    // verify d2client can read the zookeeper updates.
    hosts = client.getFacilities().getKeyMapper().getAllPartitionsMultipleHosts(new URI("d2://testService"), 20);
    Assert.assertEquals(hosts.getAllHosts().size(), 10);
    Assert.assertEquals(testClientFactory.requestCount.get(), 2000);
    // Mix announcements with request firing to test connection robustness.
    FutureCallback<None> thirdReqCallback = new FutureCallback<>();
    Callback<None> thirdReqMultiCallback = Callbacks.countDown(thirdReqCallback, requestRepeat + 10);
    for (int i = 0; i < requestRepeat; i++) {
        _threadPoolExecutor.submit(() -> {
            try {
                RestRequestBuilder builder = new RestRequestBuilder(new URI("d2://testService"));
                client.restRequest(builder.build(), decorateNoneCallback(thirdReqMultiCallback));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
        if (i % 100 == 0) {
            // markup one host every 100 requests
            ZooKeeperConnectionManager manager = connectionManagers.get(i / 100);
            _threadPoolExecutor.submit(() -> {
                try {
                    manager.getAnnouncers()[0].markUp(thirdReqMultiCallback);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            });
        }
    }
    thirdReqCallback.get(BLOCKING_CALL_TIMEOUT, TimeUnit.MILLISECONDS);
    Assert.assertEquals(testClientFactory.requestCount.get(), 3000);
    // announcers can be shutdown after announcing, without affecting client. This should not happen though.
    FutureCallback<None> announcerShutdownCallback = new FutureCallback<>();
    Callback<None> announcersShutdownCallback = Callbacks.countDown(announcerShutdownCallback, connectionManagers.size());
    for (ZooKeeperConnectionManager manager : connectionManagers) {
        manager.shutdown(announcersShutdownCallback);
    }
    announcerShutdownCallback.get(BLOCKING_CALL_TIMEOUT, TimeUnit.MILLISECONDS);
    // fire some requests to make sure d2client is still usable.
    FutureCallback<None> fourthReqCallback = new FutureCallback<>();
    fireTestRequests(client, requestRepeat, fourthReqCallback);
    thirdReqCallback.get(BLOCKING_CALL_TIMEOUT, TimeUnit.MILLISECONDS);
    hosts = client.getFacilities().getKeyMapper().getAllPartitionsMultipleHosts(new URI("d2://testService"), 20);
    Assert.assertEquals(hosts.getAllHosts().size(), 20);
    Assert.assertEquals(testClientFactory.requestCount.get(), 4000);
    // test done!
    FutureCallback<None> clientShutdownCallback = new FutureCallback<>();
    client.shutdown(clientShutdownCallback);
    clientShutdownCallback.get(BLOCKING_CALL_TIMEOUT, TimeUnit.MILLISECONDS);
    // make sure the connection is properly stopped.
    ZKPersistentConnection connection = _provider.getZKPersistentConnection(new ZKConnectionBuilder("localhost:" + ZK_PORT).setTimeout(ZK_TIMEOUT));
    Assert.assertNotNull(connection);
    Assert.assertTrue(connection.isConnectionStopped());
}
Also used : ZooKeeperConnectionManager(com.linkedin.d2.balancer.servers.ZooKeeperConnectionManager) HashMap(java.util.HashMap) D2Client(com.linkedin.d2.balancer.D2Client) URI(java.net.URI) TimeoutException(java.util.concurrent.TimeoutException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) HostSet(com.linkedin.d2.balancer.util.HostSet) UriProperties(com.linkedin.d2.balancer.properties.UriProperties) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) TransportClientFactory(com.linkedin.r2.transport.common.TransportClientFactory) None(com.linkedin.common.util.None) FutureCallback(com.linkedin.common.callback.FutureCallback) Test(org.testng.annotations.Test)

Example 13 with ZooKeeperConnectionManager

use of com.linkedin.d2.balancer.servers.ZooKeeperConnectionManager in project rest.li by linkedin.

the class SharedZkConnectionProviderTest method testZKPropertyUpdate.

/**
 * Test that when there is an zookeeper property update, d2client can receive the update correctly
 */
@Test(groups = "needZK")
public void testZKPropertyUpdate() throws Exception {
    List<URI> hosts = prepareHostNames(5, "testZKPropertyUpdate");
    List<ZooKeeperConnectionManager> connectionManagers = prepareConnectionManagers(hosts);
    Map<String, TransportClientFactory> transportClientMap = new HashMap<>();
    transportClientMap.put("http", new TestTransportClientFactory());
    // connection shared to d2client
    D2Client client = getD2Client(transportClientMap);
    FutureCallback<None> startupCallback = new FutureCallback<>();
    client.start(startupCallback);
    startupCallback.get(BLOCKING_CALL_TIMEOUT, TimeUnit.MILLISECONDS);
    startConnectionManagers(connectionManagers);
    Directory d2Directory = client.getFacilities().getDirectory();
    List<String> serviceList = new ArrayList<>();
    ServiceProperties serviceProps = new ServiceProperties("newTestService", CLUSTER_NAME, "/newTestService", Arrays.asList("degrader"), Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), Arrays.asList("http"), Collections.emptySet());
    FutureCallback<None> propertyCallback = new FutureCallback<>();
    _serviceRegistry.put("newTestService", serviceProps, propertyCallback);
    propertyCallback.get(BLOCKING_CALL_TIMEOUT, TimeUnit.MILLISECONDS);
    FutureCallback<None> finishCallback = new FutureCallback<>();
    d2Directory.getServiceNames(new Callback<List<String>>() {

        @Override
        public void onError(Throwable e) {
            finishCallback.onError(e);
        }

        @Override
        public void onSuccess(List<String> result) {
            serviceList.addAll(result);
            finishCallback.onSuccess(None.none());
        }
    });
    finishCallback.get(BLOCKING_CALL_TIMEOUT, TimeUnit.MILLISECONDS);
    Assert.assertEquals(serviceList.size(), 2);
    Assert.assertTrue(serviceList.contains("newTestService"));
    Assert.assertTrue(serviceList.contains("testService"));
    shutdownConnectionManagers(connectionManagers);
    FutureCallback<None> clientShutdownCallback = new FutureCallback<>();
    client.shutdown(clientShutdownCallback);
    clientShutdownCallback.get(BLOCKING_CALL_TIMEOUT, TimeUnit.MILLISECONDS);
}
Also used : ZooKeeperConnectionManager(com.linkedin.d2.balancer.servers.ZooKeeperConnectionManager) HashMap(java.util.HashMap) D2Client(com.linkedin.d2.balancer.D2Client) ArrayList(java.util.ArrayList) URI(java.net.URI) ServiceProperties(com.linkedin.d2.balancer.properties.ServiceProperties) List(java.util.List) ArrayList(java.util.ArrayList) TransportClientFactory(com.linkedin.r2.transport.common.TransportClientFactory) None(com.linkedin.common.util.None) FutureCallback(com.linkedin.common.callback.FutureCallback) Directory(com.linkedin.d2.balancer.Directory) Test(org.testng.annotations.Test)

Example 14 with ZooKeeperConnectionManager

use of com.linkedin.d2.balancer.servers.ZooKeeperConnectionManager in project rest.li by linkedin.

the class ExampleD2Server method main.

public static void main(String[] args) throws IOException, ParseException {
    // get server configuration
    JSONObject json = parseConfig();
    System.out.println("Finished parsing the server config");
    List<Map<String, Object>> d2ServersConfigs = (List<Map<String, Object>>) json.get("d2Servers");
    List<Map<String, Object>> echoServerConfigs = (List<Map<String, Object>>) json.get("echoServers");
    Long timeout = (Long) json.get("announcerStartTimeout");
    Long shutdownTimeout = (Long) json.get("announcerShutdownTimeout");
    // create and start echo servers
    List<EchoServer> echoServers = createAndStartEchoServers(echoServerConfigs);
    System.out.println("Finished creating echo servers");
    // create d2 announcers (for announcing the existence of these servers to the world)
    ZooKeeperAnnouncer[] zkAnnouncers = createZkAnnouncers(d2ServersConfigs);
    // manager will keep track of the lifecycle of d2 announcers i.e. start publishing
    // once connected to zookeeper, reconnect if zookeeper is disconnected, etc
    ZooKeeperConnectionManager manager = createZkManager(json, zkAnnouncers);
    System.out.println("Starting zookeeper announcers");
    ExecutorService executorService = Executors.newSingleThreadExecutor();
    startAnnouncers(manager, executorService, timeout);
    // waiting for user to turn off this process
    System.in.read();
    System.out.println("shutting down...");
    shutdown(echoServers, manager, executorService, shutdownTimeout);
}
Also used : ZooKeeperConnectionManager(com.linkedin.d2.balancer.servers.ZooKeeperConnectionManager) ZooKeeperAnnouncer(com.linkedin.d2.balancer.servers.ZooKeeperAnnouncer) JSONObject(org.json.simple.JSONObject) ExecutorService(java.util.concurrent.ExecutorService) ArrayList(java.util.ArrayList) List(java.util.List) JSONObject(org.json.simple.JSONObject) Map(java.util.Map)

Example 15 with ZooKeeperConnectionManager

use of com.linkedin.d2.balancer.servers.ZooKeeperConnectionManager in project rest.li by linkedin.

the class ExampleD2Server method createZkManager.

private static ZooKeeperConnectionManager createZkManager(JSONObject json, ZooKeeperAnnouncer[] zkAnnouncers) {
    ZKUriStoreFactory factory = new ZKUriStoreFactory();
    String zkConnectString = (String) json.get("zkConnectString");
    int zkRetryLimit = ((Long) json.get("zkRetryLimit")).intValue();
    int zkSessionTimeout = ((Long) json.get("zkSessionTimeout")).intValue();
    String zkBasePath = (String) json.get("zkBasePath");
    return new ZooKeeperConnectionManager(zkConnectString, zkSessionTimeout, zkBasePath, factory, zkRetryLimit, zkAnnouncers);
}
Also used : ZKUriStoreFactory(com.linkedin.d2.balancer.servers.ZKUriStoreFactory) ZooKeeperConnectionManager(com.linkedin.d2.balancer.servers.ZooKeeperConnectionManager)

Aggregations

Test (org.testng.annotations.Test)16 UriProperties (com.linkedin.d2.balancer.properties.UriProperties)15 FutureCallback (com.linkedin.common.callback.FutureCallback)12 None (com.linkedin.common.util.None)12 ZooKeeperConnectionManager (com.linkedin.d2.balancer.servers.ZooKeeperConnectionManager)11 URI (java.net.URI)6 HashMap (java.util.HashMap)4 ExecutionException (java.util.concurrent.ExecutionException)4 IOException (java.io.IOException)3 ArrayList (java.util.ArrayList)3 ExecutorService (java.util.concurrent.ExecutorService)3 TimeoutException (java.util.concurrent.TimeoutException)3 MultiCallback (com.linkedin.common.callback.MultiCallback)2 D2Client (com.linkedin.d2.balancer.D2Client)2 PartitionData (com.linkedin.d2.balancer.properties.PartitionData)2 ZooKeeperAnnouncer (com.linkedin.d2.balancer.servers.ZooKeeperAnnouncer)2 ZKPersistentConnection (com.linkedin.d2.discovery.stores.zk.ZKPersistentConnection)2 TransportClientFactory (com.linkedin.r2.transport.common.TransportClientFactory)2 List (java.util.List)2 Random (java.util.Random)2