use of org.apache.flink.runtime.rpc.exceptions.RpcConnectionException in project flink by apache.
the class AkkaRpcActor method handleRpcInvocation.
/**
* Handle rpc invocations by looking up the rpc method on the rpc endpoint and calling this
* method with the provided method arguments. If the method has a return value, it is returned
* to the sender of the call.
*
* @param rpcInvocation Rpc invocation message
*/
private void handleRpcInvocation(RpcInvocation rpcInvocation) {
Method rpcMethod = null;
try {
String methodName = rpcInvocation.getMethodName();
Class<?>[] parameterTypes = rpcInvocation.getParameterTypes();
rpcMethod = lookupRpcMethod(methodName, parameterTypes);
} catch (final NoSuchMethodException e) {
log.error("Could not find rpc method for rpc invocation.", e);
RpcConnectionException rpcException = new RpcConnectionException("Could not find rpc method for rpc invocation.", e);
getSender().tell(new Status.Failure(rpcException), getSelf());
}
if (rpcMethod != null) {
try {
// this supports declaration of anonymous classes
rpcMethod.setAccessible(true);
final Method capturedRpcMethod = rpcMethod;
if (rpcMethod.getReturnType().equals(Void.TYPE)) {
// No return value to send back
runWithContextClassLoader(() -> capturedRpcMethod.invoke(rpcEndpoint, rpcInvocation.getArgs()), flinkClassLoader);
} else {
final Object result;
try {
result = runWithContextClassLoader(() -> capturedRpcMethod.invoke(rpcEndpoint, rpcInvocation.getArgs()), flinkClassLoader);
} catch (InvocationTargetException e) {
log.debug("Reporting back error thrown in remote procedure {}", rpcMethod, e);
// tell the sender about the failure
getSender().tell(new Status.Failure(e.getTargetException()), getSelf());
return;
}
final String methodName = rpcMethod.getName();
if (result instanceof CompletableFuture) {
final CompletableFuture<?> responseFuture = (CompletableFuture<?>) result;
sendAsyncResponse(responseFuture, methodName);
} else {
sendSyncResponse(result, methodName);
}
}
} catch (Throwable e) {
log.error("Error while executing remote procedure call {}.", rpcMethod, e);
// tell the sender about the failure
getSender().tell(new Status.Failure(e), getSelf());
}
}
}
use of org.apache.flink.runtime.rpc.exceptions.RpcConnectionException in project flink by apache.
the class RpcConnectionTest method testConnectFailure.
@Test
public void testConnectFailure() throws Exception {
// we start the RPC service with a very long timeout to ensure that the test
// can only pass if the connection problem is not recognized merely via a timeout
Configuration configuration = new Configuration();
configuration.set(AkkaOptions.ASK_TIMEOUT_DURATION, Duration.ofSeconds(10000000));
final RpcService rpcService = RpcSystem.load().localServiceBuilder(configuration).withBindAddress("localhost").withBindPort(0).createAndStart();
try {
CompletableFuture<TaskExecutorGateway> future = rpcService.connect("foo.bar.com.test.invalid", TaskExecutorGateway.class);
future.get(10000000, TimeUnit.SECONDS);
fail("should never complete normally");
} catch (TimeoutException e) {
fail("should not fail with a generic timeout exception");
} catch (ExecutionException e) {
// that is what we want
assertTrue(e.getCause() instanceof RpcConnectionException);
assertTrue("wrong error message", e.getCause().getMessage().contains("foo.bar.com.test.invalid"));
} catch (Throwable t) {
fail("wrong exception: " + t);
} finally {
rpcService.stopService().get();
}
}
use of org.apache.flink.runtime.rpc.exceptions.RpcConnectionException in project flink by apache.
the class RpcSSLAuthITCase method testConnectFailure.
@Test
public void testConnectFailure() throws Exception {
final Configuration baseConfig = new Configuration();
baseConfig.setString(AkkaOptions.TCP_TIMEOUT, "1 s");
// we start the RPC service with a very long timeout to ensure that the test
// can only pass if the connection problem is not recognized merely via a timeout
baseConfig.set(AkkaOptions.ASK_TIMEOUT_DURATION, Duration.ofSeconds(10000000));
// !!! This config has KEY_STORE_FILE / TRUST_STORE_FILE !!!
Configuration sslConfig1 = new Configuration(baseConfig);
sslConfig1.setBoolean(SecurityOptions.SSL_INTERNAL_ENABLED, true);
sslConfig1.setString(SecurityOptions.SSL_INTERNAL_KEYSTORE, KEY_STORE_FILE);
sslConfig1.setString(SecurityOptions.SSL_INTERNAL_TRUSTSTORE, TRUST_STORE_FILE);
sslConfig1.setString(SecurityOptions.SSL_INTERNAL_KEYSTORE_PASSWORD, "password");
sslConfig1.setString(SecurityOptions.SSL_INTERNAL_KEY_PASSWORD, "password");
sslConfig1.setString(SecurityOptions.SSL_INTERNAL_TRUSTSTORE_PASSWORD, "password");
sslConfig1.setString(SecurityOptions.SSL_ALGORITHMS, "TLS_RSA_WITH_AES_128_CBC_SHA");
// !!! This config has KEY_STORE_FILE / UNTRUSTED_KEY_STORE_FILE !!!
// If this is presented by a client, it will trust the server, but the server will
// not trust this client in case client auth is enabled.
Configuration sslConfig2 = new Configuration(baseConfig);
sslConfig2.setBoolean(SecurityOptions.SSL_INTERNAL_ENABLED, true);
sslConfig2.setString(SecurityOptions.SSL_INTERNAL_KEYSTORE, UNTRUSTED_KEY_STORE_FILE);
sslConfig2.setString(SecurityOptions.SSL_INTERNAL_TRUSTSTORE, TRUST_STORE_FILE);
sslConfig2.setString(SecurityOptions.SSL_INTERNAL_KEYSTORE_PASSWORD, "password");
sslConfig2.setString(SecurityOptions.SSL_INTERNAL_KEY_PASSWORD, "password");
sslConfig2.setString(SecurityOptions.SSL_INTERNAL_TRUSTSTORE_PASSWORD, "password");
sslConfig2.setString(SecurityOptions.SSL_ALGORITHMS, "TLS_RSA_WITH_AES_128_CBC_SHA");
RpcService rpcService1 = null;
RpcService rpcService2 = null;
try {
// to test whether the test is still good:
// - create actorSystem2 with sslConfig1 (same as actorSystem1) and see that both can
// connect
// - set 'require-mutual-authentication = off' in the AkkaUtils ssl config section
rpcService1 = RpcSystem.load().localServiceBuilder(sslConfig1).withBindAddress("localhost").withBindPort(0).createAndStart();
rpcService2 = RpcSystem.load().localServiceBuilder(sslConfig2).withBindAddress("localhost").withBindPort(0).createAndStart();
TestEndpoint endpoint = new TestEndpoint(rpcService1);
endpoint.start();
CompletableFuture<TestGateway> future = rpcService2.connect(endpoint.getAddress(), TestGateway.class);
TestGateway gateway = future.get(10000000, TimeUnit.SECONDS);
CompletableFuture<String> fooFuture = gateway.foo();
fooFuture.get();
fail("should never complete normally");
} catch (ExecutionException e) {
// that is what we want
assertTrue(e.getCause() instanceof RpcConnectionException);
} finally {
final CompletableFuture<Void> rpcTerminationFuture1 = rpcService1 != null ? rpcService1.stopService() : CompletableFuture.completedFuture(null);
final CompletableFuture<Void> rpcTerminationFuture2 = rpcService2 != null ? rpcService2.stopService() : CompletableFuture.completedFuture(null);
FutureUtils.waitForAll(Arrays.asList(rpcTerminationFuture1, rpcTerminationFuture2)).get();
}
}
use of org.apache.flink.runtime.rpc.exceptions.RpcConnectionException in project flink by apache.
the class AkkaRpcService method connect.
// this method does not mutate state and is thus thread-safe
@Override
public <C extends RpcGateway> Future<C> connect(final String address, final Class<C> clazz) {
checkState(!stopped, "RpcService is stopped");
LOG.debug("Try to connect to remote RPC endpoint with address {}. Returning a {} gateway.", address, clazz.getName());
final ActorSelection actorSel = actorSystem.actorSelection(address);
final scala.concurrent.Future<Object> identify = Patterns.ask(actorSel, new Identify(42), timeout.toMilliseconds());
final scala.concurrent.Future<C> resultFuture = identify.map(new Mapper<Object, C>() {
@Override
public C checkedApply(Object obj) throws Exception {
ActorIdentity actorIdentity = (ActorIdentity) obj;
if (actorIdentity.getRef() == null) {
throw new RpcConnectionException("Could not connect to rpc endpoint under address " + address + '.');
} else {
ActorRef actorRef = actorIdentity.getRef();
final String address = AkkaUtils.getAkkaURL(actorSystem, actorRef);
final String hostname;
Option<String> host = actorRef.path().address().host();
if (host.isEmpty()) {
hostname = "localhost";
} else {
hostname = host.get();
}
InvocationHandler akkaInvocationHandler = new AkkaInvocationHandler(address, hostname, actorRef, timeout, maximumFramesize, null);
// Rather than using the System ClassLoader directly, we derive the ClassLoader
// from this class . That works better in cases where Flink runs embedded and all Flink
// code is loaded dynamically (for example from an OSGI bundle) through a custom ClassLoader
ClassLoader classLoader = AkkaRpcService.this.getClass().getClassLoader();
@SuppressWarnings("unchecked") C proxy = (C) Proxy.newProxyInstance(classLoader, new Class<?>[] { clazz }, akkaInvocationHandler);
return proxy;
}
}
}, actorSystem.dispatcher());
return new FlinkFuture<>(resultFuture);
}
Aggregations