Search in sources :

Example 1 with RpcException

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;
}
Also used : IOException(java.io.IOException) AbstractCheckedFuture(com.google.common.util.concurrent.AbstractCheckedFuture) SaslException(javax.security.sasl.SaslException) AuthenticatorFactory(org.apache.drill.exec.rpc.security.AuthenticatorFactory) ByteBuf(io.netty.buffer.ByteBuf) RpcException(org.apache.drill.exec.rpc.RpcException) SaslException(javax.security.sasl.SaslException) NonTransientRpcException(org.apache.drill.exec.rpc.NonTransientRpcException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) SaslClient(javax.security.sasl.SaslClient) RpcException(org.apache.drill.exec.rpc.RpcException) NonTransientRpcException(org.apache.drill.exec.rpc.NonTransientRpcException) ExecutionException(java.util.concurrent.ExecutionException) UserGroupInformation(org.apache.hadoop.security.UserGroupInformation) RpcOutcomeListener(org.apache.drill.exec.rpc.RpcOutcomeListener)

Example 2 with RpcException

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()));
        }
    }
}
Also used : RpcException(org.apache.drill.exec.rpc.RpcException) IOException(java.io.IOException) SaslClient(javax.security.sasl.SaslClient)

Example 3 with RpcException

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);
}
Also used : RpcException(org.apache.drill.exec.rpc.RpcException) OptionValue(org.apache.drill.exec.server.options.OptionValue) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 4 with RpcException

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();
        }
    }
}
Also used : UserClient(org.apache.drill.exec.rpc.user.UserClient) NamedThreadFactory(org.apache.drill.exec.rpc.NamedThreadFactory) ArrayList(java.util.ArrayList) NonTransientRpcException(org.apache.drill.exec.rpc.NonTransientRpcException) ZKClusterCoordinator(org.apache.drill.exec.coord.zk.ZKClusterCoordinator) UserException(org.apache.drill.common.exceptions.UserException) RpcException(org.apache.drill.exec.rpc.RpcException) ChannelClosedException(org.apache.drill.exec.rpc.ChannelClosedException) OutOfMemoryException(org.apache.drill.exec.exception.OutOfMemoryException) NonTransientRpcException(org.apache.drill.exec.rpc.NonTransientRpcException) IOException(java.io.IOException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) DrillbitEndpoint(org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint) DrillbitEndpoint(org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint) RpcException(org.apache.drill.exec.rpc.RpcException) NonTransientRpcException(org.apache.drill.exec.rpc.NonTransientRpcException) SynchronousQueue(java.util.concurrent.SynchronousQueue) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor)

Example 5 with RpcException

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()));
    }
}
Also used : RpcException(org.apache.drill.exec.rpc.RpcException) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) SaslMessage(org.apache.drill.exec.proto.UserBitShared.SaslMessage) ByteString(com.google.protobuf.ByteString) ByteBufInputStream(io.netty.buffer.ByteBufInputStream) SaslException(javax.security.sasl.SaslException) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) RpcException(org.apache.drill.exec.rpc.RpcException) IOException(java.io.IOException) SaslException(javax.security.sasl.SaslException) UndeclaredThrowableException(java.lang.reflect.UndeclaredThrowableException)

Aggregations

RpcException (org.apache.drill.exec.rpc.RpcException)56 Test (org.junit.Test)22 ExecutionException (java.util.concurrent.ExecutionException)18 IOException (java.io.IOException)15 NonTransientRpcException (org.apache.drill.exec.rpc.NonTransientRpcException)12 Connection (java.sql.Connection)10 SQLException (java.sql.SQLException)10 JdbcTest (org.apache.drill.categories.JdbcTest)10 Response (org.apache.drill.exec.rpc.Response)9 Properties (java.util.Properties)8 SaslException (javax.security.sasl.SaslException)8 QueryId (org.apache.drill.exec.proto.UserBitShared.QueryId)8 UserException (org.apache.drill.common.exceptions.UserException)6 DrillBuf (io.netty.buffer.DrillBuf)5 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)4 ByteString (com.google.protobuf.ByteString)4 InvalidProtocolBufferException (com.google.protobuf.InvalidProtocolBufferException)4 ByteBufInputStream (io.netty.buffer.ByteBufInputStream)4 DrillException (org.apache.drill.common.exceptions.DrillException)4 UserRemoteException (org.apache.drill.common.exceptions.UserRemoteException)4