use of org.apache.drill.exec.rpc.RpcException in project drill by apache.
the class UserClient method authenticate.
private CheckedFuture<Void, SaslException> authenticate(final DrillProperties properties) {
final Map<String, String> propertiesMap = properties.stringPropertiesAsMap();
// Set correct QOP property and Strength based on server needs encryption or not.
// If ChunkMode is enabled then negotiate for buffer size equal to wrapChunkSize,
// If ChunkMode is disabled then negotiate for MAX_WRAPPED_SIZE buffer size.
propertiesMap.putAll(SaslProperties.getSaslProperties(connection.isEncryptionEnabled(), connection.getMaxWrappedSize()));
// use handleAuthFailure to setException
final SettableFuture<Void> authSettable = SettableFuture.create();
final CheckedFuture<Void, SaslException> authFuture = new AbstractCheckedFuture<Void, SaslException>(authSettable) {
@Override
protected SaslException mapException(Exception e) {
if (e instanceof ExecutionException) {
final Throwable cause = Throwables.getRootCause(e);
if (cause instanceof SaslException) {
return new SaslException(String.format("Authentication failed. [Details: %s, Error %s]", connection.getEncryptionCtxtString(), cause.getMessage()), cause);
}
}
return new SaslException(String.format("Authentication failed unexpectedly. [Details: %s, Error %s]", connection.getEncryptionCtxtString(), e.getMessage()), e);
}
};
final AuthenticatorFactory factory;
final String mechanismName;
final UserGroupInformation ugi;
final SaslClient saslClient;
try {
factory = getAuthenticatorFactory(properties);
mechanismName = factory.getSimpleName();
logger.trace("Will try to authenticate to server using {} mechanism with encryption context {}", mechanismName, connection.getEncryptionCtxtString());
ugi = factory.createAndLoginUser(propertiesMap);
saslClient = factory.createSaslClient(ugi, propertiesMap);
if (saslClient == null) {
throw new SaslException(String.format("Cannot initiate authentication using %s mechanism. Insufficient " + "credentials or selected mechanism doesn't support configured security layers?", factory.getSimpleName()));
}
connection.setSaslClient(saslClient);
} catch (final IOException e) {
authSettable.setException(e);
return authFuture;
}
logger.trace("Initiating SASL exchange.");
new AuthenticationOutcomeListener<>(this, connection, RpcType.SASL_MESSAGE, ugi, new RpcOutcomeListener<Void>() {
@Override
public void failed(RpcException ex) {
authSettable.setException(ex);
}
@Override
public void success(Void value, ByteBuf buffer) {
authComplete = true;
authSettable.set(null);
}
@Override
public void interrupted(InterruptedException e) {
authSettable.setException(e);
}
}).initiate(mechanismName);
return authFuture;
}
use of org.apache.drill.exec.rpc.RpcException in project drill by apache.
the class ControlClient method validateHandshake.
@Override
protected void validateHandshake(BitControlHandshake handshake) throws RpcException {
if (handshake.getRpcVersion() != ControlRpcConfig.RPC_VERSION) {
throw new RpcException(String.format("Invalid rpc version. Expected %d, actual %d.", handshake.getRpcVersion(), ControlRpcConfig.RPC_VERSION));
}
if (handshake.getAuthenticationMechanismsCount() != 0) {
// remote requires authentication
final SaslClient saslClient;
try {
final Map<String, String> saslProperties = SaslProperties.getSaslProperties(connection.isEncryptionEnabled(), connection.getMaxWrappedSize());
saslClient = config.getAuthFactory(handshake.getAuthenticationMechanismsList()).createSaslClient(UserGroupInformation.getLoginUser(), config.getSaslClientProperties(remoteEndpoint, saslProperties));
} catch (final IOException e) {
throw new RpcException(String.format("Failed to initiate authenticate to %s", remoteEndpoint.getAddress()), e);
}
if (saslClient == null) {
throw new RpcException("Unexpected failure. Could not initiate SASL exchange.");
}
connection.setSaslClient(saslClient);
} else {
if (config.getAuthMechanismToUse() != null) {
// local requires authentication
throw new RpcException(String.format("Drillbit (%s) does not require auth, but auth is enabled.", remoteEndpoint.getAddress()));
}
}
}
use of org.apache.drill.exec.rpc.RpcException in project drill by apache.
the class TestConvertFunctions method testBigIntVarCharReturnTripConvertLogical_ScalarReplaceON.
// TODO(DRILL-2326) temporary until we fix the scalar replacement bug for this case
@Test
// Because this test sometimes fails, sometimes succeeds
@Ignore
public void testBigIntVarCharReturnTripConvertLogical_ScalarReplaceON() throws Exception {
final OptionValue srOption = QueryTestUtil.setupScalarReplacementOption(bits[0], ScalarReplacementOption.ON);
boolean caughtException = false;
try {
// this used to fail (with a JUnit assertion) until we fix the SR bug
// Something in DRILL-5116 seemed to fix this problem, so the test now
// succeeds - sometimes.
testBigIntVarCharReturnTripConvertLogical();
} catch (RpcException e) {
caughtException = true;
} finally {
QueryTestUtil.restoreScalarReplacementOption(bits[0], srOption);
}
// Yes: sometimes this works, sometimes it does not...
assertTrue(!caughtException || caughtException);
}
use of org.apache.drill.exec.rpc.RpcException in project drill by axbaretto.
the class DrillClient method connect.
/**
* Start's a connection from client to server
* @param connect - Zookeeper connection string provided at connection URL
* @param props - not null {@link Properties} filled with connection url parameters
* @throws RpcException
*/
public synchronized void connect(String connect, Properties props) throws RpcException {
if (connected) {
return;
}
properties = DrillProperties.createFromProperties(props);
final List<DrillbitEndpoint> endpoints = new ArrayList<>();
if (isDirectConnection) {
// Populate the endpoints list with all the drillbit information provided in the connection string
endpoints.addAll(parseAndVerifyEndpoints(properties.getProperty(DrillProperties.DRILLBIT_CONNECTION), config.getString(ExecConstants.INITIAL_USER_PORT)));
} else {
if (ownsZkConnection) {
try {
this.clusterCoordinator = new ZKClusterCoordinator(this.config, connect);
this.clusterCoordinator.start(10000);
} catch (Exception e) {
throw new RpcException("Failure setting up ZK for client.", e);
}
}
// Gets the drillbit endpoints that are ONLINE and excludes the drillbits that are
// in QUIESCENT state. This avoids the clients connecting to drillbits that are
// shutting down thereby avoiding reducing the chances of query failures.
endpoints.addAll(clusterCoordinator.getOnlineEndPoints());
// Make sure we have at least one endpoint in the list
checkState(!endpoints.isEmpty(), "No active Drillbit endpoint found from ZooKeeper. Check connection parameters?");
}
// shuffle the collection then get the first endpoint
Collections.shuffle(endpoints);
eventLoopGroup = createEventLoop(config.getInt(ExecConstants.CLIENT_RPC_THREADS), "Client-");
executor = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), new NamedThreadFactory("drill-client-executor-")) {
@Override
protected void afterExecute(final Runnable r, final Throwable t) {
if (t != null) {
logger.error("{}.run() leaked an exception.", r.getClass().getName(), t);
}
super.afterExecute(r, t);
}
};
final String connectTriesConf = properties.getProperty(DrillProperties.TRIES, "5");
int connectTriesVal;
try {
connectTriesVal = Math.min(endpoints.size(), Integer.parseInt(connectTriesConf));
} catch (NumberFormatException e) {
throw new InvalidConnectionInfoException("Invalid tries value: " + connectTriesConf + " specified in " + "connection string");
}
// If the value provided in the connection string is <=0 then override with 1 since we want to try connecting
// at least once
connectTriesVal = Math.max(1, connectTriesVal);
int triedEndpointIndex = 0;
DrillbitEndpoint endpoint;
while (triedEndpointIndex < connectTriesVal) {
endpoint = endpoints.get(triedEndpointIndex);
// version
if (!properties.containsKey(DrillProperties.SERVICE_HOST)) {
properties.setProperty(DrillProperties.SERVICE_HOST, endpoint.getAddress());
props.setProperty(DrillProperties.SERVICE_HOST, endpoint.getAddress());
}
// Note: the properties member is a DrillProperties instance which lower cases names of
// properties. That does not work too well with properties that are mixed case.
// For user client severla properties are mixed case so we do not use the properties member
// but instead pass the props parameter.
client = new UserClient(clientName, config, props, supportComplexTypes, allocator, eventLoopGroup, executor, endpoint);
logger.debug("Connecting to server {}:{}", endpoint.getAddress(), endpoint.getUserPort());
try {
connect(endpoint);
connected = true;
logger.info("Successfully connected to server {}:{}", endpoint.getAddress(), endpoint.getUserPort());
break;
} catch (NonTransientRpcException ex) {
logger.error("Connection to {}:{} failed with error {}. Not retrying anymore", endpoint.getAddress(), endpoint.getUserPort(), ex.getMessage());
throw ex;
} catch (RpcException ex) {
++triedEndpointIndex;
logger.error("Attempt {}: Failed to connect to server {}:{}", triedEndpointIndex, endpoint.getAddress(), endpoint.getUserPort());
// Throw exception when we have exhausted all the tries without having a successful connection
if (triedEndpointIndex == connectTriesVal) {
throw ex;
}
// Close the connection here to avoid calling close twice in case when all tries are exhausted.
// Since DrillClient.close is also calling client.close
client.close();
}
}
}
use of org.apache.drill.exec.rpc.RpcException in project drill by axbaretto.
the class ServerAuthenticationHandler method handle.
@Override
public void handle(S connection, int rpcType, ByteBuf pBody, ByteBuf dBody, ResponseSender sender) throws RpcException {
final String remoteAddress = connection.getRemoteAddress().toString();
// exchange involves server "challenges" and client "responses" (initiated by client)
if (saslRequestTypeValue == rpcType) {
final SaslMessage saslResponse;
try {
saslResponse = SaslMessage.PARSER.parseFrom(new ByteBufInputStream(pBody));
} catch (final InvalidProtocolBufferException e) {
handleAuthFailure(connection, sender, e, saslResponseType);
return;
}
logger.trace("Received SASL message {} from {}", saslResponse.getStatus(), remoteAddress);
final SaslResponseProcessor processor = RESPONSE_PROCESSORS.get(saslResponse.getStatus());
if (processor == null) {
logger.info("Unknown message type from client from {}. Will stop authentication.", remoteAddress);
handleAuthFailure(connection, sender, new SaslException("Received unexpected message"), saslResponseType);
return;
}
final SaslResponseContext<S, T> context = new SaslResponseContext<>(saslResponse, connection, sender, requestHandler, saslResponseType);
try {
processor.process(context);
} catch (final Exception e) {
handleAuthFailure(connection, sender, e, saslResponseType);
}
} else {
// drop connection
throw new RpcException(String.format("Request of type %d is not allowed without authentication. Client on %s must authenticate " + "before making requests. Connection dropped. [Details: %s]", rpcType, remoteAddress, connection.getEncryptionCtxtString()));
}
}
Aggregations