This is an automated email from the ASF dual-hosted git repository.
alexpl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new 794a536737f IGNITE-22189 Add expiry policy info to CacheView - Fixes
#11357.
794a536737f is described below
commit 794a536737f316765e83cb49d661f80849d3bd47
Author: Maksim Davydov <[email protected]>
AuthorDate: Mon Jun 10 18:51:00 2024 +0500
IGNITE-22189 Add expiry policy info to CacheView - Fixes #11357.
Signed-off-by: Aleksey Plekhanov <[email protected]>
---
.../ignite/jdbc/thin/JdbcThinMetadataSelfTest.java | 1 +
.../systemview/walker/CacheViewWalker.java | 176 +++++++++++----------
.../cache/IgniteCacheOffheapManager.java | 8 +
.../cache/IgniteCacheOffheapManagerImpl.java | 16 ++
.../cache/persistence/GridCacheOffheapManager.java | 33 ++++
.../ignite/spi/systemview/view/CacheView.java | 80 +++++++++-
.../metric/SystemViewCacheExpiryPolicyTest.java | 114 +++++++++++++
.../ignite/internal/metric/SystemViewSelfTest.java | 110 +++++++++++++
.../ignite/testsuites/IgniteCacheTestSuite13.java | 2 +
9 files changed, 452 insertions(+), 88 deletions(-)
diff --git
a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
index 135c6fc6a24..82b4fc533e0 100644
---
a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
+++
b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java
@@ -708,6 +708,7 @@ public class JdbcThinMetadataSelfTest extends
JdbcThinAbstractSelfTest {
"SYS.CACHES.NEAR_CACHE_EVICTION_POLICY_FACTORY.null",
"SYS.CACHES.NEAR_CACHE_START_SIZE.null",
"SYS.CACHES.DEFAULT_LOCK_TIMEOUT.null",
+ "SYS.CACHES.HAS_EXPIRING_ENTRIES.null",
"SYS.CACHES.INTERCEPTOR.null",
"SYS.CACHES.CACHE_STORE_FACTORY.null",
"SYS.CACHES.IS_STORE_KEEP_BINARY.null",
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/managers/systemview/walker/CacheViewWalker.java
b/modules/core/src/main/java/org/apache/ignite/internal/managers/systemview/walker/CacheViewWalker.java
index cc98a093710..c59e8f96b74 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/managers/systemview/walker/CacheViewWalker.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/managers/systemview/walker/CacheViewWalker.java
@@ -54,49 +54,50 @@ public class CacheViewWalker implements
SystemViewRowAttributeWalker<CacheView>
v.accept(16, "evictionFilter", String.class);
v.accept(17, "evictionPolicyFactory", String.class);
v.accept(18, "expiryPolicyFactory", String.class);
- v.accept(19, "interceptor", String.class);
- v.accept(20, "isCopyOnRead", boolean.class);
- v.accept(21, "isEagerTtl", boolean.class);
- v.accept(22, "isEncryptionEnabled", boolean.class);
- v.accept(23, "isEventsDisabled", boolean.class);
- v.accept(24, "isInvalidate", boolean.class);
- v.accept(25, "isLoadPreviousValue", boolean.class);
- v.accept(26, "isManagementEnabled", boolean.class);
- v.accept(27, "isNearCacheEnabled", boolean.class);
- v.accept(28, "isOnheapCacheEnabled", boolean.class);
- v.accept(29, "isReadFromBackup", boolean.class);
- v.accept(30, "isReadThrough", boolean.class);
- v.accept(31, "isSqlEscapeAll", boolean.class);
- v.accept(32, "isSqlOnheapCacheEnabled", boolean.class);
- v.accept(33, "isStatisticsEnabled", boolean.class);
- v.accept(34, "isStoreKeepBinary", boolean.class);
- v.accept(35, "isWriteBehindEnabled", boolean.class);
- v.accept(36, "isWriteThrough", boolean.class);
- v.accept(37, "maxConcurrentAsyncOperations", int.class);
- v.accept(38, "maxQueryIteratorsCount", int.class);
- v.accept(39, "nearCacheEvictionPolicyFactory", String.class);
- v.accept(40, "nearCacheStartSize", int.class);
- v.accept(41, "nodeFilter", String.class);
- v.accept(42, "partitionLossPolicy", PartitionLossPolicy.class);
- v.accept(43, "queryDetailMetricsSize", int.class);
- v.accept(44, "queryParallelism", int.class);
- v.accept(45, "rebalanceBatchSize", int.class);
- v.accept(46, "rebalanceBatchesPrefetchCount", long.class);
- v.accept(47, "rebalanceDelay", long.class);
- v.accept(48, "rebalanceMode", CacheRebalanceMode.class);
- v.accept(49, "rebalanceOrder", int.class);
- v.accept(50, "rebalanceThrottle", long.class);
- v.accept(51, "rebalanceTimeout", long.class);
- v.accept(52, "sqlIndexMaxInlineSize", int.class);
- v.accept(53, "sqlOnheapCacheMaxSize", int.class);
- v.accept(54, "sqlSchema", String.class);
- v.accept(55, "topologyValidator", String.class);
- v.accept(56, "writeBehindBatchSize", int.class);
- v.accept(57, "writeBehindCoalescing", boolean.class);
- v.accept(58, "writeBehindFlushFrequency", long.class);
- v.accept(59, "writeBehindFlushSize", int.class);
- v.accept(60, "writeBehindFlushThreadCount", int.class);
- v.accept(61, "writeSynchronizationMode",
CacheWriteSynchronizationMode.class);
+ v.accept(19, "hasExpiringEntries", String.class);
+ v.accept(20, "interceptor", String.class);
+ v.accept(21, "isCopyOnRead", boolean.class);
+ v.accept(22, "isEagerTtl", boolean.class);
+ v.accept(23, "isEncryptionEnabled", boolean.class);
+ v.accept(24, "isEventsDisabled", boolean.class);
+ v.accept(25, "isInvalidate", boolean.class);
+ v.accept(26, "isLoadPreviousValue", boolean.class);
+ v.accept(27, "isManagementEnabled", boolean.class);
+ v.accept(28, "isNearCacheEnabled", boolean.class);
+ v.accept(29, "isOnheapCacheEnabled", boolean.class);
+ v.accept(30, "isReadFromBackup", boolean.class);
+ v.accept(31, "isReadThrough", boolean.class);
+ v.accept(32, "isSqlEscapeAll", boolean.class);
+ v.accept(33, "isSqlOnheapCacheEnabled", boolean.class);
+ v.accept(34, "isStatisticsEnabled", boolean.class);
+ v.accept(35, "isStoreKeepBinary", boolean.class);
+ v.accept(36, "isWriteBehindEnabled", boolean.class);
+ v.accept(37, "isWriteThrough", boolean.class);
+ v.accept(38, "maxConcurrentAsyncOperations", int.class);
+ v.accept(39, "maxQueryIteratorsCount", int.class);
+ v.accept(40, "nearCacheEvictionPolicyFactory", String.class);
+ v.accept(41, "nearCacheStartSize", int.class);
+ v.accept(42, "nodeFilter", String.class);
+ v.accept(43, "partitionLossPolicy", PartitionLossPolicy.class);
+ v.accept(44, "queryDetailMetricsSize", int.class);
+ v.accept(45, "queryParallelism", int.class);
+ v.accept(46, "rebalanceBatchSize", int.class);
+ v.accept(47, "rebalanceBatchesPrefetchCount", long.class);
+ v.accept(48, "rebalanceDelay", long.class);
+ v.accept(49, "rebalanceMode", CacheRebalanceMode.class);
+ v.accept(50, "rebalanceOrder", int.class);
+ v.accept(51, "rebalanceThrottle", long.class);
+ v.accept(52, "rebalanceTimeout", long.class);
+ v.accept(53, "sqlIndexMaxInlineSize", int.class);
+ v.accept(54, "sqlOnheapCacheMaxSize", int.class);
+ v.accept(55, "sqlSchema", String.class);
+ v.accept(56, "topologyValidator", String.class);
+ v.accept(57, "writeBehindBatchSize", int.class);
+ v.accept(58, "writeBehindCoalescing", boolean.class);
+ v.accept(59, "writeBehindFlushFrequency", long.class);
+ v.accept(60, "writeBehindFlushSize", int.class);
+ v.accept(61, "writeBehindFlushThreadCount", int.class);
+ v.accept(62, "writeSynchronizationMode",
CacheWriteSynchronizationMode.class);
}
/** {@inheritDoc} */
@@ -120,53 +121,54 @@ public class CacheViewWalker implements
SystemViewRowAttributeWalker<CacheView>
v.accept(16, "evictionFilter", String.class, row.evictionFilter());
v.accept(17, "evictionPolicyFactory", String.class,
row.evictionPolicyFactory());
v.accept(18, "expiryPolicyFactory", String.class,
row.expiryPolicyFactory());
- v.accept(19, "interceptor", String.class, row.interceptor());
- v.acceptBoolean(20, "isCopyOnRead", row.isCopyOnRead());
- v.acceptBoolean(21, "isEagerTtl", row.isEagerTtl());
- v.acceptBoolean(22, "isEncryptionEnabled", row.isEncryptionEnabled());
- v.acceptBoolean(23, "isEventsDisabled", row.isEventsDisabled());
- v.acceptBoolean(24, "isInvalidate", row.isInvalidate());
- v.acceptBoolean(25, "isLoadPreviousValue", row.isLoadPreviousValue());
- v.acceptBoolean(26, "isManagementEnabled", row.isManagementEnabled());
- v.acceptBoolean(27, "isNearCacheEnabled", row.isNearCacheEnabled());
- v.acceptBoolean(28, "isOnheapCacheEnabled",
row.isOnheapCacheEnabled());
- v.acceptBoolean(29, "isReadFromBackup", row.isReadFromBackup());
- v.acceptBoolean(30, "isReadThrough", row.isReadThrough());
- v.acceptBoolean(31, "isSqlEscapeAll", row.isSqlEscapeAll());
- v.acceptBoolean(32, "isSqlOnheapCacheEnabled",
row.isSqlOnheapCacheEnabled());
- v.acceptBoolean(33, "isStatisticsEnabled", row.isStatisticsEnabled());
- v.acceptBoolean(34, "isStoreKeepBinary", row.isStoreKeepBinary());
- v.acceptBoolean(35, "isWriteBehindEnabled",
row.isWriteBehindEnabled());
- v.acceptBoolean(36, "isWriteThrough", row.isWriteThrough());
- v.acceptInt(37, "maxConcurrentAsyncOperations",
row.maxConcurrentAsyncOperations());
- v.acceptInt(38, "maxQueryIteratorsCount",
row.maxQueryIteratorsCount());
- v.accept(39, "nearCacheEvictionPolicyFactory", String.class,
row.nearCacheEvictionPolicyFactory());
- v.acceptInt(40, "nearCacheStartSize", row.nearCacheStartSize());
- v.accept(41, "nodeFilter", String.class, row.nodeFilter());
- v.accept(42, "partitionLossPolicy", PartitionLossPolicy.class,
row.partitionLossPolicy());
- v.acceptInt(43, "queryDetailMetricsSize",
row.queryDetailMetricsSize());
- v.acceptInt(44, "queryParallelism", row.queryParallelism());
- v.acceptInt(45, "rebalanceBatchSize", row.rebalanceBatchSize());
- v.acceptLong(46, "rebalanceBatchesPrefetchCount",
row.rebalanceBatchesPrefetchCount());
- v.acceptLong(47, "rebalanceDelay", row.rebalanceDelay());
- v.accept(48, "rebalanceMode", CacheRebalanceMode.class,
row.rebalanceMode());
- v.acceptInt(49, "rebalanceOrder", row.rebalanceOrder());
- v.acceptLong(50, "rebalanceThrottle", row.rebalanceThrottle());
- v.acceptLong(51, "rebalanceTimeout", row.rebalanceTimeout());
- v.acceptInt(52, "sqlIndexMaxInlineSize", row.sqlIndexMaxInlineSize());
- v.acceptInt(53, "sqlOnheapCacheMaxSize", row.sqlOnheapCacheMaxSize());
- v.accept(54, "sqlSchema", String.class, row.sqlSchema());
- v.accept(55, "topologyValidator", String.class,
row.topologyValidator());
- v.acceptInt(56, "writeBehindBatchSize", row.writeBehindBatchSize());
- v.acceptBoolean(57, "writeBehindCoalescing",
row.writeBehindCoalescing());
- v.acceptLong(58, "writeBehindFlushFrequency",
row.writeBehindFlushFrequency());
- v.acceptInt(59, "writeBehindFlushSize", row.writeBehindFlushSize());
- v.acceptInt(60, "writeBehindFlushThreadCount",
row.writeBehindFlushThreadCount());
- v.accept(61, "writeSynchronizationMode",
CacheWriteSynchronizationMode.class, row.writeSynchronizationMode());
+ v.accept(19, "hasExpiringEntries", String.class,
row.hasExpiringEntries());
+ v.accept(20, "interceptor", String.class, row.interceptor());
+ v.acceptBoolean(21, "isCopyOnRead", row.isCopyOnRead());
+ v.acceptBoolean(22, "isEagerTtl", row.isEagerTtl());
+ v.acceptBoolean(23, "isEncryptionEnabled", row.isEncryptionEnabled());
+ v.acceptBoolean(24, "isEventsDisabled", row.isEventsDisabled());
+ v.acceptBoolean(25, "isInvalidate", row.isInvalidate());
+ v.acceptBoolean(26, "isLoadPreviousValue", row.isLoadPreviousValue());
+ v.acceptBoolean(27, "isManagementEnabled", row.isManagementEnabled());
+ v.acceptBoolean(28, "isNearCacheEnabled", row.isNearCacheEnabled());
+ v.acceptBoolean(29, "isOnheapCacheEnabled",
row.isOnheapCacheEnabled());
+ v.acceptBoolean(30, "isReadFromBackup", row.isReadFromBackup());
+ v.acceptBoolean(31, "isReadThrough", row.isReadThrough());
+ v.acceptBoolean(32, "isSqlEscapeAll", row.isSqlEscapeAll());
+ v.acceptBoolean(33, "isSqlOnheapCacheEnabled",
row.isSqlOnheapCacheEnabled());
+ v.acceptBoolean(34, "isStatisticsEnabled", row.isStatisticsEnabled());
+ v.acceptBoolean(35, "isStoreKeepBinary", row.isStoreKeepBinary());
+ v.acceptBoolean(36, "isWriteBehindEnabled",
row.isWriteBehindEnabled());
+ v.acceptBoolean(37, "isWriteThrough", row.isWriteThrough());
+ v.acceptInt(38, "maxConcurrentAsyncOperations",
row.maxConcurrentAsyncOperations());
+ v.acceptInt(39, "maxQueryIteratorsCount",
row.maxQueryIteratorsCount());
+ v.accept(40, "nearCacheEvictionPolicyFactory", String.class,
row.nearCacheEvictionPolicyFactory());
+ v.acceptInt(41, "nearCacheStartSize", row.nearCacheStartSize());
+ v.accept(42, "nodeFilter", String.class, row.nodeFilter());
+ v.accept(43, "partitionLossPolicy", PartitionLossPolicy.class,
row.partitionLossPolicy());
+ v.acceptInt(44, "queryDetailMetricsSize",
row.queryDetailMetricsSize());
+ v.acceptInt(45, "queryParallelism", row.queryParallelism());
+ v.acceptInt(46, "rebalanceBatchSize", row.rebalanceBatchSize());
+ v.acceptLong(47, "rebalanceBatchesPrefetchCount",
row.rebalanceBatchesPrefetchCount());
+ v.acceptLong(48, "rebalanceDelay", row.rebalanceDelay());
+ v.accept(49, "rebalanceMode", CacheRebalanceMode.class,
row.rebalanceMode());
+ v.acceptInt(50, "rebalanceOrder", row.rebalanceOrder());
+ v.acceptLong(51, "rebalanceThrottle", row.rebalanceThrottle());
+ v.acceptLong(52, "rebalanceTimeout", row.rebalanceTimeout());
+ v.acceptInt(53, "sqlIndexMaxInlineSize", row.sqlIndexMaxInlineSize());
+ v.acceptInt(54, "sqlOnheapCacheMaxSize", row.sqlOnheapCacheMaxSize());
+ v.accept(55, "sqlSchema", String.class, row.sqlSchema());
+ v.accept(56, "topologyValidator", String.class,
row.topologyValidator());
+ v.acceptInt(57, "writeBehindBatchSize", row.writeBehindBatchSize());
+ v.acceptBoolean(58, "writeBehindCoalescing",
row.writeBehindCoalescing());
+ v.acceptLong(59, "writeBehindFlushFrequency",
row.writeBehindFlushFrequency());
+ v.acceptInt(60, "writeBehindFlushSize", row.writeBehindFlushSize());
+ v.acceptInt(61, "writeBehindFlushThreadCount",
row.writeBehindFlushThreadCount());
+ v.accept(62, "writeSynchronizationMode",
CacheWriteSynchronizationMode.class, row.writeSynchronizationMode());
}
/** {@inheritDoc} */
@Override public int count() {
- return 62;
+ return 63;
}
}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManager.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManager.java
index e10c6ed4544..d437b179769 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManager.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManager.java
@@ -170,6 +170,14 @@ public interface IgniteCacheOffheapManager {
*/
public long expiredSize() throws IgniteCheckedException;
+ /**
+ * Checks if the cache has entries pending expire.
+ *
+ * @return {@code True} if there are entries pending expire.
+ * @throws IgniteCheckedException If failed to get number of pending
entries.
+ */
+ public boolean hasEntriesPendingExpire(int cacheId) throws
IgniteCheckedException;
+
/**
* @param cctx Cache context.
* @param key Key.
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
index f1b0f215335..923eb153bef 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
@@ -1174,6 +1174,22 @@ public class IgniteCacheOffheapManagerImpl implements
IgniteCacheOffheapManager
return pendingEntries != null ? pendingEntries.size() : 0;
}
+ /** {@inheritDoc} */
+ @Override public boolean hasEntriesPendingExpire(int cacheId) throws
IgniteCheckedException {
+ if (pendingEntries == null)
+ return false;
+
+ if (grp.sharedGroup()) {
+ PendingRow row = new PendingRow(cacheId);
+
+ GridCursor<PendingRow> cursor = pendingEntries.find(row, row,
PendingEntriesTree.WITHOUT_KEY);
+
+ return cursor.next();
+ }
+ else
+ return !pendingEntries.isEmpty();
+ }
+
/**
*
*/
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
index 9643b65c707..5056f063189 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
@@ -1154,6 +1154,16 @@ public class GridCacheOffheapManager extends
IgniteCacheOffheapManagerImpl imple
return size;
}
+ /** {@inheritDoc} */
+ @Override public boolean hasEntriesPendingExpire(int cacheId) throws
IgniteCheckedException {
+ for (CacheDataStore store : cacheDataStores()) {
+ if (((GridCacheDataStore)store).hasEntriesPendingExpire(cacheId))
+ return true;
+ }
+
+ return false;
+ }
+
/** {@inheritDoc} */
@Override public void preloadPartition(int partId) throws
IgniteCheckedException {
GridDhtLocalPartition locPart = grp.topology().localPartition(partId,
AffinityTopologyVersion.NONE, false, false);
@@ -2660,6 +2670,29 @@ public class GridCacheOffheapManager extends
IgniteCacheOffheapManagerImpl imple
return delegate0 == null ? 0 : pendingTree.size();
}
+ /**
+ * Checks if the cache has entries pending expire.
+ *
+ * @return {@code True} if there are entries pending expire.
+ * @throws IgniteCheckedException If failed to get number of pending
entries.
+ */
+ public boolean hasEntriesPendingExpire(int cacheId) throws
IgniteCheckedException {
+ CacheDataStore delegate0 = init0(true);
+
+ if (delegate0 == null)
+ return false;
+
+ if (grp.sharedGroup()) {
+ PendingRow row = new PendingRow(cacheId);
+
+ GridCursor<PendingRow> cur = pendingTree.find(row, row,
PendingEntriesTree.WITHOUT_KEY);
+
+ return cur.next();
+ }
+ else
+ return !pendingTree.isEmpty();
+ }
+
/**
* Try to remove expired entries from data store.
*
diff --git
a/modules/core/src/main/java/org/apache/ignite/spi/systemview/view/CacheView.java
b/modules/core/src/main/java/org/apache/ignite/spi/systemview/view/CacheView.java
index 72c663fb3e7..2cc1ca8d655 100644
---
a/modules/core/src/main/java/org/apache/ignite/spi/systemview/view/CacheView.java
+++
b/modules/core/src/main/java/org/apache/ignite/spi/systemview/view/CacheView.java
@@ -17,6 +17,11 @@
package org.apache.ignite.spi.systemview.view;
+import java.util.concurrent.atomic.AtomicBoolean;
+import javax.cache.configuration.Factory;
+import javax.cache.expiry.Duration;
+import javax.cache.expiry.ExpiryPolicy;
+import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.cache.CacheRebalanceMode;
@@ -29,11 +34,13 @@ import
org.apache.ignite.configuration.NearCacheConfiguration;
import org.apache.ignite.configuration.TopologyValidator;
import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.managers.systemview.walker.Order;
+import org.apache.ignite.internal.processors.cache.CacheGroupContext;
import org.apache.ignite.internal.processors.cache.CacheGroupDescriptor;
import org.apache.ignite.internal.processors.cache.CacheType;
import org.apache.ignite.internal.processors.cache.DynamicCacheDescriptor;
import org.apache.ignite.internal.processors.cache.IgniteInternalCache;
import
org.apache.ignite.internal.processors.cache.version.CacheVersionConflictResolver;
+import org.apache.ignite.internal.util.typedef.internal.S;
import static org.apache.ignite.internal.util.IgniteUtils.toStringSafe;
@@ -331,7 +338,78 @@ public class CacheView {
/** @see CacheConfiguration#getExpiryPolicyFactory() */
public String expiryPolicyFactory() {
- return
toStringSafe(cache.cacheConfiguration().getExpiryPolicyFactory());
+ if (cache.cacheConfiguration().getExpiryPolicyFactory() == null)
+ return null;
+
+ ExpiryPolicy expiryPlc =
(ExpiryPolicy)cache.cacheConfiguration().getExpiryPolicyFactory().create();
+
+ AtomicBoolean first = new AtomicBoolean(true);
+
+ StringBuilder expiryPlcStrBld = new
StringBuilder(expiryPlc.getClass().getSimpleName());
+
+ appendField(expiryPlcStrBld, "create",
expiryPlc.getExpiryForCreation(), first);
+ appendField(expiryPlcStrBld, "update", expiryPlc.getExpiryForUpdate(),
first);
+ appendField(expiryPlcStrBld, "access", expiryPlc.getExpiryForAccess(),
first);
+
+ if (!first.get())
+ expiryPlcStrBld.append(']');
+
+ return
S.toString((Class<Factory<?>>)cache.cacheConfiguration().getExpiryPolicyFactory().getClass(),
+ cache.cacheConfiguration().getExpiryPolicyFactory(), "expiryPlc",
expiryPlcStrBld);
+ }
+
+ /**
+ * @param out {@link StringBuilder} to append to.
+ * @param fieldName create/update/access expiry policy field name.
+ * @param duration {@link Duration} for specified expiry policy field name.
+ * @param first {@link AtomicBoolean} flag indicating whether the field is
the first in sequence.
+ */
+ private static void appendField(
+ StringBuilder out,
+ String fieldName,
+ Duration duration,
+ AtomicBoolean first
+ ) {
+ if (duration != null) {
+ if (!first.get())
+ out.append(", ");
+ else {
+ out.append(" [");
+ first.compareAndSet(true, false);
+ }
+
+ out.append(fieldName).append('=');
+ appendDuration(out, duration);
+ }
+ }
+
+ /**
+ * Duration representation for specified StringBuilder instance.
+ * @param out {@link StringBuilder} to append to.
+ * @param duration {@link Duration}.
+ */
+ private static void appendDuration(StringBuilder out, Duration duration) {
+ if (duration.isEternal())
+ out.append("ETERNAL");
+ else if (duration.isZero())
+ out.append("ZERO");
+ else
+ out.append(duration.getDurationAmount()).append('
').append(duration.getTimeUnit());
+ }
+
+ /** @return {@code Yes} if cache has expired entries, {@code No}
otherwise. If {@code eagerTtl = true} returns 'Unknown'. */
+ public String hasExpiringEntries() {
+ CacheGroupContext grpCtx = ctx.cache().cacheGroup(cache.groupId());
+
+ if (!cache.cacheConfiguration().isEagerTtl() || grpCtx == null)
+ return "Unknown";
+
+ try {
+ return grpCtx.offheap().hasEntriesPendingExpire(cache.cacheId()) ?
"Yes" : "No";
+ }
+ catch (IgniteCheckedException e) {
+ return e.getMessage();
+ }
}
/** @see CacheConfiguration#isSqlEscapeAll() */
diff --git
a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewCacheExpiryPolicyTest.java
b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewCacheExpiryPolicyTest.java
new file mode 100644
index 00000000000..d0bda2428c8
--- /dev/null
+++
b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewCacheExpiryPolicyTest.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.ignite.internal.metric;
+
+import java.util.Arrays;
+import java.util.Collection;
+import javax.cache.configuration.Factory;
+import javax.cache.expiry.AccessedExpiryPolicy;
+import javax.cache.expiry.CreatedExpiryPolicy;
+import javax.cache.expiry.Duration;
+import javax.cache.expiry.EternalExpiryPolicy;
+import javax.cache.expiry.ExpiryPolicy;
+import javax.cache.expiry.ModifiedExpiryPolicy;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import
org.apache.ignite.internal.processors.platform.cache.expiry.PlatformExpiryPolicyFactory;
+import org.apache.ignite.spi.systemview.view.CacheView;
+import org.apache.ignite.spi.systemview.view.SystemView;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.MINUTES;
+import static
org.apache.ignite.internal.processors.cache.ClusterCachesInfo.CACHES_VIEW;
+
+/** Tests for {@link CacheView} expiry policy factory representation. */
+@RunWith(Parameterized.class)
+public class SystemViewCacheExpiryPolicyTest extends GridCommonAbstractTest {
+ /** {@link Factory} instances for test with different expiry policy. */
+ private static final Factory[] TTL_FACTORIES = {
+ null,
+ EternalExpiryPolicy.factoryOf(),
+ CreatedExpiryPolicy.factoryOf(new Duration(MILLISECONDS, 100L)),
+ ModifiedExpiryPolicy.factoryOf(new Duration(MILLISECONDS, 5L)),
+ AccessedExpiryPolicy.factoryOf(new Duration(MINUTES, 10L)),
+ new PlatformExpiryPolicyFactory(2, 4, 8),
+ new PlatformExpiryPolicyFactory(1, -2, -1),
+ new PlatformExpiryPolicyFactory(-1, 0, -1),
+ new PlatformExpiryPolicyFactory(0, 1, -1)
+ };
+
+ /** {@link Factory} instance. */
+ @Parameterized.Parameter
+ public Factory<ExpiryPolicy> factory;
+
+ /** Anticipated {@link String} expiry policy factory representation. */
+ @Parameterized.Parameter(1)
+ public String actual;
+
+ /**
+ * @return Test parameters.
+ */
+ @Parameterized.Parameters(name = "factory={0}, actual={1}")
+ public static Collection parameters() {
+ return Arrays.asList(new Object[][] {
+ {TTL_FACTORIES[0], "SingletonFactory
[expiryPlc=EternalExpiryPolicy [create=ETERNAL]]"},
+ {TTL_FACTORIES[1], "SingletonFactory
[expiryPlc=EternalExpiryPolicy [create=ETERNAL]]"},
+ {TTL_FACTORIES[2], "SingletonFactory
[expiryPlc=CreatedExpiryPolicy [create=100 MILLISECONDS]]"},
+ {TTL_FACTORIES[3], "SingletonFactory
[expiryPlc=ModifiedExpiryPolicy [create=5 MILLISECONDS, update=5
MILLISECONDS]]"},
+ {TTL_FACTORIES[4], "SingletonFactory
[expiryPlc=AccessedExpiryPolicy [create=10 MINUTES, access=10 MINUTES]]"},
+ {
+ TTL_FACTORIES[5], "PlatformExpiryPolicyFactory [create=2,
update=4, access=8," +
+ " expiryPlc=PlatformExpiryPolicy [create=2 MILLISECONDS,
update=4 MILLISECONDS, access=8 MILLISECONDS]]"},
+ {
+ TTL_FACTORIES[6], "PlatformExpiryPolicyFactory [create=1,
update=-2, access=-1," +
+ " expiryPlc=PlatformExpiryPolicy [create=1 MILLISECONDS,
access=ETERNAL]]"},
+ {
+ TTL_FACTORIES[7], "PlatformExpiryPolicyFactory [create=-1,
update=0, access=-1," +
+ " expiryPlc=PlatformExpiryPolicy [create=ETERNAL,
update=ZERO, access=ETERNAL]]"},
+ {
+ TTL_FACTORIES[8], "PlatformExpiryPolicyFactory [create=0,
update=1, access=-1," +
+ " expiryPlc=PlatformExpiryPolicy [create=ZERO, update=1
MILLISECONDS, access=ETERNAL]]"}
+ });
+ }
+
+ /**
+ * Test for {@link CacheView} expiry policy factory representation. The
test initializes the {@link CacheConfiguration}
+ * with custom {@link PlatformExpiryPolicyFactory}. Given different ttl
input, the test checks the {@link String}
+ * expiry policy factory outcome for {@link
CacheView#expiryPolicyFactory()}.
+ */
+ @Test
+ public void testCacheViewExpiryPolicy() throws Exception {
+ try (IgniteEx g = startGrid()) {
+ CacheConfiguration<Integer, Integer> ccfg = new
CacheConfiguration<>();
+ ccfg.setName("cache");
+ ccfg.setExpiryPolicyFactory(factory);
+
+ g.getOrCreateCache(ccfg);
+
+ SystemView<CacheView> caches =
g.context().systemView().view(CACHES_VIEW);
+
+ for (CacheView row : caches)
+ if ("cache".equals(row.cacheName()))
+ assertEquals(actual, row.expiryPolicyFactory());
+ }
+ }
+}
diff --git
a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewSelfTest.java
b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewSelfTest.java
index fce35b6ae41..ebf2a5388a1 100644
---
a/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewSelfTest.java
+++
b/modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewSelfTest.java
@@ -36,6 +36,10 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import javax.cache.Cache;
+import javax.cache.expiry.CreatedExpiryPolicy;
+import javax.cache.expiry.Duration;
+import javax.cache.expiry.EternalExpiryPolicy;
+import javax.cache.expiry.ModifiedExpiryPolicy;
import com.google.common.collect.Lists;
import org.apache.ignite.IgniteAtomicLong;
import org.apache.ignite.IgniteAtomicReference;
@@ -259,6 +263,112 @@ public class SystemViewSelfTest extends
GridCommonAbstractTest {
}
}
+ /** Tests work of {@link SystemView} for cache expiry policy info with
in-memory configuration. */
+ @Test
+ public void testCacheViewExpiryPolicyWithInMemory() throws Exception {
+ testCacheViewExpiryPolicy(false);
+ }
+
+ /** Tests work of {@link SystemView} for cache expiry policy info with
persist configuration. */
+ @Test
+ public void testCacheViewExpiryPolicyWithPersist() throws Exception {
+ testCacheViewExpiryPolicy(true);
+ }
+
+ /** Tests work of {@link SystemView} for cache groups expiry policy info.
*/
+ private void testCacheViewExpiryPolicy(boolean withPersistence) throws
Exception {
+ try (IgniteEx g = !withPersistence ? startGrid() :
startGrid(getConfiguration().setDataStorageConfiguration(
+ new DataStorageConfiguration().setDefaultDataRegionConfiguration(
+ new DataRegionConfiguration().setPersistenceEnabled(true)
+ )))) {
+
+ if (withPersistence)
+ g.cluster().state(ClusterState.ACTIVE);
+
+ String eternalCacheName = "eternalCache";
+ String createdCacheName = "createdCache";
+ String eagerTtlCacheName = "eagerTtlCache";
+ String withoutGrpCacheName = "withoutGrpCache";
+ String dfltCacheName = "defaultCache";
+
+ CacheConfiguration<Long, Long> eternalCache = new
CacheConfiguration<Long, Long>(eternalCacheName)
+ .setGroupName("group1")
+ .setExpiryPolicyFactory(EternalExpiryPolicy.factoryOf());
+
+ CacheConfiguration<Long, Long> createdCache = new
CacheConfiguration<Long, Long>(createdCacheName)
+ .setGroupName("group2")
+ .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new
Duration(TimeUnit.MILLISECONDS, 500L)));
+
+ CacheConfiguration<Long, Long> eagerTtlCache = new
CacheConfiguration<Long, Long>(eagerTtlCacheName)
+ .setGroupName("group2")
+ .setEagerTtl(false)
+ .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new
Duration(TimeUnit.MILLISECONDS, 500L)));
+
+ CacheConfiguration<Long, Long> withoutGrpCache = new
CacheConfiguration<Long, Long>(withoutGrpCacheName)
+ .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new
Duration(TimeUnit.MILLISECONDS, 500L)));
+
+ CacheConfiguration<Long, Long> dfltCache = new
CacheConfiguration<Long, Long>(dfltCacheName)
+ .setGroupName("group3");
+
+ g.createCache(eternalCache);
+ g.createCache(createdCache);
+ g.createCache(eagerTtlCache);
+ g.createCache(withoutGrpCache);
+ g.createCache(dfltCache);
+
+ SystemView<CacheView> caches =
g.context().systemView().view(CACHES_VIEW);
+
+ for (CacheView row : caches) {
+ switch (row.cacheName()) {
+ case "defaultCache":
+ case "eternalCache":
+ assertEquals("No", row.hasExpiringEntries());
+
+ g.cache(row.cacheName()).put(0, 0);
+
+ assertEquals("No", row.hasExpiringEntries());
+
+ g.cache(row.cacheName())
+ .withExpiryPolicy(new CreatedExpiryPolicy(new
Duration(TimeUnit.MILLISECONDS, 200L)))
+ .put(1, 1);
+
+ assertEquals("Yes", row.hasExpiringEntries());
+ assertTrue(waitForCondition(() ->
"No".equals(row.hasExpiringEntries()), getTestTimeout()));
+
+ break;
+
+ case "withoutGrpCache":
+ case "createdCache":
+ assertEquals("No", row.hasExpiringEntries());
+
+ g.cache(row.cacheName()).put(0, 0);
+
+ assertEquals("Yes", row.hasExpiringEntries());
+ assertTrue(waitForCondition(() ->
"No".equals(row.hasExpiringEntries()), getTestTimeout()));
+
+ g.cache(row.cacheName())
+ .withExpiryPolicy(new ModifiedExpiryPolicy(new
Duration(TimeUnit.MILLISECONDS, 200L)))
+ .put(1, 1);
+
+ assertEquals("Yes", row.hasExpiringEntries());
+ assertTrue(waitForCondition(() ->
"No".equals(row.hasExpiringEntries()), getTestTimeout()));
+
+ if (row.cacheName().equals(createdCacheName)) {
+ g.cache(eagerTtlCacheName).put(2, 2);
+ assertEquals("No", row.hasExpiringEntries());
+ }
+
+ break;
+
+ case "eagerTtlCache":
+ assertEquals("Unknown", row.hasExpiringEntries());
+
+ break;
+ }
+ }
+ }
+ }
+
/** Tests work of {@link SystemView} for services. */
@Test
public void testServices() throws Exception {
diff --git
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite13.java
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite13.java
index 6c9daabd47d..58ace1eff29 100644
---
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite13.java
+++
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite13.java
@@ -32,6 +32,7 @@ import
org.apache.ignite.internal.metric.MetricsConfigurationTest;
import org.apache.ignite.internal.metric.MetricsSelfTest;
import org.apache.ignite.internal.metric.ReadMetricsOnNodeStartupTest;
import org.apache.ignite.internal.metric.SystemMetricsTest;
+import org.apache.ignite.internal.metric.SystemViewCacheExpiryPolicyTest;
import org.apache.ignite.internal.metric.SystemViewClusterActivationTest;
import org.apache.ignite.internal.metric.SystemViewComputeJobTest;
import org.apache.ignite.internal.metric.SystemViewSelfTest;
@@ -86,6 +87,7 @@ public class IgniteCacheTestSuite13 {
GridTestUtils.addTestIfNeeded(suite, SystemViewSelfTest.class,
ignoredTests);
GridTestUtils.addTestIfNeeded(suite,
SystemViewClusterActivationTest.class, ignoredTests);
GridTestUtils.addTestIfNeeded(suite, SystemViewComputeJobTest.class,
ignoredTests);
+ GridTestUtils.addTestIfNeeded(suite,
SystemViewCacheExpiryPolicyTest.class, ignoredTests);
GridTestUtils.addTestIfNeeded(suite, CacheMetricsAddRemoveTest.class,
ignoredTests);
GridTestUtils.addTestIfNeeded(suite, JmxExporterSpiTest.class,
ignoredTests);
GridTestUtils.addTestIfNeeded(suite, LogExporterSpiTest.class,
ignoredTests);