/**
  * 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));
  }