org.infinispan.client.hotrod.impl.Util Maven / Gradle / Ivy
package org.infinispan.client.hotrod.impl;
import static org.infinispan.client.hotrod.logging.Log.HOTROD;
import java.net.SocketTimeoutException;
import java.util.Collections;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import javax.transaction.xa.Xid;
import org.infinispan.client.hotrod.exceptions.HotRodClientException;
import org.infinispan.client.hotrod.exceptions.TransportException;
import org.infinispan.client.hotrod.impl.operations.OperationsFactory;
import org.infinispan.client.hotrod.impl.transaction.operations.PrepareTransactionOperation;
import org.infinispan.client.hotrod.logging.Log;
import org.infinispan.commons.CacheException;
import org.infinispan.commons.marshall.WrappedByteArray;
public class Util {
private final static long BIG_DELAY_NANOS = TimeUnit.DAYS.toNanos(1);
private static final Xid DUMMY_XID = new Xid() {
@Override
public int getFormatId() {
return 0;
}
@Override
public byte[] getGlobalTransactionId() {
return new byte[]{1};
}
@Override
public byte[] getBranchQualifier() {
return new byte[]{1};
}
};
private Util() {
}
public static T await(CompletionStage cf) {
return await(cf.toCompletableFuture());
}
public static T await(CompletableFuture cf) {
try {
// timed wait does not do busy waiting
return cf.get(BIG_DELAY_NANOS, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
// Need to restore interrupt status because InterruptedException cannot be sent back as is
Thread.currentThread().interrupt();
throw new HotRodClientException(e);
} catch (ExecutionException e) {
throw rewrap(e);
} catch (TimeoutException e) {
throw new IllegalStateException(e);
}
}
public static T await(CompletableFuture cf, long timeoutMillis) {
try {
return cf.get(timeoutMillis, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// Need to restore interrupt status because InterruptedException cannot be sent back as is
Thread.currentThread().interrupt();
throw new HotRodClientException(e);
} catch (ExecutionException e) {
throw rewrap(e);
} catch (TimeoutException e) {
cf.cancel(false);
throw new TransportException(new SocketTimeoutException(), null);
}
}
protected static RuntimeException rewrap(ExecutionException e) {
Throwable cause = e.getCause();
if (cause instanceof HotRodClientException) {
cause.setStackTrace(e.getStackTrace());
return (HotRodClientException) cause;
} else if (cause instanceof CacheException) {
return new CacheException(cause);
} else {
return new TransportException(cause, null);
}
}
public static CompletionStage checkTransactionSupport(String cacheName, OperationsFactory factory) {
PrepareTransactionOperation op = factory.newPrepareTransactionOperation(DUMMY_XID, true, Collections.emptyList(),
false, 60000);
return op.execute().handle((integer, throwable) -> {
if (throwable != null) {
HOTROD.invalidTxServerConfig(cacheName, throwable);
}
return throwable == null;
});
}
public static boolean checkTransactionSupport(String cacheName, OperationsFactory factory, Log log) {
PrepareTransactionOperation op = factory.newPrepareTransactionOperation(DUMMY_XID, true, Collections.emptyList(),
false, 60000);
try {
return op.execute().handle((integer, throwable) -> {
if (throwable != null) {
HOTROD.invalidTxServerConfig(cacheName, throwable);
}
return throwable == null;
}).get();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
log.debugf("Exception while checking transaction support in server", e);
}
return false;
}
public static WrappedByteArray wrapBytes(byte[] cacheName) {
WrappedByteArray wrappedCacheName;
if (cacheName == null || cacheName.length == 0) {
wrappedCacheName = WrappedByteArray.EMPTY_BYTES;
} else {
wrappedCacheName = new WrappedByteArray(cacheName);
}
return wrappedCacheName;
}
}