use of org.infinispan.encoding.DataConversion in project infinispan by infinispan.
the class CallInterceptor method visitReadWriteManyEntriesCommand.
@Override
public Object visitReadWriteManyEntriesCommand(InvocationContext ctx, ReadWriteManyEntriesCommand command) throws Throwable {
Map<Object, Object> arguments = command.getArguments();
List<Object> returns = new ArrayList<>(arguments.size());
boolean skipStats = Param.StatisticsMode.isSkip(command.getParams());
BiFunction biFunction = command.getBiFunction();
DataConversion keyDataConversion = command.getKeyDataConversion();
DataConversion valueDataConversion = command.getValueDataConversion();
arguments.forEach((k, arg) -> {
MVCCEntry entry = (MVCCEntry) ctx.lookupEntry(k);
if (entry == null) {
throw new IllegalStateException();
}
Object decodedArgument = valueDataConversion.fromStorage(arg);
boolean exists = entry.getValue() != null;
EntryViews.AccessLoggingReadWriteView view = EntryViews.readWrite(entry, keyDataConversion, valueDataConversion);
Object r = snapshot(biFunction.apply(decodedArgument, view));
returns.add(skipStats ? r : StatsEnvelope.create(r, entry, exists, view.isRead()));
updateStoreFlags(command, entry);
});
return returns;
}
use of org.infinispan.encoding.DataConversion in project infinispan by infinispan.
the class PreloadManager method preloadEntry.
private Single<?> preloadEntry(long flags, MarshallableEntry<Object, Object> me, DataConversion keyDataConversion, DataConversion valueDataConversion) {
// CallInterceptor will preserve the timestamps if the metadata is an InternalMetadataImpl instance
InternalMetadataImpl metadata = new InternalMetadataImpl(me.getMetadata(), me.created(), me.lastUsed());
// TODO If the storage media type is application/x-protostream, this will convert to POJOs and back
Object key = keyDataConversion.toStorage(me.getKey());
Object value = valueDataConversion.toStorage(me.getValue());
PutKeyValueCommand cmd = commandsFactory.buildPutKeyValueCommand(key, value, keyPartitioner.getSegment(key), metadata, flags);
cmd.setInternalMetadata(me.getInternalMetadata());
CompletionStage<?> stage;
if (configuration.transaction().transactionMode().isTransactional()) {
try {
Transaction transaction = new FakeJTATransaction();
InvocationContext ctx = invocationContextFactory.createInvocationContext(transaction, false);
LocalTransaction localTransaction = ((LocalTxInvocationContext) ctx).getCacheTransaction();
stage = CompletionStages.handleAndCompose(invocationHelper.invokeAsync(ctx, cmd), (__, t) -> completeTransaction(key, localTransaction, t)).whenComplete((__, t) -> transactionTable.removeLocalTransaction(localTransaction));
} catch (Exception e) {
throw log.problemPreloadingKey(key, e);
}
} else {
stage = invocationHelper.invokeAsync(cmd, 1);
}
// The return value doesn't matter, but it cannot be null
return Completable.fromCompletionStage(stage).toSingleDefault(me);
}
use of org.infinispan.encoding.DataConversion in project infinispan by infinispan.
the class CacheNotifierImpl method registerClusterListeners.
private <C> CompletionStage<Void> registerClusterListeners(List<Address> members, UUID generatedId, Address ourAddress, CacheEventFilter<? super K, ? super V> filter, CacheEventConverter<? super K, ? super V, C> converter, Listener l, Object listener, DataConversion keyDataConversion, DataConversion valueDataConversion, boolean useStorageFormat) {
if (log.isTraceEnabled()) {
log.tracef("Replicating cluster listener to other nodes %s for cluster listener with id %s", members, generatedId);
}
ClusterListenerReplicateCallable<K, V> callable = new ClusterListenerReplicateCallable(cache.wired().getName(), generatedId, ourAddress, filter, converter, l.sync(), findListenerCallbacks(listener), keyDataConversion, valueDataConversion, useStorageFormat);
TriConsumer<Address, Void, Throwable> handleSuspect = (a, ignore, t) -> {
if (t != null && !(t instanceof SuspectException)) {
log.debugf(t, "Address: %s encountered an exception while adding cluster listener", a);
throw new CacheListenerException(t);
}
};
// Send to all nodes but ours
CompletionStage<Void> completionStage = clusterExecutor.filterTargets(a -> !ourAddress.equals(a)).submitConsumer(callable, handleSuspect);
// the listener - unfortunately if there are no nodes it throws a SuspectException, so we ignore that
return completionStage.thenCompose(v -> clusterExecutor.filterTargets(a -> !members.contains(a) && !a.equals(ourAddress)).submitConsumer(callable, handleSuspect).exceptionally(t -> {
// Ignore any suspect exception
if (!(t instanceof SuspectException)) {
throw new CacheListenerException(t);
}
return null;
}));
}
use of org.infinispan.encoding.DataConversion in project infinispan by infinispan.
the class CacheNotifierImpl method convertKey.
private K convertKey(CacheEntryListenerInvocation listenerInvocation, K key) {
if (key == null)
return null;
DataConversion keyDataConversion = listenerInvocation.getKeyDataConversion();
Wrapper wrp = keyDataConversion.getWrapper();
Object unwrappedKey = keyDataConversion.getEncoder().fromStorage(wrp.unwrap(key));
CacheEventFilter filter = listenerInvocation.getFilter();
CacheEventConverter converter = listenerInvocation.getConverter();
if (filter == null && converter == null) {
if (listenerInvocation.useStorageFormat()) {
return (K) unwrappedKey;
}
// If no filter is present, convert to the requested format directly
return (K) keyDataConversion.fromStorage(key);
}
MediaType convertFormat = filter == null ? converter.format() : filter.format();
if (listenerInvocation.useStorageFormat() || convertFormat == null) {
// Filter will be run on the storage format, return the unwrapped key
return (K) unwrappedKey;
}
// Filter has a specific format to run, convert to that format
return (K) encoderRegistry.convert(unwrappedKey, keyDataConversion.getStorageMediaType(), convertFormat);
}
use of org.infinispan.encoding.DataConversion in project infinispan by infinispan.
the class CacheNotifierImpl method addFilteredListenerInternal.
private <C> CompletionStage<Void> addFilteredListenerInternal(Object listener, DataConversion keyDataConversion, DataConversion valueDataConversion, CacheEventFilter<? super K, ? super V> filter, CacheEventConverter<? super K, ? super V, C> converter, Set<Class<? extends Annotation>> filterAnnotations, boolean useStorageFormat) {
final Listener l = testListenerClassValidity(listener.getClass());
final UUID generatedId = Util.threadLocalRandomUUID();
final CacheMode cacheMode = config.clustering().cacheMode();
FilterIndexingServiceProvider indexingProvider = null;
boolean foundMethods = false;
// We use identity for null as this means it was invoked by a non encoder cache
DataConversion keyConversion = keyDataConversion == null ? DataConversion.IDENTITY_KEY : keyDataConversion;
DataConversion valueConversion = valueDataConversion == null ? DataConversion.IDENTITY_VALUE : valueDataConversion;
if (filter instanceof IndexedFilter) {
indexingProvider = findIndexingServiceProvider((IndexedFilter) filter);
if (indexingProvider != null) {
DelegatingCacheInvocationBuilder builder = new DelegatingCacheInvocationBuilder(indexingProvider);
adjustCacheInvocationBuilder(builder, filter, converter, filterAnnotations, l, useStorageFormat, generatedId, keyConversion, valueConversion, null);
foundMethods = validateAndAddFilterListenerInvocations(listener, builder, filterAnnotations);
builder.registerListenerInvocations();
}
}
if (indexingProvider == null) {
CacheInvocationBuilder builder = new CacheInvocationBuilder();
adjustCacheInvocationBuilder(builder, filter, converter, filterAnnotations, l, useStorageFormat, generatedId, keyConversion, valueConversion, null);
foundMethods = validateAndAddFilterListenerInvocations(listener, builder, filterAnnotations);
}
CompletionStage<Void> stage = CompletableFutures.completedNull();
if (foundMethods && l.clustered()) {
if (l.observation() == Listener.Observation.PRE) {
throw CONTAINER.clusterListenerRegisteredWithOnlyPreEvents(listener.getClass());
} else if (cacheMode.isInvalidation()) {
throw new UnsupportedOperationException("Cluster listeners cannot be used with Invalidation Caches!");
} else if (clusterListenerOnPrimaryOnly()) {
clusterListenerIDs.put(listener, generatedId);
// This way we only retrieve members of the cache itself
Address ourAddress = rpcManager.getAddress();
List<Address> members = rpcManager.getMembers();
// If we are the only member don't even worry about sending listeners
if (members != null && members.size() > 1) {
stage = registerClusterListeners(members, generatedId, ourAddress, filter, converter, l, listener, keyDataConversion, valueDataConversion, useStorageFormat);
}
}
}
// If we have a segment listener handler, it means we have to do initial state
QueueingSegmentListener<K, V, ? extends Event<K, V>> handler = segmentHandler.remove(generatedId);
if (handler != null) {
if (log.isTraceEnabled()) {
log.tracef("Listener %s requests initial state for cache", generatedId);
}
Collection<IntermediateOperation<?, ?, ?, ?>> intermediateOperations = new ArrayList<>();
MediaType storage = valueConversion.getStorageMediaType();
MediaType keyReq = keyConversion.getRequestMediaType();
MediaType valueReq = valueConversion.getRequestMediaType();
AdvancedCache advancedCache = cache.running();
DataConversion chainedKeyDataConversion = advancedCache.getKeyDataConversion();
DataConversion chainedValueDataConversion = advancedCache.getValueDataConversion();
if (keyReq != null && valueReq != null) {
chainedKeyDataConversion = chainedKeyDataConversion.withRequestMediaType(keyReq);
chainedValueDataConversion = chainedValueDataConversion.withRequestMediaType(valueReq);
}
boolean hasFilter = false;
MediaType filterMediaType = null;
if (filter != null) {
hasFilter = true;
filterMediaType = useStorageFormat ? null : filter.format();
if (filterMediaType == null) {
// iterate in the storage format
chainedKeyDataConversion = chainedKeyDataConversion.withRequestMediaType(storage);
chainedValueDataConversion = chainedValueDataConversion.withRequestMediaType(storage);
} else {
// iterate in the filter format
chainedKeyDataConversion = chainedKeyDataConversion.withRequestMediaType(filterMediaType);
chainedValueDataConversion = chainedValueDataConversion.withRequestMediaType(filterMediaType);
}
}
if (converter != null) {
hasFilter = true;
filterMediaType = useStorageFormat ? null : converter.format();
if (filterMediaType == null) {
// iterate in the storage format
chainedKeyDataConversion = chainedKeyDataConversion.withRequestMediaType(storage);
chainedValueDataConversion = chainedValueDataConversion.withRequestMediaType(storage);
} else {
// iterate in the filter format
chainedKeyDataConversion = chainedKeyDataConversion.withRequestMediaType(filterMediaType);
chainedValueDataConversion = chainedValueDataConversion.withRequestMediaType(filterMediaType);
}
}
if (!Objects.equals(chainedKeyDataConversion, keyDataConversion) || !Objects.equals(chainedValueDataConversion, valueDataConversion)) {
componentRegistry.wireDependencies(chainedKeyDataConversion, false);
componentRegistry.wireDependencies(chainedValueDataConversion, false);
intermediateOperations.add(new MapOperation<>(EncoderEntryMapper.newCacheEntryMapper(chainedKeyDataConversion, chainedValueDataConversion, entryFactory)));
}
if (filter instanceof CacheEventFilterConverter && (filter == converter || converter == null)) {
intermediateOperations.add(new MapOperation<>(CacheFilters.converterToFunction(new CacheEventFilterConverterAsKeyValueFilterConverter<>((CacheEventFilterConverter<?, ?, ?>) filter))));
intermediateOperations.add(new FilterOperation<>(CacheFilters.notNullCacheEntryPredicate()));
} else {
if (filter != null) {
intermediateOperations.add(new FilterOperation<>(CacheFilters.predicate(new CacheEventFilterAsKeyValueFilter<>(filter))));
}
if (converter != null) {
intermediateOperations.add(new MapOperation<>(CacheFilters.function(new CacheEventConverterAsConverter<>(converter))));
}
}
boolean finalHasFilter = hasFilter;
MediaType finalFilterMediaType = filterMediaType;
Function<Object, Object> kc = k -> {
if (!finalHasFilter)
return k;
if (finalFilterMediaType == null || useStorageFormat || keyReq == null) {
return keyDataConversion.fromStorage(k);
}
return encoderRegistry.convert(k, finalFilterMediaType, keyDataConversion.getRequestMediaType());
};
Function<Object, Object> kv = v -> {
if (!finalHasFilter)
return v;
if (finalFilterMediaType == null || useStorageFormat || valueReq == null) {
return valueConversion.fromStorage(v);
}
return encoderRegistry.convert(v, finalFilterMediaType, valueConversion.getRequestMediaType());
};
stage = handlePublisher(stage, intermediateOperations, handler, generatedId, l, kc, kv);
}
return stage;
}
Aggregations