Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IGNITE-12179 #6878

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -305,10 +305,16 @@ public int execute(List<String> rawArgs) {
if (isConnectionError(e)) {
IgniteCheckedException cause = X.cause(e, IgniteCheckedException.class);

if (cause != null && cause.getMessage() != null && cause.getMessage().contains("SSL"))
e = cause;
if (isConnectionClosedSilentlyException(e))
logger.severe("Connection to cluster failed. Please check firewall settings and " +
"client and server are using the same SSL configuration.");
else {
if (isSSLMisconfigurationError(cause))
e = cause;

logger.severe("Connection to cluster failed. " + CommandLogger.errorMessage(e));
logger.severe("Connection to cluster failed. " + CommandLogger.errorMessage(e));

}

logger.info("Command [" + commandName + "] finished with code: " + EXIT_CODE_CONNECTION_FAILED);

Expand Down Expand Up @@ -343,6 +349,53 @@ public int execute(List<String> rawArgs) {
}
}

/**
* Analyses passed exception to find out whether it is related to SSL misconfiguration issues.
*
* (!) Implementation depends heavily on structure of exception stack trace
* thus is very fragile to any changes in that structure.
*
* @param e Exception to analyze.
*
* @return {@code True} if exception may be related to SSL misconfiguration issues.
*/
private boolean isSSLMisconfigurationError(Throwable e) {
return e != null && e.getMessage() != null && e.getMessage().contains("SSL");
}

/**
* Analyses passed exception to find out whether it is caused by server closing connection silently.
* This happens when client tries to establish unprotected connection
* to the cluster supporting only secured communications (e.g. when server is configured to use SSL certificates
* and client is not).
*
* (!) Implementation depends heavily on structure of exception stack trace
* thus is very fragile to any changes in that structure.
*
* @param e Exception to analyse.
* @return {@code True} if exception may be related to the attempt to establish unprotected connection
* to secured cluster.
*/
private boolean isConnectionClosedSilentlyException(Throwable e) {
if (!(e instanceof GridClientDisconnectedException))
return false;

Throwable cause = e.getCause();

if (cause == null)
return false;

cause = cause.getCause();

if (cause instanceof GridClientConnectionResetException &&
cause.getMessage() != null &&
cause.getMessage().contains("Failed to perform handshake")
)
return true;

return false;
}

/**
* Does one of three things:
* <ul>
Expand Down
Expand Up @@ -17,6 +17,15 @@

package org.apache.ignite.internal.processors.cache;

import javax.cache.Cache;
import javax.cache.CacheException;
import javax.cache.expiry.Duration;
import javax.cache.expiry.ExpiryPolicy;
import javax.cache.expiry.TouchedExpiryPolicy;
import javax.cache.processor.EntryProcessor;
import javax.cache.processor.EntryProcessorException;
import javax.cache.processor.EntryProcessorResult;
import javax.cache.processor.MutableEntry;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
Expand All @@ -38,15 +47,6 @@
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import javax.cache.Cache;
import javax.cache.CacheException;
import javax.cache.expiry.Duration;
import javax.cache.expiry.ExpiryPolicy;
import javax.cache.expiry.TouchedExpiryPolicy;
import javax.cache.processor.EntryProcessor;
import javax.cache.processor.EntryProcessorException;
import javax.cache.processor.EntryProcessorResult;
import javax.cache.processor.MutableEntry;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import org.apache.ignite.Ignite;
Expand Down Expand Up @@ -4319,7 +4319,7 @@ public void testTtlNoTxOldEntry() throws Exception {
* @throws Exception If failed.
*/
private void checkTtl(boolean inTx, boolean oldEntry) throws Exception {
int ttl = 1000;
int ttl = 4000;

final ExpiryPolicy expiry = new TouchedExpiryPolicy(new Duration(MILLISECONDS, ttl));

Expand Down
Expand Up @@ -18,6 +18,7 @@
package org.apache.ignite.spi.communication.tcp;

import java.io.IOException;
import java.net.BindException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.util.Collections;
Expand Down Expand Up @@ -60,6 +61,9 @@ public class TcpCommunicationSpiFaultyClientTest extends GridCommonAbstractTest
}
};

