package codeine; import java.util.Collection; import java.util.List; import java.util.Set; import java.util.concurrent.ThreadPoolExecutor; import org.apache.log4j.Logger; import codeine.api.NodeGetter; import codeine.api.NodeInfo; import codeine.api.NodeWithMonitorsInfo; import codeine.configuration.Links; import codeine.executer.ThreadPoolUtils; import codeine.jsons.nodes.NodeDiscoveryStrategy; import codeine.jsons.peer_status.PeerStatusJsonV2; import codeine.jsons.peer_status.PeerType; import codeine.jsons.peer_status.PeersProjectsStatus; import codeine.jsons.project.ProjectJson; import codeine.model.Constants; import codeine.utils.ExceptionUtils; import codeine.utils.StringUtils; import codeine.utils.network.HttpUtils; import com.google.common.base.Stopwatch; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.inject.Inject; public class ProjectConfigurationInPeerUpdater{ private static final Logger log = Logger.getLogger(ProjectConfigurationInPeerUpdater.class); @Inject private PeersProjectsStatus peersProjectsStatus; @Inject private NodeGetter nodeGetter; @Inject private Links links; private ThreadPoolExecutor threadPool = ThreadPoolUtils.newThreadPool(10, "ProjectConfigurationInPeerUpdater"); private void sendUpdateToPeers(Collection<PeerStatusJsonV2> allPeers) { Stopwatch s = Stopwatch.createStarted(); List<PeerStatusJsonV2> failedPeers = Lists.newArrayList(); log.info("sending refresh request to " + allPeers.size() + " peers"); for (PeerStatusJsonV2 e : allPeers) { try { if (e.peer_type() == PeerType.Reporter) { log.debug("reporter peer, will not push configuration " + e); continue; } String result = HttpUtils.doGET(links.getPeerLink(e.address_port() + Constants.RELOAD_CONFIGURATION_CONTEXT),null, HttpUtils.SHORT_READ_TIMEOUT_MILLI); log.debug("updated " + e.address_port() + " result " + result); } catch (Exception e1) { failedPeers.add(e); log.warn("fail to push conf " + e.address_port() + " " + ExceptionUtils.getRootCauseMessage(e1)); } } log.info("finished to send refresh request to " + allPeers.size() + " peers, failed to send to " + failedPeers.size() + " ; took " + s); } public void updateAllPeers() { executeOnThreadPool(peersProjectsStatus.peer_to_projects().values()); } private void executeOnThreadPool(final Collection<PeerStatusJsonV2> allPeers) { log.info("adding task to thread pool " + threadPool); threadPool.execute(new Runnable() { @Override public void run() { sendUpdateToPeers(allPeers); } }); } public void updatePeers(ProjectJson updatedProject, ProjectJson previousProject) { Collection<PeerStatusJsonV2> peers = Sets.newHashSet(); List<NodeWithMonitorsInfo> nodes = nodeGetter.getNodes(updatedProject.name()); for (NodeWithMonitorsInfo node : nodes) { peers.add(node.peer()); } peers.addAll(getPeersFromProject(updatedProject)); peers.addAll(getPeersFromProject(previousProject)); executeOnThreadPool(peers); } private Collection<? extends PeerStatusJsonV2> getPeersFromProject(ProjectJson project) { Collection<PeerStatusJsonV2> peers = Sets.newHashSet(); if (null == project || project.node_discovery_startegy() != NodeDiscoveryStrategy.Configuration) { return peers; } Set<String> nodes = Sets.newHashSet(); for (NodeInfo node : project.nodes_info()) { String name = node.name(); if (name.contains(":")) { name = name.substring(0, name.indexOf(":")); } nodes.add(name.toLowerCase()); } for (PeerStatusJsonV2 peer : peersProjectsStatus.peer_to_projects().values()) { if (null != peer.host()) { if (nodes.contains(StringUtils.toLowerCase(peer.host()))) { peers.add(peer); } } } return peers; } }