package com.jivesoftware.os.amza.embed; import com.google.common.base.Strings; import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.jivesoftware.os.amza.api.ring.RingHost; import com.jivesoftware.os.amza.api.ring.RingMember; import com.jivesoftware.os.amza.service.AmzaRingStoreWriter; import com.jivesoftware.os.amza.service.AmzaService; import com.jivesoftware.os.mlogger.core.MetricLogger; import com.jivesoftware.os.mlogger.core.MetricLoggerFactory; import com.jivesoftware.os.routing.bird.deployable.Deployable; import com.jivesoftware.os.routing.bird.shared.ConnectionDescriptor; import com.jivesoftware.os.routing.bird.shared.ConnectionDescriptors; import com.jivesoftware.os.routing.bird.shared.HostPort; import com.jivesoftware.os.routing.bird.shared.InstanceDescriptor; import com.jivesoftware.os.routing.bird.shared.TenantRoutingProvider; import com.jivesoftware.os.routing.bird.shared.TenantsServiceConnectionDescriptorProvider; import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; /** * @author jonathan.colt */ public class RoutingBirdAmzaDiscovery implements Runnable { private static final MetricLogger LOG = MetricLoggerFactory.getLogger(); private final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1, new ThreadFactoryBuilder().setNameFormat("routing-bird-discovery-%d").build()); private final Deployable deployable; private final String serviceName; private final AmzaService amzaService; private final long discoveryIntervalMillis; private final Set<RingMember> blacklistRingMembers; private final AtomicInteger systemRingSize; public RoutingBirdAmzaDiscovery(Deployable deployable, String serviceName, AmzaService amzaService, long discoveryIntervalMillis, Set<RingMember> blacklistRingMembers, AtomicInteger systemRingSize) { this.deployable = deployable; this.serviceName = serviceName; this.amzaService = amzaService; this.discoveryIntervalMillis = discoveryIntervalMillis; this.blacklistRingMembers = blacklistRingMembers; this.systemRingSize = systemRingSize; } public void start() { scheduledExecutorService.scheduleWithFixedDelay(this, 0, discoveryIntervalMillis, TimeUnit.MILLISECONDS); } public void stop() { scheduledExecutorService.shutdownNow(); } @Override public void run() { try { TenantRoutingProvider tenantRoutingProvider = deployable.getTenantRoutingProvider(); TenantsServiceConnectionDescriptorProvider connections = tenantRoutingProvider.getConnections(serviceName, "main", discoveryIntervalMillis); ConnectionDescriptors selfConnections = connections.getConnections(""); for (ConnectionDescriptor connectionDescriptor : selfConnections.getConnectionDescriptors()) { InstanceDescriptor routingInstanceDescriptor = connectionDescriptor.getInstanceDescriptor(); RingMember routingRingMember = new RingMember( Strings.padStart(String.valueOf(routingInstanceDescriptor.instanceName), 5, '0') + "_" + routingInstanceDescriptor.instanceKey); if (!blacklistRingMembers.contains(routingRingMember)) { HostPort hostPort = connectionDescriptor.getHostPort(); InstanceDescriptor instanceDescriptor = connectionDescriptor.getInstanceDescriptor(); AmzaRingStoreWriter ringWriter = amzaService.getRingWriter(); ringWriter.register(routingRingMember, new RingHost(instanceDescriptor.datacenter, instanceDescriptor.rack, hostPort.getHost(), hostPort.getPort()), -1, false); } } systemRingSize.set(selfConnections.getConnectionDescriptors().size()); } catch (Exception x) { LOG.warn("Failed while calling routing bird discovery.", x); } } }