All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.infinispan.client.hotrod.counter.operation.BaseCounterOperation Maven / Gradle / Ivy
package org.infinispan.client.hotrod.counter.operation;
import static org.infinispan.client.hotrod.counter.impl.CounterOperationFactory.COUNTER_CACHE_NAME;
import java.net.SocketAddress;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import org.infinispan.client.hotrod.configuration.Configuration;
import org.infinispan.client.hotrod.impl.ClientTopology;
import org.infinispan.client.hotrod.impl.operations.RetryOnFailureOperation;
import org.infinispan.client.hotrod.impl.protocol.HotRodConstants;
import org.infinispan.client.hotrod.impl.transport.netty.ByteBufUtil;
import org.infinispan.client.hotrod.impl.transport.netty.ChannelFactory;
import org.infinispan.client.hotrod.logging.LogFactory;
import org.infinispan.commons.logging.Log;
import org.infinispan.commons.util.Util;
import org.infinispan.counter.exception.CounterException;
/**
* A base operation class for the counter's operation.
*
* @author Pedro Ruivo
* @since 9.2
*/
abstract class BaseCounterOperation extends RetryOnFailureOperation {
private static final Log commonsLog = LogFactory.getLog(BaseCounterOperation.class, Log.class);
private static final Charset CHARSET = StandardCharsets.UTF_8;
private static final byte[] EMPTY_CACHE_NAME = Util.EMPTY_BYTE_ARRAY;
private final String counterName;
private final boolean useConsistentHash;
BaseCounterOperation(short requestCode, short responseCode, ChannelFactory channelFactory, AtomicReference clientTopology, Configuration cfg,
String counterName, boolean useConsistentHash) {
super(requestCode, responseCode, channelFactory.getNegotiatedCodec(), channelFactory, EMPTY_CACHE_NAME,
clientTopology, 0, cfg, null, null);
this.counterName = counterName;
this.useConsistentHash = useConsistentHash;
}
/**
* Writes the operation header followed by the counter's name.
*/
void sendHeaderAndCounterNameAndRead(Channel channel) {
ByteBuf buf = getHeaderAndCounterNameBufferAndRead(channel, 0);
channel.writeAndFlush(buf);
}
ByteBuf getHeaderAndCounterNameBufferAndRead(Channel channel, int extraBytes) {
scheduleRead(channel);
// counterName should never be null/empty
byte[] counterBytes = counterName.getBytes(HotRodConstants.HOTROD_STRING_CHARSET);
ByteBuf buf = channel.alloc().buffer(codec.estimateHeaderSize(header) + ByteBufUtil.estimateArraySize(counterBytes) + extraBytes);
codec.writeHeader(buf, header);
ByteBufUtil.writeString(buf, counterName);
setCacheName();
return buf;
}
/**
* If the status is {@link #KEY_DOES_NOT_EXIST_STATUS}, the counter is undefined and a {@link CounterException} is
* thrown.
*/
void checkStatus(short status) {
if (status == KEY_DOES_NOT_EXIST_STATUS) {
throw commonsLog.undefinedCounter(counterName);
}
}
void setCacheName() {
header.cacheName(COUNTER_CACHE_NAME);
}
@Override
protected void fetchChannelAndInvoke(int retryCount, Set failedServers) {
if (retryCount == 0 && useConsistentHash) {
channelFactory.fetchChannelAndInvoke(new ByteString(counterName), failedServers, COUNTER_CACHE_NAME, this);
} else {
channelFactory.fetchChannelAndInvoke(failedServers, COUNTER_CACHE_NAME, this);
}
}
@Override
protected Throwable handleException(Throwable cause, Channel channel, SocketAddress address) {
cause = super.handleException(cause, channel, address);
if (cause instanceof CounterException) {
completeExceptionally(cause);
return null;
}
return cause;
}
@Override
protected void addParams(StringBuilder sb) {
sb.append("counter=").append(counterName);
}
private static class ByteString {
private final int hash;
private final byte[] b;
private ByteString(String s) {
//copied from ByteString in core
this.b = s.getBytes(CHARSET);
this.hash = Arrays.hashCode(b);
}
@Override
public int hashCode() {
return hash;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ByteString that = (ByteString) o;
return Arrays.equals(b, that.b);
}
@Override
public String toString() {
return new String(b, CHARSET);
}
}
}