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.impl.RemoteCacheImpl Maven / Gradle / Ivy
package org.infinispan.client.hotrod.impl;
import static org.infinispan.client.hotrod.filter.Filters.makeFactoryParams;
import static org.infinispan.client.hotrod.impl.Util.await;
import static org.infinispan.client.hotrod.logging.Log.HOTROD;
import static org.infinispan.commons.internal.InternalCacheNames.GLOBAL_STATE_INTERNAL_CACHES;
import java.net.SocketAddress;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;
import java.util.function.Function;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.infinispan.client.hotrod.CacheTopologyInfo;
import org.infinispan.client.hotrod.DataFormat;
import org.infinispan.client.hotrod.Flag;
import org.infinispan.client.hotrod.MetadataValue;
import org.infinispan.client.hotrod.ProtocolVersion;
import org.infinispan.client.hotrod.RemoteCacheContainer;
import org.infinispan.client.hotrod.RemoteCacheManager;
import org.infinispan.client.hotrod.ServerStatistics;
import org.infinispan.client.hotrod.StreamingRemoteCache;
import org.infinispan.client.hotrod.configuration.Configuration;
import org.infinispan.client.hotrod.configuration.StatisticsConfiguration;
import org.infinispan.client.hotrod.exceptions.RemoteCacheManagerNotStartedException;
import org.infinispan.client.hotrod.filter.Filters;
import org.infinispan.client.hotrod.impl.iteration.RemotePublisher;
import org.infinispan.client.hotrod.impl.operations.AddClientListenerOperation;
import org.infinispan.client.hotrod.impl.operations.ClearOperation;
import org.infinispan.client.hotrod.impl.operations.ContainsKeyOperation;
import org.infinispan.client.hotrod.impl.operations.ExecuteOperation;
import org.infinispan.client.hotrod.impl.operations.GetAllParallelOperation;
import org.infinispan.client.hotrod.impl.operations.GetOperation;
import org.infinispan.client.hotrod.impl.operations.GetWithMetadataOperation;
import org.infinispan.client.hotrod.impl.operations.OperationsFactory;
import org.infinispan.client.hotrod.impl.operations.PingResponse;
import org.infinispan.client.hotrod.impl.operations.PutAllParallelOperation;
import org.infinispan.client.hotrod.impl.operations.PutIfAbsentOperation;
import org.infinispan.client.hotrod.impl.operations.PutOperation;
import org.infinispan.client.hotrod.impl.operations.RemoveClientListenerOperation;
import org.infinispan.client.hotrod.impl.operations.RemoveIfUnmodifiedOperation;
import org.infinispan.client.hotrod.impl.operations.RemoveOperation;
import org.infinispan.client.hotrod.impl.operations.ReplaceIfUnmodifiedOperation;
import org.infinispan.client.hotrod.impl.operations.ReplaceOperation;
import org.infinispan.client.hotrod.impl.operations.RetryAwareCompletionStage;
import org.infinispan.client.hotrod.impl.operations.SizeOperation;
import org.infinispan.client.hotrod.impl.operations.StatsOperation;
import org.infinispan.client.hotrod.impl.query.RemoteQueryFactory;
import org.infinispan.client.hotrod.logging.Log;
import org.infinispan.client.hotrod.logging.LogFactory;
import org.infinispan.client.hotrod.near.NearCacheService;
import org.infinispan.commons.api.query.ContinuousQuery;
import org.infinispan.commons.dataconversion.MediaType;
import org.infinispan.commons.time.TimeService;
import org.infinispan.commons.util.CloseableIterator;
import org.infinispan.commons.util.CloseableIteratorCollection;
import org.infinispan.commons.util.CloseableIteratorSet;
import org.infinispan.commons.util.Closeables;
import org.infinispan.commons.util.IntSet;
import org.infinispan.commons.util.concurrent.CompletableFutures;
import org.infinispan.query.dsl.Query;
import org.reactivestreams.Publisher;
import io.reactivex.rxjava3.core.Flowable;
/**
* @author [email protected]
* @since 4.1
*/
public class RemoteCacheImpl extends RemoteCacheSupport implements InternalRemoteCache {
private static final Log log = LogFactory.getLog(RemoteCacheImpl.class, Log.class);
private final String name;
private final RemoteCacheManager remoteCacheManager;
protected OperationsFactory operationsFactory;
private int batchSize;
private volatile boolean isObjectStorage;
private DataFormat dataFormat;
protected ClientStatistics clientStatistics;
private ObjectName mbeanObjectName;
private RemoteQueryFactory queryFactory;
public RemoteCacheImpl(RemoteCacheManager rcm, String name, TimeService timeService) {
this(rcm, name, timeService, null);
}
public RemoteCacheImpl(RemoteCacheManager rcm, String name, TimeService timeService, NearCacheService nearCacheService) {
if (log.isTraceEnabled()) {
log.tracef("Creating remote cache: %s", name);
}
this.name = name;
this.remoteCacheManager = rcm;
this.dataFormat = DataFormat.builder().build();
this.clientStatistics = new ClientStatistics(rcm.getConfiguration().statistics().enabled(), timeService, nearCacheService);
}
protected RemoteCacheImpl(RemoteCacheManager rcm, String name, ClientStatistics clientStatistics) {
if (log.isTraceEnabled()) {
log.tracef("Creating remote cache: %s", name);
}
this.name = name;
this.remoteCacheManager = rcm;
this.dataFormat = DataFormat.builder().build();
this.clientStatistics = clientStatistics;
}
@Override
public void init(OperationsFactory operationsFactory,
Configuration configuration, ObjectName jmxParent) {
init(operationsFactory, configuration);
registerMBean(jmxParent);
}
/**
* Inititalize without mbeans
*/
@Override
public void init(OperationsFactory operationsFactory, Configuration configuration) {
init(operationsFactory, configuration.batchSize());
}
private void init(OperationsFactory operationsFactory, int batchSize) {
this.operationsFactory = operationsFactory;
this.batchSize = batchSize;
// try cautiously
try {
this.queryFactory = new RemoteQueryFactory(this);
} catch (Throwable e) {
log.queryDisabled();
}
}
private void registerMBean(ObjectName jmxParent) {
StatisticsConfiguration configuration = getRemoteCacheContainer().getConfiguration().statistics();
if (configuration.jmxEnabled()) {
try {
MBeanServer mbeanServer = configuration.mbeanServerLookup().getMBeanServer();
String cacheName = name.isEmpty() ? "org.infinispan.default" : name;
mbeanObjectName = new ObjectName(String.format("%s:type=HotRodClient,name=%s,cache=%s", jmxParent.getDomain(), configuration.jmxName(), cacheName));
mbeanServer.registerMBean(clientStatistics, mbeanObjectName);
} catch (Exception e) {
throw HOTROD.jmxRegistrationFailure(e);
}
}
}
private synchronized void unregisterMBean() {
if (mbeanObjectName != null) {
try {
MBeanServer mBeanServer = getRemoteCacheContainer().getConfiguration().statistics()
.mbeanServerLookup().getMBeanServer();
if (mBeanServer.isRegistered(mbeanObjectName)) {
mBeanServer.unregisterMBean(mbeanObjectName);
} else {
HOTROD.debugf("MBean not registered: %s", mbeanObjectName);
}
mbeanObjectName = null;
} catch (Exception e) {
throw HOTROD.jmxUnregistrationFailure(e);
}
}
}
@Override
public OperationsFactory getOperationsFactory() {
return operationsFactory;
}
@Override
public RemoteCacheContainer getRemoteCacheContainer() {
return remoteCacheManager;
}
@Override
public CompletableFuture removeWithVersionAsync(final K key, final long version) {
assertRemoteCacheManagerIsStarted();
RemoveIfUnmodifiedOperation op = operationsFactory.newRemoveIfUnmodifiedOperation(
key, keyToBytes(key), version, dataFormat);
return op.execute().thenApply(response -> response.getCode().isUpdated());
}
@Override
public CompletableFuture mergeAsync(K key, V value, BiFunction super V, ? super V, ? extends V> remappingFunction, long lifespan, TimeUnit lifespanUnit, long maxIdleTime, TimeUnit maxIdleTimeUnit) {
throw new UnsupportedOperationException();
}
public CompletableFuture replaceWithVersionAsync(K key, V newValue, long version, long lifespan, TimeUnit lifespanTimeUnit, long maxIdle, TimeUnit maxIdleTimeUnit) {
assertRemoteCacheManagerIsStarted();
ReplaceIfUnmodifiedOperation op = operationsFactory.newReplaceIfUnmodifiedOperation(
key, keyToBytes(key), valueToBytes(newValue), lifespan, lifespanTimeUnit, maxIdle, maxIdleTimeUnit, version, dataFormat);
return op.execute().thenApply(response -> response.getCode().isUpdated());
}
@Override
public CloseableIterator> retrieveEntries(String filterConverterFactory, Object[] filterConverterParams, Set segments, int batchSize) {
Publisher> remotePublisher = publishEntries(filterConverterFactory, filterConverterParams, segments, batchSize);
//noinspection unchecked
return Closeables.iterator((Publisher) remotePublisher, batchSize);
}
@Override
public Publisher> publishEntries(String filterConverterFactory, Object[] filterConverterParams, Set segments, int batchSize) {
assertRemoteCacheManagerIsStarted();
if (segments != null && segments.isEmpty()) {
return Flowable.empty();
}
byte[][] params = marshallParams(filterConverterParams);
return new RemotePublisher<>(operationsFactory, filterConverterFactory, params, segments,
batchSize, false, dataFormat);
}
@Override
public CloseableIterator> retrieveEntriesByQuery(Query> filterQuery, Set segments, int batchSize) {
Publisher> remotePublisher = publishEntriesByQuery(filterQuery, segments, batchSize);
//noinspection unchecked
return Closeables.iterator((Publisher) remotePublisher, batchSize);
}
@Override
public Publisher> publishEntriesByQuery(Query> filterQuery, Set segments, int batchSize) {
Object[] factoryParams = makeFactoryParams(filterQuery);
return publishEntries(Filters.ITERATION_QUERY_FILTER_CONVERTER_FACTORY_NAME, factoryParams, segments, batchSize);
}
@Override
public CloseableIterator>> retrieveEntriesWithMetadata(Set segments, int batchSize) {
Publisher>> remotePublisher = publishEntriesWithMetadata(segments, batchSize);
//noinspection unchecked
return Closeables.iterator((Publisher) remotePublisher, batchSize);
}
@Override
public Publisher>> publishEntriesWithMetadata(Set segments, int batchSize) {
return new RemotePublisher<>(operationsFactory, null, null, segments,
batchSize, true, dataFormat);
}
@Override
public CompletableFuture> getWithMetadataAsync(K key) {
assertRemoteCacheManagerIsStarted();
GetWithMetadataOperation op = operationsFactory.newGetWithMetadataOperation(
key, keyToBytes(key), dataFormat);
return op.execute();
}
@Override
public RetryAwareCompletionStage> getWithMetadataAsync(K key, SocketAddress preferredAddres) {
assertRemoteCacheManagerIsStarted();
GetWithMetadataOperation op = operationsFactory.newGetWithMetadataOperation(
key, keyToBytes(key), dataFormat, preferredAddres);
return op.internalExecute();
}
@Override
public CompletableFuture putAllAsync(Map extends K, ? extends V> map, long lifespan, TimeUnit lifespanUnit, long maxIdleTime, TimeUnit maxIdleTimeUnit) {
assertRemoteCacheManagerIsStarted();
if (log.isTraceEnabled()) {
log.tracef("About to putAll entries (%s) lifespan:%d (%s), maxIdle:%d (%s)", map, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit);
}
Map byteMap = new HashMap<>();
for (Entry extends K, ? extends V> entry : map.entrySet()) {
byteMap.put(keyToBytes(entry.getKey()), valueToBytes(entry.getValue()));
}
PutAllParallelOperation op = operationsFactory.newPutAllOperation(byteMap, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit, dataFormat);
return op.execute();
}
@Override
public CompletableFuture sizeAsync() {
assertRemoteCacheManagerIsStarted();
SizeOperation op = operationsFactory.newSizeOperation();
return op.execute().thenApply(Integer::longValue);
}
@Override
public boolean isEmpty() {
return size() == 0;
}
@Override
public ClientStatistics clientStatistics() {
return clientStatistics;
}
@Override
public ServerStatistics serverStatistics() {
return await(serverStatisticsAsync());
}
@Override
public CompletionStage serverStatisticsAsync() {
assertRemoteCacheManagerIsStarted();
StatsOperation op = operationsFactory.newStatsOperation();
return op.execute();
}
@Override
public CompletableFuture putAsync(K key, V value, long lifespan, TimeUnit lifespanUnit, long maxIdleTime, TimeUnit maxIdleTimeUnit) {
assertRemoteCacheManagerIsStarted();
if (log.isTraceEnabled()) {
log.tracef("About to add (K,V): (%s, %s) lifespan:%d, maxIdle:%d", key, value, lifespan, maxIdleTime);
}
PutOperation op = operationsFactory.newPutKeyValueOperation(key,
keyToBytes(key), valueToBytes(value), lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit, dataFormat);
return op.execute();
}
@Override
public CompletableFuture clearAsync() {
assertRemoteCacheManagerIsStarted();
ClearOperation op = operationsFactory.newClearOperation();
return op.execute();
}
@Override
public CompletableFuture computeAsync(K key, BiFunction super K, ? super V, ? extends V> remappingFunction, long lifespan, TimeUnit lifespanUnit, long maxIdle, TimeUnit maxIdleUnit) {
CompletableFuture> cf = getWithMetadataAsync(key);
return cf.thenCompose(metadataValue -> {
V newValue;
V oldValue;
long version;
if (metadataValue != null) {
oldValue = metadataValue.getValue();
version = metadataValue.getVersion();
} else {
oldValue = null;
version = -1;
}
newValue = remappingFunction.apply(key, oldValue);
CompletionStage doneStage;
if (newValue != null) {
if (oldValue != null) {
doneStage = replaceWithVersionAsync(key, newValue, version, lifespan, lifespanUnit, maxIdle, maxIdleUnit);
} else {
doneStage = putIfAbsentAsync(key, newValue, lifespan, lifespanUnit, maxIdle, maxIdleUnit, Flag.FORCE_RETURN_VALUE)
.thenApply(Objects::isNull);
}
} else {
if (oldValue != null) {
doneStage = removeWithVersionAsync(key, version);
} else {
// Nothing to remove
doneStage = CompletableFuture.completedFuture(Boolean.TRUE);
}
}
return doneStage.thenCompose(done -> {
if (done) {
return CompletableFuture.completedFuture(newValue);
}
// Retry if one of the operations failed
return computeAsync(key, remappingFunction, lifespan, lifespanUnit, maxIdle, maxIdleUnit);
});
});
}
@Override
public CompletableFuture computeIfAbsentAsync(K key, Function super K, ? extends V> mappingFunction, long lifespan, TimeUnit lifespanUnit, long maxIdle, TimeUnit maxIdleUnit) {
CompletableFuture cf = getAsync(key);
return cf.thenCompose(oldValue -> {
if (oldValue != null) return CompletableFuture.completedFuture(oldValue);
V newValue = mappingFunction.apply(key);
if (newValue == null) return CompletableFutures.completedNull();
return putIfAbsentAsync(key, newValue, lifespan, lifespanUnit, maxIdle, maxIdleUnit)
.thenApply(v -> v == null ? newValue : v);
});
}
@Override
public CompletableFuture computeIfPresentAsync(K key, BiFunction super K, ? super V, ? extends V> remappingFunction, long lifespan, TimeUnit lifespanUnit, long maxIdle, TimeUnit maxIdleUnit) {
CompletableFuture> cf = getWithMetadataAsync(key);
return cf.thenCompose(metadata -> {
if (metadata == null || metadata.getValue() == null) return CompletableFutures.completedNull();
V newValue = remappingFunction.apply(key, metadata.getValue());
CompletableFuture done;
if (newValue == null) {
done = removeWithVersionAsync(key, metadata.getVersion());
} else {
done = replaceWithVersionAsync(key, newValue, metadata.getVersion(), lifespan, lifespanUnit, maxIdle, maxIdleUnit);
}
return done.thenCompose(success -> {
if (success) {
return CompletableFuture.completedFuture(newValue);
}
return computeIfPresentAsync(key, remappingFunction, lifespan, lifespanUnit, maxIdle, maxIdleUnit);
});
});
}
@Override
public void replaceAll(BiFunction super K, ? super V, ? extends V> function) {
throw new UnsupportedOperationException();
}
@Override
public CompletableFuture putIfAbsentAsync(K key, V value, long lifespan, TimeUnit lifespanUnit, long maxIdleTime, TimeUnit maxIdleTimeUnit) {
return putIfAbsentAsync(key, value, lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit, (Flag[]) null);
}
private CompletableFuture putIfAbsentAsync(K key, V value, long lifespan, TimeUnit lifespanUnit, long maxIdleTime, TimeUnit maxIdleTimeUnit, Flag ... flags) {
assertRemoteCacheManagerIsStarted();
PutIfAbsentOperation op = operationsFactory.newPutIfAbsentOperation(key,
keyToBytes(key), valueToBytes(value), lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit, dataFormat);
op.header().addFlags(flags);
return op.execute();
}
@Override
public CompletableFuture replaceAsync(K key, V oldValue, V newValue, long lifespan, TimeUnit lifespanUnit, long maxIdle, TimeUnit maxIdleUnit) {
Objects.requireNonNull(oldValue);
Objects.requireNonNull(newValue);
CompletionStage> stage = getWithMetadataAsync(key);
return stage.thenCompose(metadataValue -> {
if (metadataValue != null) {
V prevValue = metadataValue.getValue();
if (oldValue.equals(prevValue)) {
return replaceWithVersionAsync(key, newValue, metadataValue.getVersion(), lifespan, lifespanUnit, maxIdle, maxIdleUnit)
.thenCompose(replaced -> {
if (replaced) {
return CompletableFuture.completedFuture(replaced);
}
// Concurrent modification - the value could still equal - we need to retry
return replaceAsync(key, oldValue, newValue, lifespan, lifespanUnit, maxIdle, maxIdleUnit);
});
}
}
return CompletableFuture.completedFuture(Boolean.FALSE);
}).toCompletableFuture();
}
@Override
public CompletableFuture removeAsync(Object key) {
assertRemoteCacheManagerIsStarted();
RemoveOperation removeOperation = operationsFactory.newRemoveOperation(key, keyToBytes(key), dataFormat);
// TODO: It sucks that you need the prev value to see if it works...
// We need to find a better API for RemoteCache...
return removeOperation.execute();
}
@Override
public CompletableFuture removeAsync(Object key, Object value) {
Objects.requireNonNull(value);
CompletionStage> stage = getWithMetadataAsync((K) key);
return stage.thenCompose(metadataValue -> {
if (metadataValue == null || !value.equals(metadataValue.getValue())) {
return CompletableFuture.completedFuture(Boolean.FALSE);
}
return removeWithVersionAsync((K) key, metadataValue.getVersion())
.thenCompose(removed -> {
if (removed) {
return CompletableFuture.completedFuture(Boolean.TRUE);
}
// Concurrent operation - need to retry
return removeAsync(key, value);
});
}).toCompletableFuture();
}
@Override
public CompletableFuture replaceAsync(K key, V value, long lifespan, TimeUnit lifespanUnit, long maxIdleTime, TimeUnit maxIdleTimeUnit) {
assertRemoteCacheManagerIsStarted();
ReplaceOperation op = operationsFactory.newReplaceOperation(key,
keyToBytes(key), valueToBytes(value), lifespan, lifespanUnit, maxIdleTime, maxIdleTimeUnit, dataFormat);
return op.execute();
}
@Override
public CompletableFuture containsKeyAsync(K key) {
assertRemoteCacheManagerIsStarted();
ContainsKeyOperation op = operationsFactory.newContainsKeyOperation(key, keyToBytes(key), dataFormat);
return op.execute();
}
@Override
public boolean containsValue(Object value) {
Objects.requireNonNull(value);
return values().contains(value);
}
@Override
public CompletableFuture> getAllAsync(Set> keys) {
assertRemoteCacheManagerIsStarted();
if (log.isTraceEnabled()) {
log.tracef("About to getAll entries (%s)", keys);
}
Set byteKeys = new HashSet<>(keys.size());
for (Object key : keys) {
byteKeys.add(keyToBytes(key));
}
GetAllParallelOperation op = operationsFactory.newGetAllOperation(byteKeys, dataFormat);
return op.execute().thenApply(Collections::unmodifiableMap);
}
@Override
public void start() {
if (log.isDebugEnabled()) {
log.debugf("Start called, nothing to do here(%s)", getName());
}
}
@Override
public void stop() {
unregisterMBean();
}
@Override
public String getName() {
return name;
}
@Override
public String getVersion() {
return RemoteCacheImpl.class.getPackage().getImplementationVersion();
}
@Override
public Query query(String query) {
if (queryFactory == null) {
throw log.queryNotSupported();
}
return queryFactory.create(query);
}
@Override
public ContinuousQuery continuousQuery() {
if (queryFactory == null) {
throw log.queryNotSupported();
}
return queryFactory.continuousQuery(this);
}
@Override
public String getProtocolVersion() {
return "HotRod client, protocol version: " + ProtocolVersion.DEFAULT_PROTOCOL_VERSION;
}
@Override
public void addClientListener(Object listener) {
assertRemoteCacheManagerIsStarted();
AddClientListenerOperation op = operationsFactory.newAddClientListenerOperation(listener, dataFormat);
// no timeout, see below
await(op.execute());
}
@Override
public void addClientListener(Object listener, Object[] filterFactoryParams, Object[] converterFactoryParams) {
assertRemoteCacheManagerIsStarted();
byte[][] marshalledFilterParams = marshallParams(filterFactoryParams);
byte[][] marshalledConverterParams = marshallParams(converterFactoryParams);
AddClientListenerOperation op = operationsFactory.newAddClientListenerOperation(
listener, marshalledFilterParams, marshalledConverterParams, dataFormat);
// No timeout: transferring initial state can take a while, socket timeout setting is not applicable here
await(op.execute());
}
@Override
public SocketAddress addNearCacheListener(Object listener, int bloomBits) {
throw new UnsupportedOperationException("Adding a near cache listener to a RemoteCache is not supported!");
}
private byte[][] marshallParams(Object[] params) {
if (params == null)
return org.infinispan.commons.util.Util.EMPTY_BYTE_ARRAY_ARRAY;
byte[][] marshalledParams = new byte[params.length][];
for (int i = 0; i < marshalledParams.length; i++) {
byte[] bytes = keyToBytes(params[i]);// should be small
marshalledParams[i] = bytes;
}
return marshalledParams;
}
@Override
public void removeClientListener(Object listener) {
assertRemoteCacheManagerIsStarted();
RemoveClientListenerOperation op = operationsFactory.newRemoveClientListenerOperation(listener);
await(op.execute());
}
@Override
public InternalRemoteCache withFlags(Flag... flags) {
operationsFactory.setFlags(flags);
return this;
}
@Override
public CompletableFuture getAsync(Object key) {
assertRemoteCacheManagerIsStarted();
byte[] keyBytes = keyToBytes(key);
GetOperation gco = operationsFactory.newGetKeyOperation(key, keyBytes, dataFormat);
CompletableFuture result = gco.execute();
if (log.isTraceEnabled()) {
result.thenAccept(value -> log.tracef("For key(%s) returning %s", key, value));
}
return result;
}
public CompletionStage ping() {
return operationsFactory.newFaultTolerantPingOperation().execute();
}
@Override
public byte[] keyToBytes(Object o) {
return dataFormat.keyToBytes(o);
}
protected byte[] valueToBytes(Object o) {
return dataFormat.valueToBytes(o);
}
protected void assertRemoteCacheManagerIsStarted() {
if (!remoteCacheManager.isStarted()) {
String message = "Cannot perform operations on a cache associated with an unstarted RemoteCacheManager. Use RemoteCacheManager.start before using the remote cache.";
HOTROD.unstartedRemoteCacheManager();
throw new RemoteCacheManagerNotStartedException(message);
}
}
@Override
public CloseableIteratorSet keySet(IntSet segments) {
return new RemoteCacheKeySet<>(this, segments);
}
@Override
public CloseableIterator keyIterator(IntSet segments) {
return operationsFactory.getCodec().keyIterator(this, operationsFactory, segments, batchSize);
}
@Override
public CloseableIteratorSet> entrySet(IntSet segments) {
return new RemoteCacheEntrySet<>(this, segments);
}
@Override
public CloseableIterator> entryIterator(IntSet segments) {
return operationsFactory.getCodec().entryIterator(this, segments, batchSize);
}
@Override
public CloseableIteratorCollection values(IntSet segments) {
return new RemoteCacheValuesCollection<>(this, segments);
}
@Override
public T execute(String taskName, Map params) {
return execute(taskName, params, null);
}
@Override
public T execute(String taskName, Map params, Object key) {
assertRemoteCacheManagerIsStarted();
Map marshalledParams = new HashMap<>();
if (params != null) {
for (java.util.Map.Entry entry : params.entrySet()) {
marshalledParams.put(entry.getKey(), keyToBytes(entry.getValue()));
}
}
Object keyHint = null;
if (key != null) {
keyHint = isObjectStorage ? key : keyToBytes(key);
}
ExecuteOperation op = operationsFactory.newExecuteOperation(taskName, marshalledParams, keyHint, dataFormat);
return await(op.execute());
}
@Override
public CacheTopologyInfo getCacheTopologyInfo() {
return operationsFactory.getCacheTopologyInfo();
}
@Override
public StreamingRemoteCache streaming() {
assertRemoteCacheManagerIsStarted();
return new StreamingRemoteCacheImpl<>(this);
}
@Override
public InternalRemoteCache withDataFormat(DataFormat newDataFormat) {
Objects.requireNonNull(newDataFormat, "Data Format must not be null")
.initialize(remoteCacheManager, name, isObjectStorage);
RemoteCacheImpl instance = newInstance();
instance.dataFormat = newDataFormat;
return instance;
}
private RemoteCacheImpl newInstance() {
RemoteCacheImpl copy = new RemoteCacheImpl<>(this.remoteCacheManager, name, clientStatistics);
copy.init(this.operationsFactory, this.batchSize);
return copy;
}
public void resolveStorage(boolean objectStorage) {
this.isObjectStorage = objectStorage;
this.dataFormat.initialize(remoteCacheManager, name, isObjectStorage);
}
@Override
public void resolveStorage(MediaType key, MediaType value, boolean objectStorage) {
// Set the storage first and initialize the current data format.
// We need this to check if the key type match.
resolveStorage(objectStorage);
if (key != null && key != MediaType.APPLICATION_UNKNOWN && !dataFormat.getKeyType().match(key)) {
DataFormat.Builder server = DataFormat.builder()
.from(this.dataFormat)
.keyType(key)
.valueType(value);
this.dataFormat = DataFormat.builder()
.from(this.dataFormat)
.serverDataFormat(server)
.build();
resolveStorage(objectStorage);
// Now proceed and check if the server has an available marshaller.
// This means that the client DOES NOT have a marshaller capable of converting to the server key type.
// Therefore, it will utilize the default fallback and NOT convert the object.
// This could cause additional redirections on the server side and poor performance for the client.
if (!GLOBAL_STATE_INTERNAL_CACHES.contains(name) && remoteCacheManager.getMarshallerRegistry().getMarshaller(key) == null) {
log.serverKeyTypeNotRecognized(key);
}
}
}
@Override
public DataFormat getDataFormat() {
return dataFormat;
}
@Override
public boolean isTransactional() {
return false;
}
public boolean isObjectStorage() {
return isObjectStorage;
}
@Override
public boolean hasForceReturnFlag() {
return operationsFactory.hasFlag(Flag.FORCE_RETURN_VALUE);
}
@Override
public CompletionStage updateBloomFilter() {
return CompletableFuture.completedFuture(null);
}
@Override
public String toString() {
return "RemoteCache " + name;
}
}