use of org.apache.thrift.transport.TTransportException in project accumulo by apache.
the class ConditionalWriterImpl method sendToServer.
private void sendToServer(HostAndPort location, TabletServerMutations<QCMutation> mutations) {
TabletClientService.Iface client = null;
TInfo tinfo = Tracer.traceInfo();
Map<Long, CMK> cmidToCm = new HashMap<>();
MutableLong cmid = new MutableLong(0);
SessionID sessionId = null;
try {
Map<TKeyExtent, List<TConditionalMutation>> tmutations = new HashMap<>();
CompressedIterators compressedIters = new CompressedIterators();
convertMutations(mutations, cmidToCm, cmid, tmutations, compressedIters);
// getClient() call must come after converMutations in case it throws a TException
client = getClient(location);
List<TCMResult> tresults = null;
while (tresults == null) {
try {
sessionId = reserveSessionID(location, client, tinfo);
tresults = client.conditionalUpdate(tinfo, sessionId.sessionID, tmutations, compressedIters.getSymbolTable());
} catch (NoSuchScanIDException nssie) {
sessionId = null;
invalidateSessionID(location);
}
}
HashSet<KeyExtent> extentsToInvalidate = new HashSet<>();
ArrayList<QCMutation> ignored = new ArrayList<>();
for (TCMResult tcmResult : tresults) {
if (tcmResult.status == TCMStatus.IGNORED) {
CMK cmk = cmidToCm.get(tcmResult.cmid);
ignored.add(cmk.cm);
extentsToInvalidate.add(cmk.ke);
} else {
QCMutation qcm = cmidToCm.get(tcmResult.cmid).cm;
qcm.queueResult(new Result(fromThrift(tcmResult.status), qcm, location.toString()));
}
}
for (KeyExtent ke : extentsToInvalidate) {
locator.invalidateCache(ke);
}
queueRetry(ignored, location);
} catch (ThriftSecurityException tse) {
AccumuloSecurityException ase = new AccumuloSecurityException(context.getCredentials().getPrincipal(), tse.getCode(), Tables.getPrintableTableInfoFromId(context.getInstance(), tableId), tse);
queueException(location, cmidToCm, ase);
} catch (TTransportException e) {
locator.invalidateCache(context.getInstance(), location.toString());
invalidateSession(location, mutations, cmidToCm, sessionId);
} catch (TApplicationException tae) {
queueException(location, cmidToCm, new AccumuloServerException(location.toString(), tae));
} catch (TException e) {
locator.invalidateCache(context.getInstance(), location.toString());
invalidateSession(location, mutations, cmidToCm, sessionId);
} catch (Exception e) {
queueException(location, cmidToCm, e);
} finally {
if (sessionId != null)
unreserveSessionID(location);
ThriftUtil.returnClient((TServiceClient) client);
}
}
use of org.apache.thrift.transport.TTransportException in project accumulo by apache.
the class MasterClient method executeGeneric.
public static void executeGeneric(ClientContext context, ClientExec<MasterClientService.Client> exec) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
MasterClientService.Client client = null;
while (true) {
try {
client = getConnectionWithRetry(context);
exec.execute(client);
break;
} catch (TTransportException tte) {
log.debug("MasterClient request failed, retrying ... ", tte);
sleepUninterruptibly(100, TimeUnit.MILLISECONDS);
} catch (ThriftSecurityException e) {
throw new AccumuloSecurityException(e.user, e.code, e);
} catch (AccumuloException e) {
throw e;
} catch (ThriftTableOperationException e) {
switch(e.getType()) {
case NAMESPACE_NOTFOUND:
throw new TableNotFoundException(e.getTableName(), new NamespaceNotFoundException(e));
case NOTFOUND:
throw new TableNotFoundException(e);
default:
throw new AccumuloException(e);
}
} catch (ThriftNotActiveServiceException e) {
// Let it loop, fetching a new location
log.debug("Contacted a Master which is no longer active, re-creating the connection to the active Master");
} catch (Exception e) {
throw new AccumuloException(e);
} finally {
if (client != null)
close(client);
}
}
}
use of org.apache.thrift.transport.TTransportException in project accumulo by apache.
the class ThriftUtil method createClient.
/**
* Lifted from Thrift-0.9.1 because it was private. Create an SSLSocket with the given factory, host:port, and timeout.
*
* @param factory
* Factory to create the socket from
* @param host
* Destination host
* @param port
* Destination port
* @param timeout
* Socket timeout
*/
private static TSocket createClient(SSLSocketFactory factory, String host, int port, int timeout) throws TTransportException {
SSLSocket socket = null;
try {
socket = (SSLSocket) factory.createSocket(host, port);
socket.setSoTimeout(timeout);
return new TSocket(socket);
} catch (Exception e) {
try {
if (socket != null)
socket.close();
} catch (IOException ioe) {
}
throw new TTransportException("Could not connect to " + host + " on port " + port, e);
}
}
use of org.apache.thrift.transport.TTransportException in project accumulo by apache.
the class ThriftUtil method createSSLContext.
/**
* Lifted from TSSLTransportFactory in Thrift-0.9.1. The method to create a client socket with an SSLContextFactory object is not visibile to us. Have to use
* SslConnectionParams instead of TSSLTransportParameters because no getters exist on TSSLTransportParameters.
*
* @param params
* Parameters to use to create the SSLContext
*/
private static SSLContext createSSLContext(SslConnectionParams params) throws TTransportException {
SSLContext ctx;
try {
ctx = SSLContext.getInstance(params.getClientProtocol());
TrustManagerFactory tmf = null;
KeyManagerFactory kmf = null;
if (params.isTrustStoreSet()) {
tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore ts = KeyStore.getInstance(params.getTrustStoreType());
try (FileInputStream fis = new FileInputStream(params.getTrustStorePath())) {
ts.load(fis, params.getTrustStorePass().toCharArray());
}
tmf.init(ts);
}
if (params.isKeyStoreSet()) {
kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
KeyStore ks = KeyStore.getInstance(params.getKeyStoreType());
try (FileInputStream fis = new FileInputStream(params.getKeyStorePath())) {
ks.load(fis, params.getKeyStorePass().toCharArray());
}
kmf.init(ks, params.getKeyStorePass().toCharArray());
}
if (params.isKeyStoreSet() && params.isTrustStoreSet()) {
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
} else if (params.isKeyStoreSet()) {
ctx.init(kmf.getKeyManagers(), null, null);
} else {
ctx.init(null, tmf.getTrustManagers(), null);
}
} catch (Exception e) {
throw new TTransportException("Error creating the transport", e);
}
return ctx;
}
use of org.apache.thrift.transport.TTransportException in project accumulo by apache.
the class ThriftUtil method createClientTransport.
/**
* Create a TTransport for clients to the given address with the provided socket timeout and session-layer configuration
*
* @param address
* Server address to connect to
* @param timeout
* Client socket timeout
* @param sslParams
* RPC options for SSL servers
* @param saslParams
* RPC options for SASL servers
* @return An open TTransport which must be closed when finished
*/
public static TTransport createClientTransport(HostAndPort address, int timeout, SslConnectionParams sslParams, SaslConnectionParams saslParams) throws TTransportException {
boolean success = false;
TTransport transport = null;
try {
if (sslParams != null) {
// The check in AccumuloServerContext ensures that servers are brought up with sane configurations, but we also want to validate clients
if (null != saslParams) {
throw new IllegalStateException("Cannot use both SSL and SASL");
}
log.trace("Creating SSL client transport");
// TSSLTransportFactory handles timeout 0 -> forever natively
if (sslParams.useJsse()) {
transport = TSSLTransportFactory.getClientSocket(address.getHost(), address.getPort(), timeout);
} else {
// JDK6's factory doesn't appear to pass the protocol onto the Socket properly so we have
// to do some magic to make sure that happens. Not an issue in JDK7
// Taken from thrift-0.9.1 to make the SSLContext
SSLContext sslContext = createSSLContext(sslParams);
// Create the factory from it
SSLSocketFactory sslSockFactory = sslContext.getSocketFactory();
// Wrap the real factory with our own that will set the protocol on the Socket before returning it
ProtocolOverridingSSLSocketFactory wrappingSslSockFactory = new ProtocolOverridingSSLSocketFactory(sslSockFactory, new String[] { sslParams.getClientProtocol() });
// Create the TSocket from that
transport = createClient(wrappingSslSockFactory, address.getHost(), address.getPort(), timeout);
// TSSLTransportFactory leaves transports open, so no need to open here
}
transport = ThriftUtil.transportFactory().getTransport(transport);
} else if (null != saslParams) {
if (!UserGroupInformation.isSecurityEnabled()) {
throw new IllegalStateException("Expected Kerberos security to be enabled if SASL is in use");
}
log.trace("Creating SASL connection to {}:{}", address.getHost(), address.getPort());
// Make sure a timeout is set
try {
transport = TTimeoutTransport.create(address, timeout);
} catch (IOException e) {
log.warn("Failed to open transport to {}", address);
throw new TTransportException(e);
}
try {
// Log in via UGI, ensures we have logged in with our KRB credentials
final UserGroupInformation currentUser = UserGroupInformation.getCurrentUser();
final UserGroupInformation userForRpc;
if (AuthenticationMethod.PROXY == currentUser.getAuthenticationMethod()) {
// that the current user is the user that has some credentials.
if (currentUser.getRealUser() != null) {
userForRpc = currentUser.getRealUser();
log.trace("{} is a proxy user, using real user instead {}", currentUser, userForRpc);
} else {
// The current user has no credentials, let it fail naturally at the RPC layer (no ticket)
// We know this won't work, but we can't do anything else
log.warn("The current user is a proxy user but there is no underlying real user (likely that RPCs will fail): {}", currentUser);
userForRpc = currentUser;
}
} else {
// The normal case: the current user has its own ticket
userForRpc = currentUser;
}
// Is this pricey enough that we want to cache it?
final String hostname = InetAddress.getByName(address.getHost()).getCanonicalHostName();
final SaslMechanism mechanism = saslParams.getMechanism();
log.trace("Opening transport to server as {} to {}/{} using {}", userForRpc, saslParams.getKerberosServerPrimary(), hostname, mechanism);
// Create the client SASL transport using the information for the server
// Despite the 'protocol' argument seeming to be useless, it *must* be the primary of the server being connected to
transport = new TSaslClientTransport(mechanism.getMechanismName(), null, saslParams.getKerberosServerPrimary(), hostname, saslParams.getSaslProperties(), saslParams.getCallbackHandler(), transport);
// Wrap it all in a processor which will run with a doAs the current user
transport = new UGIAssumingTransport(transport, userForRpc);
// Open the transport
transport.open();
} catch (TTransportException e) {
log.warn("Failed to open SASL transport", e);
// We might have had a valid ticket, but it expired. We'll let the caller retry, but we will attempt to re-login to make the next attempt work.
// Sadly, we have no way to determine the actual reason we got this TTransportException other than inspecting the exception msg.
log.debug("Caught TTransportException opening SASL transport, checking if re-login is necessary before propagating the exception.");
attemptClientReLogin();
throw e;
} catch (IOException e) {
log.warn("Failed to open SASL transport", e);
throw new TTransportException(e);
}
} else {
log.trace("Opening normal transport");
if (timeout == 0) {
transport = new TSocket(address.getHost(), address.getPort());
transport.open();
} else {
try {
transport = TTimeoutTransport.create(address, timeout);
} catch (IOException ex) {
log.warn("Failed to open transport to {}", address);
throw new TTransportException(ex);
}
// Open the transport
transport.open();
}
transport = ThriftUtil.transportFactory().getTransport(transport);
}
success = true;
} finally {
if (!success && transport != null) {
transport.close();
}
}
return transport;
}
Aggregations