Source:
<code>@Override public final @Nullable Throwable validateCache( GridCacheContext cctx, boolean recovery, boolean read, @Nullable Object key, @Nullable Collection<?> keys ) { assert isDone() : this; Throwable err = error(); if (err != null) return err; if (!clusterIsActive) return new CacheInvalidStateException( "Failed to perform cache operation (cluster is not activated): " + cctx.name()); OperationType opType = read ? OperationType.READ : WRITE; CacheGroupContext grp = cctx.group(); PartitionLossPolicy lossPlc = grp.config().getPartitionLossPolicy(); if (cctx.shared().readOnlyMode() && opType == WRITE && !isSystemCache(cctx.name())) <START> return new СlusterReadOnlyModeCheckedException("Failed to perform cache operation (cluster is in read only mode)"); <END> if (grp.needsRecovery() && !recovery) { if (opType == WRITE && (lossPlc == READ_ONLY_SAFE || lossPlc == READ_ONLY_ALL)) return new IgniteCheckedException( "Failed to write to cache (cache is moved to a read-only state): " + cctx.name()); } CacheGroupValidation validation = grpValidRes.get(grp.groupId()); if (validation == null) return null; if (opType == WRITE && !validation.isValid()) { return new IgniteCheckedException("Failed to perform cache operation " + "(cache topology is not valid): " + cctx.name()); } if (recovery) return null; if (validation.hasLostPartitions()) { if (key != null) return LostPolicyValidator.validate(cctx, key, opType, validation.lostPartitions()); if (keys != null) return LostPolicyValidator.validate(cctx, keys, opType, validation.lostPartitions()); } return null; }</code><technical_language>pattern: read-only</technical_language>

Target:
@Override public final @Nullable Throwable validateCache( GridCacheContext cctx, boolean recovery, boolean read, @Nullable Object key, @Nullable Collection<?> keys ) { assert isDone() : this; Throwable err = error(); if (err != null) return err; if (!clusterIsActive) return new CacheInvalidStateException( "Failed to perform cache operation (cluster is not activated): " + cctx.name()); if (cctx.cache() == null) return new CacheInvalidStateException( "Failed to perform cache operation (cache is stopped): " + cctx.name()); OperationType opType = read ? OperationType.READ : WRITE; CacheGroupContext grp = cctx.group(); PartitionLossPolicy lossPlc = grp.config().getPartitionLossPolicy(); if (cctx.shared().readOnlyMode() && opType == WRITE && !isSystemCache(cctx.name())) return new ClusterReadOnlyModeCheckedException("Failed to perform cache operation (cluster is in read-only mode)"); if (grp.needsRecovery() && !recovery) { if (opType == WRITE && (lossPlc == READ_ONLY_SAFE || lossPlc == READ_ONLY_ALL)) return new IgniteCheckedException( "Failed to write to cache (cache is moved to a read-only state): " + cctx.name()); } CacheGroupValidation validation = grpValidRes.get(grp.groupId()); if (validation == null) return null; if (opType == WRITE && !validation.isValid()) { return new IgniteCheckedException("Failed to perform cache operation " + "(cache topology is not valid): " + cctx.name()); } if (recovery) return null; if (validation.hasLostPartitions()) { if (key != null) return LostPolicyValidator.validate(cctx, key, opType, validation.lostPartitions()); if (keys != null) return LostPolicyValidator.validate(cctx, keys, opType, validation.lostPartitions()); } return null; }