/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ignite.spi.discovery.tcp;
import java.util.Collection;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import org.apache.ignite.Ignite;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.events.Event;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgnitePredicate;
import org.apache.ignite.spi.discovery.DiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder;
import org.apache.ignite.testframework.GridTestUtils;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.apache.ignite.events.EventType.EVT_CLIENT_NODE_DISCONNECTED;
import static org.apache.ignite.events.EventType.EVT_CLIENT_NODE_RECONNECTED;
/**
*
*/
public class TcpClientDiscoverySpiMulticastTest extends GridCommonAbstractTest {
/** */
private boolean forceSrv;
/** */
private ThreadLocal<Boolean> client = new ThreadLocal<>();
/** */
private ThreadLocal<Integer> discoPort = new ThreadLocal<>();
/** {@inheritDoc} */
@Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
cfg.setLocalHost("127.0.0.1");
TcpDiscoverySpi spi = new TcpDiscoverySpi();
TcpDiscoveryMulticastIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();
ipFinder.setAddressRequestAttempts(5);
spi.setIpFinder(ipFinder);
Boolean clientFlag = client.get();
client.set(null);
if (clientFlag != null && clientFlag) {
cfg.setClientMode(true);
spi.setForceServerMode(forceSrv);
}
else {
Integer port = discoPort.get();
discoPort.set(null);
if (port != null)
spi.setLocalPort(port);
}
cfg.setDiscoverySpi(spi);
return cfg;
}
/** {@inheritDoc} */
@Override protected void afterTest() throws Exception {
super.afterTest();
stopAllGrids();
}
/**
* @throws Exception If failed.
*/
public void testClientStartsFirst() throws Exception {
IgniteInternalFuture<Ignite> fut = GridTestUtils.runAsync(new Callable<Ignite>() {
@Override public Ignite call() throws Exception {
client.set(true);
return startGrid(0);
}
}, "start-client");
U.sleep(10_000);
discoPort.set(TcpDiscoverySpi.DFLT_PORT);
Ignite srv = startGrid(1);
Ignite client = fut.get();
final CountDownLatch reconnectLatch = new CountDownLatch(1);
final CountDownLatch disconnectLatch = new CountDownLatch(1);
client.events().localListen(new IgnitePredicate<Event>() {
@Override public boolean apply(Event evt) {
info("Client event: " + evt);
if (evt.type() == EVT_CLIENT_NODE_DISCONNECTED) {
assertEquals(1, reconnectLatch.getCount());
disconnectLatch.countDown();
}
else if (evt.type() == EVT_CLIENT_NODE_RECONNECTED) {
assertEquals(0, disconnectLatch.getCount());
reconnectLatch.countDown();
}
return true;
}
}, EVT_CLIENT_NODE_DISCONNECTED, EVT_CLIENT_NODE_RECONNECTED);
srv.close();
assertTrue(disconnectLatch.await(30, SECONDS));
discoPort.set(TcpDiscoverySpi.DFLT_PORT + 100);
startGrid(1);
assertTrue(reconnectLatch.await(30, SECONDS));
}
/**
* @throws Exception If failed.
*/
public void testJoinWithMulticast() throws Exception {
joinWithMulticast();
}
/**
* @throws Exception If failed.
*/
public void testJoinWithMulticastForceServer() throws Exception {
forceSrv = true;
joinWithMulticast();
}
/**
* @throws Exception If failed.
*/
private void joinWithMulticast() throws Exception {
Ignite ignite0 = startGrid(0);
assertSpi(ignite0, false);
client.set(true);
Ignite ignite1 = startGrid(1);
assertTrue(ignite1.configuration().isClientMode());
assertSpi(ignite1, !forceSrv);
assertTrue(ignite1.configuration().isClientMode());
assertEquals(2, ignite0.cluster().nodes().size());
assertEquals(2, ignite1.cluster().nodes().size());
client.set(false);
Ignite ignite2 = startGrid(2);
assertSpi(ignite2, false);
assertEquals(3, ignite0.cluster().nodes().size());
assertEquals(3, ignite1.cluster().nodes().size());
assertEquals(3, ignite2.cluster().nodes().size());
}
/**
* @param ignite Ignite.
* @param client Expected client mode flag.
*/
private void assertSpi(Ignite ignite, boolean client) {
DiscoverySpi spi = ignite.configuration().getDiscoverySpi();
assertSame(TcpDiscoverySpi.class, spi.getClass());
TcpDiscoverySpi spi0 = (TcpDiscoverySpi)spi;
assertSame(TcpDiscoveryMulticastIpFinder.class, spi0.getIpFinder().getClass());
assertEquals(client, spi0.isClientMode());
Collection<Object> addrSnds = GridTestUtils.getFieldValue(spi0.getIpFinder(), "addrSnds");
assertNotNull(addrSnds);
if (client)
assertTrue(addrSnds.isEmpty()); // Check client does not send its address.
else
assertFalse(addrSnds.isEmpty());
}
}