Java tutorial
/* * Copyright 2012 Netflix, 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 discovery; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map; import org.apache.commons.io.IOUtils; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.netflix.curator.framework.CuratorFramework; import com.netflix.curator.framework.CuratorFrameworkFactory; import com.netflix.curator.retry.ExponentialBackoffRetry; import com.netflix.curator.test.TestingServer; import com.netflix.curator.x.discovery.ServiceDiscovery; import com.netflix.curator.x.discovery.ServiceDiscoveryBuilder; import com.netflix.curator.x.discovery.ServiceInstance; import com.netflix.curator.x.discovery.ServiceProvider; import com.netflix.curator.x.discovery.details.JsonInstanceSerializer; import com.netflix.curator.x.discovery.strategies.RandomStrategy; public class DiscoveryExample { private static final String PATH = "/discovery/example"; public static void main(String[] args) throws Exception { // This method is scaffolding to get the example up and running TestingServer server = new TestingServer(); CuratorFramework client = null; ServiceDiscovery<InstanceDetails> serviceDiscovery = null; Map<String, ServiceProvider<InstanceDetails>> providers = Maps.newHashMap(); try { client = CuratorFrameworkFactory.newClient(server.getConnectString(), new ExponentialBackoffRetry(1000, 3)); client.start(); JsonInstanceSerializer<InstanceDetails> serializer = new JsonInstanceSerializer<InstanceDetails>( InstanceDetails.class); serviceDiscovery = ServiceDiscoveryBuilder.builder(InstanceDetails.class).client(client).basePath(PATH) .serializer(serializer).build(); serviceDiscovery.start(); processCommands(serviceDiscovery, providers, client); } finally { for (ServiceProvider<InstanceDetails> cache : providers.values()) { IOUtils.closeQuietly(cache); } IOUtils.closeQuietly(serviceDiscovery); IOUtils.closeQuietly(client); IOUtils.closeQuietly(server); } } private static void processCommands(ServiceDiscovery<InstanceDetails> serviceDiscovery, Map<String, ServiceProvider<InstanceDetails>> providers, CuratorFramework client) throws Exception { // More scaffolding that does a simple command line processor printHelp(); List<ExampleServer> servers = Lists.newArrayList(); try { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); boolean done = false; while (!done) { System.out.print("> "); String command = in.readLine().trim(); String[] parts = command.split("\\s"); if (parts.length == 0) { continue; } String operation = parts[0]; String args[] = Arrays.copyOfRange(parts, 1, parts.length); if (operation.equalsIgnoreCase("help") || operation.equalsIgnoreCase("?")) { printHelp(); } else if (operation.equalsIgnoreCase("q") || operation.equalsIgnoreCase("quit")) { done = true; } else if (operation.equals("add")) { addInstance(args, client, command, servers); } else if (operation.equals("delete")) { deleteInstance(args, command, servers); } else if (operation.equals("random")) { listRandomInstance(args, serviceDiscovery, providers, command); } else if (operation.equals("list")) { listInstances(serviceDiscovery); } } } finally { for (ExampleServer server : servers) { IOUtils.closeQuietly(server); } } } private static void listRandomInstance(String[] args, ServiceDiscovery<InstanceDetails> serviceDiscovery, Map<String, ServiceProvider<InstanceDetails>> providers, String command) throws Exception { // this shows how to use a ServiceProvider // in a real application you'd create the ServiceProvider early for the service(s) you're interested in if (args.length != 1) { System.err.println("syntax error (expected random <name>): " + command); return; } String serviceName = args[0]; ServiceProvider<InstanceDetails> provider = providers.get(serviceName); if (provider == null) { provider = serviceDiscovery.serviceProviderBuilder().serviceName(serviceName) .providerStrategy(new RandomStrategy<InstanceDetails>()).build(); providers.put(serviceName, provider); provider.start(); Thread.sleep(2500); // give the provider time to warm up - in a real application you wouldn't need to do this } ServiceInstance<InstanceDetails> instance = provider.getInstance(); if (instance == null) { System.err.println("No instances named: " + serviceName); } else { outputInstance(instance); } } private static void listInstances(ServiceDiscovery<InstanceDetails> serviceDiscovery) throws Exception { // This shows how to query all the instances in service discovery try { Collection<String> serviceNames = serviceDiscovery.queryForNames(); System.out.println(serviceNames.size() + " type(s)"); for (String serviceName : serviceNames) { Collection<ServiceInstance<InstanceDetails>> instances = serviceDiscovery .queryForInstances(serviceName); System.out.println(serviceName); for (ServiceInstance<InstanceDetails> instance : instances) { outputInstance(instance); } } } finally { IOUtils.closeQuietly(serviceDiscovery); } } private static void outputInstance(ServiceInstance<InstanceDetails> instance) { System.out.println("\t" + instance.getPayload().getDescription() + ": " + instance.buildUriSpec()); } private static void deleteInstance(String[] args, String command, List<ExampleServer> servers) { // simulate a random instance going down // in a real application, this would occur due to normal operation, a crash, maintenance, etc. if (args.length != 1) { System.err.println("syntax error (expected delete <name>): " + command); return; } final String serviceName = args[0]; ExampleServer server = Iterables.find(servers, new Predicate<ExampleServer>() { @Override public boolean apply(ExampleServer server) { return server.getThisInstance().getName().endsWith(serviceName); } }, null); if (server == null) { System.err.println("No servers found named: " + serviceName); return; } servers.remove(server); IOUtils.closeQuietly(server); System.out.println("Removed a random instance of: " + serviceName); } private static void addInstance(String[] args, CuratorFramework client, String command, List<ExampleServer> servers) throws Exception { // simulate a new instance coming up // in a real application, this would be a separate process if (args.length < 2) { System.err.println("syntax error (expected add <name> <description>): " + command); return; } StringBuilder description = new StringBuilder(); for (int i = 1; i < args.length; ++i) { if (i > 1) { description.append(' '); } description.append(args[i]); } String serviceName = args[0]; ExampleServer server = new ExampleServer(client, PATH, serviceName, description.toString()); servers.add(server); server.start(); System.out.println(serviceName + " added"); } private static void printHelp() { System.out.println( "An example of using the ServiceDiscovery APIs. This example is driven by entering commands at the prompt:\n"); System.out.println("add <name> <description>: Adds a mock service with the given name and description"); System.out.println("delete <name>: Deletes one of the mock services with the given name"); System.out.println("list: Lists all the currently registered services"); System.out.println("random <name>: Lists a random instance of the service with the given name"); System.out.println("quit: Quit the example"); System.out.println(); } }