/*
* 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.activemq.artemis.tests.integration.remoting;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.activemq.artemis.api.core.TransportConfiguration;
import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.api.core.client.ServerLocator;
import org.apache.activemq.artemis.core.config.Configuration;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.junit.Assert;
import org.junit.Test;
public abstract class NetworkAddressTestBase extends ActiveMQTestBase {
// Constants -----------------------------------------------------
// Attributes ----------------------------------------------------
// Static --------------------------------------------------------
static {
try {
Map<NetworkInterface, InetAddress> map = NetworkAddressTestBase.getAddressForEachNetworkInterface();
StringBuilder s = new StringBuilder("using network settings:\n");
Set<Entry<NetworkInterface, InetAddress>> set = map.entrySet();
for (Entry<NetworkInterface, InetAddress> entry : set) {
s.append(entry.getKey().getDisplayName() + ": " + entry.getValue().getHostAddress() + "\n");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static Map<NetworkInterface, InetAddress> getAddressForEachNetworkInterface() throws Exception {
Map<NetworkInterface, InetAddress> map = new HashMap<>();
Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
while (ifaces.hasMoreElements()) {
NetworkInterface iface = ifaces.nextElement();
Enumeration<InetAddress> enumeration = iface.getInetAddresses();
while (enumeration.hasMoreElements()) {
InetAddress inetAddress = enumeration.nextElement();
if (inetAddress instanceof Inet4Address) {
map.put(iface, inetAddress);
break;
}
}
}
return map;
}
// Constructors --------------------------------------------------
// Public --------------------------------------------------------
@Test
public void testConnectToServerWithSameHost() throws Exception {
Map<NetworkInterface, InetAddress> map = NetworkAddressTestBase.getAddressForEachNetworkInterface();
if (map.size() > 0) {
Set<Entry<NetworkInterface, InetAddress>> set = map.entrySet();
Iterator<Entry<NetworkInterface, InetAddress>> iterator = set.iterator();
InetAddress address = iterator.next().getValue();
String host = address.getHostAddress();
testConnection(host, host, true, 0);
}
}
@Test
public void testConnectToServerAcceptingAllHosts() throws Exception {
Map<NetworkInterface, InetAddress> map = NetworkAddressTestBase.getAddressForEachNetworkInterface();
Set<Entry<NetworkInterface, InetAddress>> set = map.entrySet();
for (Entry<NetworkInterface, InetAddress> entry : set) {
String host = entry.getValue().getHostAddress();
testConnection("0.0.0.0", host, true, 0);
}
}
@Test
public void testConnectToServerAcceptingOnlyAnotherHost() throws Exception {
Map<NetworkInterface, InetAddress> map = NetworkAddressTestBase.getAddressForEachNetworkInterface();
if (map.size() <= 1) {
System.err.println("There must be at least 1 network interfaces: test will not be executed");
return;
}
Set<Entry<NetworkInterface, InetAddress>> set = map.entrySet();
Iterator<Entry<NetworkInterface, InetAddress>> iterator = set.iterator();
Entry<NetworkInterface, InetAddress> acceptorEntry = iterator.next();
Entry<NetworkInterface, InetAddress> connectorEntry = iterator.next();
testConnection(acceptorEntry.getValue().getHostName(), connectorEntry.getValue().getHostAddress(), false, 0);
}
@Test
public void testConnectToServerUsingLocalPort() throws Exception {
Map<NetworkInterface, InetAddress> map = NetworkAddressTestBase.getAddressForEachNetworkInterface();
if (map.size() <= 1) {
System.err.println("There must be at least 1 network interfaces: test will not be executed");
return;
}
Set<Entry<NetworkInterface, InetAddress>> set = map.entrySet();
Iterator<Entry<NetworkInterface, InetAddress>> iterator = set.iterator();
Entry<NetworkInterface, InetAddress> entry = iterator.next();
String host = entry.getValue().getHostAddress();
testConnection(host, host, true, 7777);
}
@Test
public void testConnectorToServerAcceptingAListOfHosts() throws Exception {
Map<NetworkInterface, InetAddress> map = NetworkAddressTestBase.getAddressForEachNetworkInterface();
if (map.size() <= 1) {
System.err.println("There must be at least 2 network interfaces: test will not be executed");
return;
}
Set<Entry<NetworkInterface, InetAddress>> set = map.entrySet();
Iterator<Entry<NetworkInterface, InetAddress>> iterator = set.iterator();
Entry<NetworkInterface, InetAddress> entry1 = iterator.next();
Entry<NetworkInterface, InetAddress> entry2 = iterator.next();
String listOfHosts = entry1.getValue().getHostAddress() + ", " + entry2.getValue().getHostAddress();
testConnection(listOfHosts, entry1.getValue().getHostAddress(), true, 0);
testConnection(listOfHosts, entry2.getValue().getHostAddress(), true, 0);
}
@Test
public void testConnectorToServerAcceptingAListOfHosts_2() throws Exception {
Map<NetworkInterface, InetAddress> map = NetworkAddressTestBase.getAddressForEachNetworkInterface();
if (map.size() <= 2) {
System.err.println("There must be at least 3 network interfaces: test will not be executed");
return;
}
Set<Entry<NetworkInterface, InetAddress>> set = map.entrySet();
Iterator<Entry<NetworkInterface, InetAddress>> iterator = set.iterator();
Entry<NetworkInterface, InetAddress> entry1 = iterator.next();
Entry<NetworkInterface, InetAddress> entry2 = iterator.next();
Entry<NetworkInterface, InetAddress> entry3 = iterator.next();
String listOfHosts = entry1.getValue().getHostAddress() + ", " + entry2.getValue().getHostAddress();
testConnection(listOfHosts, entry1.getValue().getHostAddress(), true, 0);
testConnection(listOfHosts, entry2.getValue().getHostAddress(), true, 0);
testConnection(listOfHosts, entry3.getValue().getHostAddress(), false, 0);
}
public void testConnection(final String acceptorHost,
final String connectorHost,
final boolean mustConnect,
final int localPort) throws Exception {
System.out.println("acceptor=" + acceptorHost + ", connector=" + connectorHost + ", mustConnect=" + mustConnect);
Map<String, Object> params = new HashMap<>();
params.put(getHostPropertyKey(), acceptorHost);
TransportConfiguration acceptorConfig = new TransportConfiguration(getAcceptorFactoryClassName(), params);
Set<TransportConfiguration> transportConfigs = new HashSet<>();
transportConfigs.add(acceptorConfig);
Configuration config = createDefaultNettyConfig();
config.setAcceptorConfigurations(transportConfigs);
ActiveMQServer messagingService = createServer(false, config);
try {
messagingService.start();
params = new HashMap<>();
params.put(getHostPropertyKey(), connectorHost);
if (localPort != 0) {
params.put(getLocalPortProperty(), localPort);
}
TransportConfiguration connectorConfig = new TransportConfiguration(getConnectorFactoryClassName(), params);
ServerLocator locator = addServerLocator(ActiveMQClient.createServerLocatorWithoutHA(connectorConfig));
if (mustConnect) {
ClientSessionFactory sf = createSessionFactory(locator);
if (localPort != 0) {
Iterator<RemotingConnection> iterator = messagingService.getRemotingService().getConnections().iterator();
Assert.assertTrue("no connection created", iterator.hasNext());
String address = iterator.next().getTransportConnection().getRemoteAddress();
Assert.assertTrue(address.endsWith(":" + localPort));
}
sf.close();
System.out.println("connection OK");
} else {
try {
locator.createSessionFactory();
Assert.fail("session creation must fail because connector must not be able to connect to the server bound to another network interface");
} catch (Exception e) {
}
}
} finally {
messagingService.stop();
}
}
// Package protected ---------------------------------------------
// Protected -----------------------------------------------------
protected abstract String getAcceptorFactoryClassName();
protected abstract String getConnectorFactoryClassName();
protected abstract String getHostPropertyKey();
protected abstract String getLocalPortProperty();
// Private -------------------------------------------------------
// Inner classes -------------------------------------------------
}