/** * Connects this member to the cluster using the given <code>loadFactor</code>. The <code> * loadFactor</code> defines the (approximate) relative load that this member will receive. * * <p>A good default value is 100, which will give this member 100 nodes on the distributed hash * ring. Giving all members (proportionally) lower values will result in a less evenly distributed * hash. * * @param loadFactor The load factor for this node. * @throws ConnectionFailedException when an error occurs while connecting */ public synchronized void connect(int loadFactor) throws ConnectionFailedException { this.currentLoadFactor = loadFactor; Assert.isTrue(loadFactor >= 0, "Load Factor must be a positive integer value."); Assert.isTrue( channel.getReceiver() == null || channel.getReceiver() == messageReceiver, "The given channel already has a receiver configured. " + "Has the channel been reused with other Connectors?"); try { channel.setReceiver(messageReceiver); if (channel.isConnected() && !clusterName.equals(channel.getClusterName())) { throw new AxonConfigurationException( "The Channel that has been configured with this JGroupsConnector " + "is already connected to another cluster."); } else if (channel.isConnected()) { // we need to fetch state now that we have attached our MessageReceiver channel.getState(null, 10000); } else { // we need to connect. This will automatically fetch state as well. channel.connect(clusterName, null, 10000); } updateMembership(); } catch (Exception e) { joinedCondition.markJoined(false); channel.disconnect(); throw new ConnectionFailedException("Failed to connect to JGroupsConnectorFactoryBean", e); } }
@Test public void testJoinMessageReceivedForDisconnectedHost() throws Exception { final AtomicInteger counter1 = new AtomicInteger(0); final AtomicInteger counter2 = new AtomicInteger(0); connector1.subscribe(String.class.getName(), new CountingCommandHandler(counter1)); connector1.connect(20); assertTrue( "Expected connector 1 to connect within 10 seconds", connector1.awaitJoined(10, TimeUnit.SECONDS)); connector2.subscribe(String.class.getName(), new CountingCommandHandler(counter2)); connector2.connect(80); assertTrue("Connector 2 failed to connect", connector2.awaitJoined()); // wait for both connectors to have the same view waitForConnectorSync(); ConsistentHash hashBefore = connector1.getConsistentHash(); // secretly insert an illegal message channel1 .getReceiver() .receive( new Message( channel1.getAddress(), new IpAddress(12345), new JoinMessage(10, Collections.<String>emptySet()))); ConsistentHash hash2After = connector1.getConsistentHash(); assertEquals("That message should not have changed the ring", hashBefore, hash2After); }
private static void injectView(View view, JChannel... channels) { for (JChannel ch : channels) { ch.down(new Event(Event.VIEW_CHANGE, view)); ch.up(new Event(Event.VIEW_CHANGE, view)); } for (JChannel ch : channels) { MyReceiver receiver = (MyReceiver) ch.getReceiver(); System.out.println("[" + receiver.name + "] view=" + ch.getView()); } }
@Test public void testSetupOfReplyingCallback() throws InterruptedException { final String mockPayload = "DummyString"; final CommandMessage<String> commandMessage = new GenericCommandMessage<>(mockPayload); final DispatchMessage dispatchMessage = new DispatchMessage(commandMessage, serializer, true); final Message message = new Message(channel1.getAddress(), dispatchMessage); connector1.connect(20); assertTrue( "Expected connector 1 to connect within 10 seconds", connector1.awaitJoined(10, TimeUnit.SECONDS)); channel1.getReceiver().receive(message); // Verify that the newly introduced ReplyingCallBack class is being wired in. Actual behaviour // of ReplyingCallback is tested in its unit tests verify(mockCommandBus1).dispatch(any(), any(ReplyingCallback.class)); }