/** Server port for {@link FakeServer}. */
private static int serverPort = 47200;

/** Client mode. */
private static boolean clientMode;

Expand Down Expand Up @@ -107,9 +111,29 @@ public class TcpCommunicationSpiFaultyClientTest extends GridCommonAbstractTest
@Override protected void beforeTestsStarted() throws Exception {
super.beforeTestsStarted();

serverPort = takeFreePort();

System.setProperty(IgniteSystemProperties.IGNITE_ENABLE_FORCIBLE_NODE_KILL, "true");
}

/**
* @throws IOException If failed.
*/
private static int takeFreePort() throws IOException {
int freePort = serverPort;

while(true) {
try {
U.closeQuiet(startServerSocket(freePort));

return freePort;
}
catch (BindException ignore) { //If address already in use (Bind failed) t trying to choose another one.
freePort++;
}
}
}

/** {@inheritDoc} */
@Override protected void afterTestsStopped() throws Exception {
super.afterTestsStopped();
Expand Down Expand Up @@ -283,6 +307,13 @@ private void testFailClient(FakeServer srv, long expDelay) throws Exception {
}
}

/**
* @throws IOException If failed.
*/
private static ServerSocket startServerSocket(int port) throws IOException {
return new ServerSocket(port, 50, InetAddress.getByName("127.0.0.1"));
}

/**
* Server that emulates connection troubles.
*/
Expand All @@ -297,7 +328,7 @@ private static class FakeServer implements Runnable {
* Default constructor.
*/
FakeServer() throws IOException {
srv = new ServerSocket(47200, 50, InetAddress.getByName("127.0.0.1"));
srv = startServerSocket(serverPort);
}

/**
Expand Down Expand Up @@ -336,7 +367,7 @@ private static class TestCommunicationSpi extends TcpCommunicationSpi {
Map<String, Object> attrs = new HashMap<>(node.attributes());

attrs.put(createAttributeName(ATTR_ADDRS), Collections.singleton("127.0.0.1"));
attrs.put(createAttributeName(ATTR_PORT), 47200);
attrs.put(createAttributeName(ATTR_PORT), serverPort);
attrs.put(createAttributeName(ATTR_EXT_ADDRS), Collections.emptyList());
attrs.put(createAttributeName(ATTR_HOST_NAMES), Collections.emptyList());

Expand Down
Expand Up @@ -17,9 +17,9 @@

package org.apache.ignite.spi.communication.tcp;

import javax.cache.Cache;
import java.lang.management.ManagementFactory;
import java.util.Iterator;
import javax.cache.Cache;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteDataStreamer;
import org.apache.ignite.IgniteLogger;
Expand Down Expand Up @@ -103,7 +103,7 @@ public class TcpCommunicationSpiFreezingClientTest extends GridCommonAbstractTes
@Test
public void testFreezingClient() throws Exception {
try {
final IgniteEx srv = startGrid(0);
final IgniteEx srv = startGrids(2);

final IgniteEx client = startGrid("client");

Expand Down
Expand Up @@ -106,6 +106,30 @@ private void activate(String nodeCipherSuite, String utilityCipherSuite, int exp
assertEquals(EXIT_CODE_CONNECTION_FAILED, cmd.execute(Arrays.asList("--deactivate", "--yes")));
}

/**
* Verifies that when client without SSL tries to connect to SSL-enabled cluster,
* it fails and prints clear message with possible causes to output.
*
* @throws Exception If test failed.
*/
@Test
public void testClientWithoutSslConnectsToSslEnabledCluster() throws Exception {
startGrid(0);

List<String> params = new ArrayList<>();

params.add("--activate");

injectTestSystemOut();

assertEquals(EXIT_CODE_CONNECTION_FAILED, execute(params));

String out = testOut.toString();

assertContains(log, out, "firewall settings");
assertContains(log, out, "SSL configuration");
}

/**
* @throws Exception If test failed.
*/
Expand Down