package com.ctriposs.baiji.rpc.client.registry; import com.ctriposs.etcd.CEtcdClient; import com.ctriposs.etcd.CEtcdClientException; import com.ctriposs.etcd.CEtcdNode; import com.ctriposs.etcd.CEtcdResult; import java.net.URI; import java.util.ArrayList; import java.util.List; /** * Client used to access etcd service registry. */ public class EtcdRegistryClient implements RegistryClient { private static final String BASE_KEY = "/soa4j"; private final CEtcdClient _client; public EtcdRegistryClient(URI uri) { _client = new CEtcdClient(uri); } /** * Gets all instances of the given service from registry. * * @param serviceName the name of the service * @param serviceNamespace the namespace of the service * @param subEnv the sub environment of the instances to be fetched. nullable. * @return */ @Override public List<InstanceInfo> getServiceInstances(String serviceName, String serviceNamespace, String subEnv) { String key = getServiceKey(serviceName, serviceNamespace, subEnv); CEtcdResult result; try { result = _client.listChildren(key, true); } catch (CEtcdClientException e) { return null; } if (result == null || result.node == null || result.node.nodes == null) { return null; } List<InstanceInfo> instances = new ArrayList<InstanceInfo>(); for (CEtcdNode node : result.node.nodes) { if (!node.dir || node.nodes == null) { continue; } InstanceInfo instance = new InstanceInfo(); for (CEtcdNode propertyNode : node.nodes) { String propertyName = getPropertyName(propertyNode.key); switch (propertyName) { case "url": instance.setServiceUrl(propertyNode.value); break; case "up": boolean up = false; if (propertyNode.value != null) { up = Boolean.valueOf(propertyNode.value); } instance.setUp(up); break; } } if (instance.getServiceUrl() != null) { instances.add(instance); } } return instances; } private static String getServiceKey(String serviceName, String serviceNamespace, String subEnv) { String key = BASE_KEY + "/" + normalizeKey(serviceName) + "/" + normalizeKey(serviceNamespace); if (subEnv != null) { key += "/" + normalizeKey(subEnv); } return key; } private static String normalizeKey(String key) { return key != null ? key.replace('/', '_') : null; } private static String getPropertyName(String key) { int lastSlashIndex = key.lastIndexOf('/'); return key.substring(lastSlashIndex + 1); } }