com.hazelcast.client.cache.impl.AbstractClientCacheProxy Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 2008-2020, Hazelcast, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hazelcast.client.cache.impl;
import com.hazelcast.cache.CacheStatistics;
import com.hazelcast.client.impl.clientside.ClientMessageDecoder;
import com.hazelcast.client.impl.protocol.ClientMessage;
import com.hazelcast.client.impl.protocol.codec.CacheGetAllCodec;
import com.hazelcast.client.impl.protocol.codec.CacheGetCodec;
import com.hazelcast.client.impl.protocol.codec.CachePutAllCodec;
import com.hazelcast.client.impl.protocol.codec.CacheSetExpiryPolicyCodec;
import com.hazelcast.client.impl.protocol.codec.CacheSizeCodec;
import com.hazelcast.client.spi.ClientContext;
import com.hazelcast.client.spi.ClientPartitionService;
import com.hazelcast.client.spi.impl.ClientInvocation;
import com.hazelcast.client.spi.impl.ClientInvocationFuture;
import com.hazelcast.client.util.ClientDelegatingFuture;
import com.hazelcast.config.CacheConfig;
import com.hazelcast.core.ExecutionCallback;
import com.hazelcast.core.ICompletableFuture;
import com.hazelcast.nio.serialization.Data;
import com.hazelcast.spi.InternalCompletableFuture;
import com.hazelcast.util.FutureUtil;
import javax.cache.CacheException;
import javax.cache.expiry.ExpiryPolicy;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import static com.hazelcast.cache.impl.CacheProxyUtil.NULL_KEY_IS_NOT_ALLOWED;
import static com.hazelcast.cache.impl.CacheProxyUtil.validateNotNull;
import static com.hazelcast.cache.impl.operation.MutableOperation.IGNORE_COMPLETION;
import static com.hazelcast.util.CollectionUtil.objectToDataCollection;
import static com.hazelcast.util.ExceptionUtil.rethrow;
import static com.hazelcast.util.ExceptionUtil.rethrowAllowedTypeFirst;
import static com.hazelcast.util.MapUtil.createHashMap;
import static com.hazelcast.util.Preconditions.checkNotNull;
import static java.util.Collections.emptyMap;
/**
* Hazelcast provides extension functionality to default spec interface {@link javax.cache.Cache}.
* {@link com.hazelcast.cache.ICache} is the designated interface.
*
* AbstractCacheProxyExtension provides implementation of various {@link com.hazelcast.cache.ICache} methods.
*
* Note: this partial implementation is used by client.
*
* @param the type of key
* @param the type of value
*/
@SuppressWarnings("checkstyle:npathcomplexity")
abstract class AbstractClientCacheProxy extends AbstractClientInternalCacheProxy {
@SuppressWarnings("unchecked")
private static final ClientMessageDecoder CACHE_GET_RESPONSE_DECODER = new ClientMessageDecoder() {
@Override
public T decodeClientMessage(ClientMessage clientMessage) {
return (T) CacheGetCodec.decodeResponse(clientMessage).response;
}
};
AbstractClientCacheProxy(CacheConfig cacheConfig, ClientContext context) {
super(cacheConfig, context);
}
protected V getSyncInternal(Object key, ExpiryPolicy expiryPolicy) {
long startNanos = nowInNanosOrDefault();
try {
ClientDelegatingFuture future = getInternal(key, expiryPolicy, false);
V value = future.get();
if (statisticsEnabled) {
statsHandler.onGet(startNanos, value != null);
}
return value;
} catch (Throwable e) {
throw rethrowAllowedTypeFirst(e, CacheException.class);
}
}
@Override
public ICompletableFuture getAsync(K key) {
return getAsync(key, null);
}
@Override
public ICompletableFuture getAsync(K key, ExpiryPolicy expiryPolicy) {
long startNanos = nowInNanosOrDefault();
ensureOpen();
validateNotNull(key);
ExecutionCallback callback = !statisticsEnabled ? null : statsHandler.newOnGetCallback(startNanos);
return getAsyncInternal(key, expiryPolicy, callback);
}
protected InternalCompletableFuture getAsyncInternal(Object key, ExpiryPolicy expiryPolicy,
ExecutionCallback callback) {
Data dataKey = toData(key);
ClientDelegatingFuture future = getInternal(dataKey, expiryPolicy, true);
addCallback(future, callback);
return future;
}
private ClientDelegatingFuture getInternal(Object key, ExpiryPolicy expiryPolicy, boolean deserializeResponse) {
Data keyData = toData(key);
Data expiryPolicyData = toData(expiryPolicy);
ClientMessage request = CacheGetCodec.encodeRequest(nameWithPrefix, keyData, expiryPolicyData);
int partitionId = getContext().getPartitionService().getPartitionId(keyData);
ClientInvocation clientInvocation = new ClientInvocation(getClient(), request, name, partitionId);
ClientInvocationFuture future = clientInvocation.invoke();
return newDelegatingFuture(future, CACHE_GET_RESPONSE_DECODER, deserializeResponse);
}
@Override
public ICompletableFuture putAsync(K key, V value) {
return putAsync(key, value, null);
}
@Override
public ICompletableFuture putAsync(K key, V value, ExpiryPolicy expiryPolicy) {
return (ICompletableFuture) putAsyncInternal(key, value, expiryPolicy, false, true, newStatsCallbackOrNull(false));
}
@Override
public ICompletableFuture putIfAbsentAsync(K key, V value) {
return (ICompletableFuture) putIfAbsentInternal(key, value, null, false, true);
}
@Override
public ICompletableFuture putIfAbsentAsync(K key, V value, ExpiryPolicy expiryPolicy) {
return (ICompletableFuture) putIfAbsentInternal(key, value, expiryPolicy, false, true);
}
@Override
public ICompletableFuture getAndPutAsync(K key, V value) {
return getAndPutAsync(key, value, null);
}
@Override
public ICompletableFuture getAndPutAsync(K key, V value, ExpiryPolicy expiryPolicy) {
return putAsyncInternal(key, value, expiryPolicy, true, false, newStatsCallbackOrNull(true));
}
@Override
public ICompletableFuture removeAsync(K key) {
return (ICompletableFuture) removeAsyncInternal(key, null, false, false, true);
}
@Override
public ICompletableFuture removeAsync(K key, V oldValue) {
return (ICompletableFuture) removeAsyncInternal(key, oldValue, true, false, true);
}
@Override
public ICompletableFuture getAndRemoveAsync(K key) {
return getAndRemoveAsyncInternal(key);
}
@Override
public ICompletableFuture replaceAsync(K key, V value) {
return replaceAsyncInternal(key, null, value, null, false, false, true);
}
@Override
public ICompletableFuture replaceAsync(K key, V value, ExpiryPolicy expiryPolicy) {
return replaceAsyncInternal(key, null, value, expiryPolicy, false, false, true);
}
@Override
public ICompletableFuture replaceAsync(K key, V oldValue, V newValue) {
return replaceAsyncInternal(key, oldValue, newValue, null, true, false, true);
}
@Override
public ICompletableFuture replaceAsync(K key, V oldValue, V newValue, ExpiryPolicy expiryPolicy) {
return replaceAsyncInternal(key, oldValue, newValue, expiryPolicy, true, false, true);
}
@Override
public ICompletableFuture getAndReplaceAsync(K key, V value) {
return replaceAndGetAsyncInternal(key, null, value, null, false, false, true);
}
@Override
public ICompletableFuture getAndReplaceAsync(K key, V value, ExpiryPolicy expiryPolicy) {
return replaceAndGetAsyncInternal(key, null, value, expiryPolicy, false, false, true);
}
@Override
public V get(K key, ExpiryPolicy expiryPolicy) {
ensureOpen();
validateNotNull(key);
return toObject(getSyncInternal(key, expiryPolicy));
}
@Override
public Map getAll(Set extends K> keys, ExpiryPolicy expiryPolicy) {
long startNanos = nowInNanosOrDefault();
ensureOpen();
checkNotNull(keys, NULL_KEY_IS_NOT_ALLOWED);
if (keys.isEmpty()) {
return emptyMap();
}
int keysSize = keys.size();
List dataKeys = new LinkedList();
List