package com.limegroup.gnutella.util; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.concurrent.ScheduledExecutorService; import org.limewire.core.settings.UltrapeerSettings; import org.limewire.io.NetworkInstanceUtils; import org.limewire.net.ConnectionDispatcher; import org.limewire.net.SocketsManager; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; import com.google.inject.name.Named; import com.limegroup.gnutella.ConnectionManagerImpl; import com.limegroup.gnutella.ConnectionServices; import com.limegroup.gnutella.HostCatcher; import com.limegroup.gnutella.NetworkManager; import com.limegroup.gnutella.NodeAssigner; import com.limegroup.gnutella.QueryUnicaster; import com.limegroup.gnutella.connection.ConnectionCheckerManager; import com.limegroup.gnutella.connection.RoutedConnection; import com.limegroup.gnutella.connection.RoutedConnectionFactory; import com.limegroup.gnutella.filters.IPFilter; import com.limegroup.gnutella.messages.PingRequestFactory; import com.limegroup.gnutella.messages.QueryRequest; import com.limegroup.gnutella.messages.QueryRequestFactory; import com.limegroup.gnutella.messages.vendor.CapabilitiesVMFactory; import com.limegroup.gnutella.routing.QueryRouteTable; import com.limegroup.gnutella.simpp.SimppManager; /** * Helper class that supplies the list of connections for searching. */ @Singleton public class TestConnectionManager extends ConnectionManagerImpl { /** * The list of ultrapeer <tt>Connection</tt> instances */ private final List<RoutedConnection> CONNECTIONS = new LinkedList<RoutedConnection>(); /** * The list of leaf <tt>Connection</tt> instances */ private final List<RoutedConnection> LEAF_CONNECTIONS = new LinkedList<RoutedConnection>(); /** * Constant for whether or not this should be considered an * Ultrapeer. */ private boolean ULTRAPEER; /** * Constant for the number of Ultrapeer connections that the * test connection manager should maintain. */ private int NUM_CONNECTIONS; /** * Constant for the number of leaf connections that the test * connection manager should maintain. */ private int NUM_LEAF_CONNECTIONS; /** * Constant array for the keywords that I should have (this node). */ private String[] MY_KEYWORDS; private int numNewConnections; private boolean useVaried; /** * Constant array for the keywords that I should have (this node) * by default, unless the caller specifies otherwise. */ private static final String[] DEFAULT_MY_KEYWORDS = { "me", }; /** * Constant array for the keywords for Ultrapeers to use. */ private static final String[] ULTRAPEER_KEYWORDS = { "qwe", "wer", "ert", "rty", "tyu", "yui", "uio", "iop", "opa ", "pas", "asd", "sdf", "dfg", "fgh", "ghj", "hjk", "jkl", "klz", "lzx", "zxc", "xcv", "cvb", "vbn", "bnm", "qwer", "wert", "erty", "rtyu", "tyui", "yuio", }; /** * Constant array for the keywords for leaves to use. */ private static final String[] LEAF_KEYWORDS = { "this", "is", "a", "test", "for", "query", "routing", "in", "all", "its", "forms", "including", "both", "leaves", "and", "Ultrapeers", "which", "should", "both", "work", "like", "we", "expect", "them", "to", "at", "least", "in", "theory", "and", "hopefully", "in", "fact", "as", "well", "but", "it's", "hard", "to", "know", }; /** * Array of keywords that should not match anything in the routing * tables. */ private static final String[] UNMATCHING_KEYWORDS = { "miss", "NCWEPHCE", "IEYWHFDSNC", "UIYRIEH", "dfjaivuih", }; private final QueryRequestFactory queryRequestFactory; private final TestConnectionFactory testConnectionFactory; @Inject public TestConnectionManager(NetworkManager networkManager, Provider<HostCatcher> hostCatcher, @Named("global") Provider<ConnectionDispatcher> connectionDispatcher, @Named("backgroundExecutor") ScheduledExecutorService backgroundExecutor, Provider<SimppManager> simppManager, CapabilitiesVMFactory capabilitiesVMFactory, RoutedConnectionFactory managedConnectionFactory, Provider<QueryUnicaster> queryUnicaster, SocketsManager socketsManager, ConnectionServices connectionServices, Provider<NodeAssigner> nodeAssigner, Provider<IPFilter> ipFilter, ConnectionCheckerManager connectionCheckerManager, PingRequestFactory pingRequestFactory, QueryRequestFactory queryRequestFactory, TestConnectionFactory testConnectionFactory, NetworkInstanceUtils networkInstanceUtils) { super(networkManager, hostCatcher, connectionDispatcher, backgroundExecutor, simppManager, capabilitiesVMFactory, managedConnectionFactory, queryUnicaster, socketsManager, connectionServices, nodeAssigner, ipFilter, connectionCheckerManager, pingRequestFactory, networkInstanceUtils); this.queryRequestFactory = queryRequestFactory; this.testConnectionFactory = testConnectionFactory; configureDefaultManager(); } public void configureDefaultManager() { setNumNewConnections(20); setUltraPeer(true); setNumConnections(20); setNumLeafConnections(UltrapeerSettings.MAX_LEAVES.getValue()); setKeywords(DEFAULT_MY_KEYWORDS); setUseVaried(false); } public void configureManagerWithVariedLeafs() { setNumNewConnections(20); setUltraPeer(true); setNumConnections(20); setNumLeafConnections(UltrapeerSettings.MAX_LEAVES.getValue()); setKeywords(DEFAULT_MY_KEYWORDS); setUseVaried(true); } public void setNumNewConnections(int numNewConnections) { this.numNewConnections = numNewConnections; } public void setUltraPeer(boolean ultraPeer) { ULTRAPEER = ultraPeer; } public void setNumConnections(int numConnections) { NUM_CONNECTIONS = numConnections; } public void setNumLeafConnections(int numLeafConnections) { NUM_LEAF_CONNECTIONS = numLeafConnections; } public void setKeywords(String[] keywords) { MY_KEYWORDS = keywords; } public void setUseVaried(boolean useVaried) { this.useVaried = useVaried; } public void resetAndInitialize() { CONNECTIONS.clear(); LEAF_CONNECTIONS.clear(); for(int i=0; i<NUM_CONNECTIONS; i++) { RoutedConnection curConn = null; if(i < numNewConnections) { curConn = testConnectionFactory.createUltrapeerConnection(new String[]{ULTRAPEER_KEYWORDS[i]}); } else { curConn = testConnectionFactory.createOldConnection(15); } CONNECTIONS.add(curConn); } // now, give ourselves the desired number of leaves for(int i=0; i<NUM_LEAF_CONNECTIONS; i++) { RoutedConnection conn; if(useVaried && i >= (NUM_LEAF_CONNECTIONS/2)) { conn = testConnectionFactory.createAltLeafConnection(); } else { conn = testConnectionFactory.createWithKeywords(new String[]{LEAF_KEYWORDS[i]}); } LEAF_CONNECTIONS.add(conn); } } /** * Test to make sure that the given <tt>QueryRouteTable</tt> has matches * for all of the expected keywords and that it doesn't have matches * for any of the unexpected keywords. * * @param qrt the <tt>QueryRouteTable</tt> instance to test */ public boolean runQRPMatch(QueryRouteTable qrt) { for(int i=0; i<MY_KEYWORDS.length; i++) { QueryRequest qr = queryRequestFactory.createQuery(MY_KEYWORDS[i]); if(!qrt.contains(qr)) return false; } for(int i=0; i<NUM_LEAF_CONNECTIONS; i++) { QueryRequest qr = queryRequestFactory.createQuery(LEAF_KEYWORDS[i]); if(!qrt.contains(qr)) return false; } for(int i=0; i<UNMATCHING_KEYWORDS.length; i++) { QueryRequest qr = queryRequestFactory.createQuery(UNMATCHING_KEYWORDS[i]); if(qrt.contains(qr)) return false; } return true; } /** * Accessor for the custom list of connections. */ @Override public List<RoutedConnection> getInitializedConnections() { return CONNECTIONS; } public void setInitializedConnections(List<RoutedConnection> connections) { CONNECTIONS.clear(); CONNECTIONS.addAll(connections); } @Override public List<RoutedConnection> getInitializedClientConnections() { return LEAF_CONNECTIONS; } @Override public boolean isSupernode() { return ULTRAPEER; } /** * Returns the total number of queries received over all Ultrapeer connections. */ public int getNumUltrapeerQueries() { return getNumQueries(CONNECTIONS); } /** * Returns the total number of queries received over all leaf connections. */ public int getNumLeafQueries() { return getNumQueries(LEAF_CONNECTIONS); } /** * Returns the total number of queries received over all leaf connections. */ private static int getNumQueries(Collection<RoutedConnection> connections) { int numQueries = 0; Iterator<RoutedConnection> iter = connections.iterator(); while(iter.hasNext()) { TestConnection tc = (TestConnection)iter.next(); numQueries += tc.getNumQueries(); } return numQueries; } /** * Returns the total number of queries received over all old connections. */ public int getNumOldConnectionQueries() { int numQueries = 0; Iterator<RoutedConnection> iter = CONNECTIONS.iterator(); while(iter.hasNext()) { TestConnection tc = (TestConnection)iter.next(); if(tc instanceof OldConnection) { numQueries += tc.getNumQueries(); } } return numQueries; } /** * Returns the total number of queries received over all old connections. */ public int getNumNewConnectionQueries() { int numQueries = 0; Iterator<RoutedConnection> iter = CONNECTIONS.iterator(); while(iter.hasNext()) { TestConnection tc = (TestConnection)iter.next(); if(tc instanceof NewConnection) { numQueries += tc.getNumQueries(); } } return numQueries; } public boolean isClientSupernodeConnection() { return false; } }