use of org.apache.ignite.internal.util.future.GridFinishedFuture in project ignite by apache.
the class GridPartitionedGetFuture method map.
/**
* @param keys Keys.
* @param mapped Mappings to check for duplicates.
* @param topVer Topology version on which keys should be mapped.
*/
@Override
protected void map(Collection<KeyCacheObject> keys, Map<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> mapped, AffinityTopologyVersion topVer) {
GridDhtPartitionsExchangeFuture fut = cctx.shared().exchange().lastTopologyFuture();
// Finished DHT future is required for topology validation.
if (!fut.isDone()) {
if (fut.initialVersion().after(topVer) || (fut.exchangeActions() != null && fut.exchangeActions().hasStop()))
fut = cctx.shared().exchange().lastFinishedFuture();
else {
fut.listen(new IgniteInClosure<IgniteInternalFuture<AffinityTopologyVersion>>() {
@Override
public void apply(IgniteInternalFuture<AffinityTopologyVersion> fut) {
if (fut.error() != null)
onDone(fut.error());
else {
cctx.closures().runLocalSafe(new GridPlainRunnable() {
@Override
public void run() {
map(keys, mapped, topVer);
}
}, true);
}
}
});
return;
}
}
Collection<ClusterNode> cacheNodes = CU.affinityNodes(cctx, topVer);
validate(cacheNodes, fut);
// Future can be already done with some exception.
if (isDone())
return;
Map<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> mappings = U.newHashMap(cacheNodes.size());
int keysSize = keys.size();
// Map for local (key,value) pairs.
Map<K, V> locVals = U.newHashMap(keysSize);
// True if we have remote nodes after key mapping complete.
boolean hasRmtNodes = false;
// Assign keys to nodes.
for (KeyCacheObject key : keys) hasRmtNodes |= map(key, topVer, mappings, mapped, locVals);
// Future can be alredy done with some exception.
if (isDone())
return;
// Add local read (key,value) in result.
if (!locVals.isEmpty())
add(new GridFinishedFuture<>(locVals));
// If we have remote nodes in mapping we should registrate future in mvcc manager.
if (hasRmtNodes)
registrateFutureInMvccManager(this);
// Create mini futures after mapping to remote nodes.
for (Map.Entry<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> entry : mappings.entrySet()) {
// Node for request.
ClusterNode n = entry.getKey();
// Keys for request.
LinkedHashMap<KeyCacheObject, Boolean> mappedKeys = entry.getValue();
assert !mappedKeys.isEmpty();
// If this is the primary or backup node for the keys.
if (n.isLocal()) {
GridDhtFuture<Collection<GridCacheEntryInfo>> fut0 = cache().getDhtAsync(n.id(), -1, mappedKeys, false, readThrough, topVer, taskName == null ? 0 : taskName.hashCode(), expiryPlc, skipVals, recovery, txLbl, mvccSnapshot());
Collection<Integer> invalidParts = fut0.invalidPartitions();
if (!F.isEmpty(invalidParts)) {
Collection<KeyCacheObject> remapKeys = new ArrayList<>(keysSize);
for (KeyCacheObject key : keys) {
int part = cctx.affinity().partition(key);
if (key != null && invalidParts.contains(part)) {
addNodeAsInvalid(n, part, topVer);
remapKeys.add(key);
}
}
AffinityTopologyVersion updTopVer = cctx.shared().exchange().readyAffinityVersion();
// Remap recursively.
map(remapKeys, mappings, updTopVer);
}
// Add new future.
add(fut0.chain(f -> {
try {
return createResultMap(f.get());
} catch (Exception e) {
U.error(log, "Failed to get values from dht cache [fut=" + fut0 + "]", e);
onDone(e);
return Collections.emptyMap();
}
}));
} else {
MiniFuture miniFut = new MiniFuture(n, mappedKeys, topVer);
GridCacheMessage req = miniFut.createGetRequest(futId);
// Append new future.
add(miniFut);
try {
cctx.io().send(n, req, cctx.ioPolicy());
} catch (IgniteCheckedException e) {
// Fail the whole thing.
if (e instanceof ClusterTopologyCheckedException)
miniFut.onNodeLeft((ClusterTopologyCheckedException) e);
else
miniFut.onResult(e);
}
}
}
markInitialized();
}
use of org.apache.ignite.internal.util.future.GridFinishedFuture in project ignite by apache.
the class GridCacheMvccManager method finishLocks.
/**
* @param filter Entry filter.
* @param topVer Topology version.
* @return Future that signals when all locks for given partitions will be released.
*/
private IgniteInternalFuture<?> finishLocks(@Nullable final IgnitePredicate<GridDistributedCacheEntry> filter, AffinityTopologyVersion topVer) {
assert topVer.topologyVersion() != 0;
if (topVer.equals(AffinityTopologyVersion.NONE))
return new GridFinishedFuture();
final FinishLockFuture finishFut = new FinishLockFuture(filter == null ? locked() : F.view(locked(), filter), topVer);
finishFuts.add(finishFut);
finishFut.listen(new CI1<IgniteInternalFuture<?>>() {
@Override
public void apply(IgniteInternalFuture<?> e) {
finishFuts.remove(finishFut);
}
});
finishFut.recheck();
return finishFut;
}
use of org.apache.ignite.internal.util.future.GridFinishedFuture in project ignite by apache.
the class GridCachePartitionExchangeManager method affinityReadyFuture.
/**
* @param ver Topology version.
* @return Future or {@code null} is future is already completed.
*/
@NotNull
public IgniteInternalFuture<AffinityTopologyVersion> affinityReadyFuture(AffinityTopologyVersion ver) {
GridDhtPartitionsExchangeFuture lastInitializedFut0 = lastInitializedFut;
if (lastInitializedFut0 != null && lastInitializedFut0.initialVersion().compareTo(ver) == 0 && lastInitializedFut0.changedAffinity()) {
if (log.isTraceEnabled())
log.trace("Return lastInitializedFut for topology ready future " + "[ver=" + ver + ", fut=" + lastInitializedFut0 + ']');
return lastInitializedFut0;
}
AffinityTopologyVersion topVer = exchFuts.readyTopVer();
if (topVer.compareTo(ver) >= 0) {
if (log.isTraceEnabled())
log.trace("Return finished future for topology ready future [ver=" + ver + ", topVer=" + topVer + ']');
return new GridFinishedFuture<>(topVer);
}
GridFutureAdapter<AffinityTopologyVersion> fut = F.addIfAbsent(readyFuts, ver, new AffinityReadyFuture(ver));
if (log.isDebugEnabled())
log.debug("Created topology ready future [ver=" + ver + ", fut=" + fut + ']');
topVer = exchFuts.readyTopVer();
if (topVer.compareTo(ver) >= 0) {
if (log.isTraceEnabled())
log.trace("Completing created topology ready future " + "[ver=" + topVer + ", topVer=" + topVer + ", fut=" + fut + ']');
fut.onDone(topVer);
} else if (stopErr != null)
fut.onDone(stopErr);
return fut;
}
use of org.apache.ignite.internal.util.future.GridFinishedFuture in project ignite by apache.
the class GridEncryptionManager method generateKeys.
/**
* @param keyCnt Count of keys to generate.
* @return Future that will contain results of generation.
*/
public IgniteInternalFuture<T2<Collection<byte[]>, byte[]>> generateKeys(int keyCnt) {
if (keyCnt == 0 || !ctx.clientNode())
return new GridFinishedFuture<>(createKeys(keyCnt));
synchronized (opsMux) {
if (disconnected || stopped) {
return new GridFinishedFuture<>(new IgniteFutureCancelledException("Node " + (stopped ? "stopped" : "disconnected")));
}
try {
GenerateEncryptionKeyFuture genEncKeyFut = new GenerateEncryptionKeyFuture(keyCnt);
sendGenerateEncryptionKeyRequest(genEncKeyFut);
genEncKeyFuts.put(genEncKeyFut.id(), genEncKeyFut);
return genEncKeyFut;
} catch (IgniteCheckedException e) {
return new GridFinishedFuture<>(e);
}
}
}
use of org.apache.ignite.internal.util.future.GridFinishedFuture in project ignite by apache.
the class GroupKeyChangeProcess method prepare.
/**
* Validates existing keys.
*
* @param req Request.
* @return Result future.
*/
private IgniteInternalFuture<EmptyResult> prepare(ChangeCacheEncryptionRequest req) {
if (ctx.clientNode())
return new GridFinishedFuture<>();
if (inProgress()) {
return new GridFinishedFuture<>(new IgniteException("Cache group key change was rejected. " + "The previous change was not completed."));
}
if (ctx.cache().context().snapshotMgr().isSnapshotCreating() || ctx.cache().context().snapshotMgr().isRestoring()) {
return new GridFinishedFuture<>(new IgniteException("Cache group key change was rejected. " + "Snapshot operation is in progress."));
}
this.req = req;
try {
for (int i = 0; i < req.groupIds().length; i++) {
int grpId = req.groupIds()[i];
int keyId = req.keyIds()[i] & 0xff;
if (ctx.encryption().reencryptionInProgress(grpId)) {
return new GridFinishedFuture<>(new IgniteException("Cache group key change was rejected. " + "Cache group reencryption is in progress [grpId=" + grpId + "]"));
}
List<Integer> keyIds = ctx.encryption().groupKeyIds(grpId);
if (keyIds == null) {
return new GridFinishedFuture<>(new IgniteException("Cache group key change was rejected." + "Encrypted cache group not found [grpId=" + grpId + "]"));
}
GroupKey currKey = ctx.encryption().getActiveKey(grpId);
for (int locKeyId : keyIds) {
if (locKeyId != keyId)
continue;
Long walSegment = keys.reservedSegment(grpId, keyId);
// Can overwrite inactive key if it was added during prepare phase.
if (walSegment == null && currKey.id() != (byte) keyId)
continue;
return new GridFinishedFuture<>(new IgniteException("Cache group key change was rejected. Cannot add new key identifier, " + "it's already present. There existing WAL segments that encrypted with this key [" + "grpId=" + grpId + ", newId=" + keyId + ", currId=" + currKey.unsignedId() + ", walSegment=" + walSegment + "]."));
}
}
return ctx.encryption().withMasterKeyChangeReadLock(() -> {
if (!Arrays.equals(ctx.config().getEncryptionSpi().masterKeyDigest(), req.masterKeyDigest())) {
return new GridFinishedFuture<>(new IgniteException("Cache group key change was rejected. " + "Master key has been changed."));
}
for (int i = 0; i < req.groupIds().length; i++) {
// Save the new key as inactive, because the master key may change later
// and there will be no way to decrypt the received keys.
GroupKeyEncrypted grpKey = new GroupKeyEncrypted(req.keyIds()[i] & 0xff, req.keys()[i]);
ctx.encryption().addGroupKey(req.groupIds()[i], grpKey);
}
return new GridFinishedFuture<>(new EmptyResult());
});
} catch (Exception e) {
return new GridFinishedFuture<>(new IgniteException("Cache group key change was rejected [nodeId=" + ctx.localNodeId() + ']', e));
}
}
Aggregations