You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ni...@apache.org on 2020/09/09 15:10:37 UTC

[ignite] branch master updated: IGNITE-13408 BinaryMetatadatView introduced (#8228)

This is an automated email from the ASF dual-hosted git repository.

nizhikov 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 589efec  IGNITE-13408 BinaryMetatadatView introduced (#8228)
589efec is described below

commit 589efec218110bd35071b721aafc0b5869534c54
Author: Nikolay <ni...@apache.org>
AuthorDate: Wed Sep 9 18:10:10 2020 +0300

    IGNITE-13408 BinaryMetatadatView introduced (#8228)
---
 .../internal/jdbc2/JdbcMetadataSelfTest.java       |  3 +-
 .../ignite/jdbc/thin/JdbcThinMetadataSelfTest.java | 12 ++-
 .../SystemViewRowAttributeWalkerGenerator.java     |  2 +
 .../walker/BinaryMetadataViewWalker.java           | 56 ++++++++++++++
 .../binary/CacheObjectBinaryProcessorImpl.java     | 12 +++
 .../spi/systemview/view/BinaryMetadataView.java    | 85 ++++++++++++++++++++++
 .../ignite/internal/metric/JmxExporterSpiTest.java | 39 ++++++++++
 .../ignite/internal/metric/SystemViewSelfTest.java | 40 ++++++++++
 .../cache/metric/SqlViewExporterSpiTest.java       | 52 ++++++++++++-
 9 files changed, 297 insertions(+), 4 deletions(-)

diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcMetadataSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcMetadataSelfTest.java
index aa1237f..604ba15 100755
--- a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcMetadataSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcMetadataSelfTest.java
@@ -345,7 +345,8 @@ public class JdbcMetadataSelfTest extends GridCommonAbstractTest {
             "STRIPED_THREADPOOL_QUEUE",
             "DATASTREAM_THREADPOOL_QUEUE",
             "CACHE_GROUP_PAGE_LISTS",
-            "PARTITION_STATES"
+            "PARTITION_STATES",
+            "BINARY_METADATA"
         ));
 
         Set<String> actViews = new HashSet<>();
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 4fba9eb..4abe84f 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
@@ -443,7 +443,8 @@ public class JdbcThinMetadataSelfTest extends JdbcThinAbstractSelfTest {
                 "SYS.DATASTREAM_THREADPOOL_QUEUE",
                 "SYS.CACHE_GROUP_PAGE_LISTS",
                 "SYS.DATA_REGION_PAGE_LISTS",
-                "SYS.PARTITION_STATES"
+                "SYS.PARTITION_STATES",
+                "SYS.BINARY_METADATA"
             ))
         );
     }
@@ -988,7 +989,14 @@ public class JdbcThinMetadataSelfTest extends JdbcThinAbstractSelfTest {
                 "SYS.PARTITION_STATES.PARTITION_ID.null.10",
                 "SYS.PARTITION_STATES.NODE_ID.null.2147483647",
                 "SYS.PARTITION_STATES.STATE.null.2147483647",
-                "SYS.PARTITION_STATES.IS_PRIMARY.null.1"
+                "SYS.PARTITION_STATES.IS_PRIMARY.null.1",
+                "SYS.BINARY_METADATA.FIELDS.null.2147483647",
+                "SYS.BINARY_METADATA.AFF_KEY_FIELD_NAME.null.2147483647",
+                "SYS.BINARY_METADATA.SCHEMAS_IDS.null.2147483647",
+                "SYS.BINARY_METADATA.TYPE_ID.null.10",
+                "SYS.BINARY_METADATA.IS_ENUM.null.1",
+                "SYS.BINARY_METADATA.FIELDS_COUNT.null.10",
+                "SYS.BINARY_METADATA.TYPE_NAME.null.2147483647"
                 ));
 
             Assert.assertEquals(expectedCols, actualSystemCols);
diff --git a/modules/codegen/src/main/java/org/apache/ignite/codegen/SystemViewRowAttributeWalkerGenerator.java b/modules/codegen/src/main/java/org/apache/ignite/codegen/SystemViewRowAttributeWalkerGenerator.java
index 9f6043b..3752dff 100644
--- a/modules/codegen/src/main/java/org/apache/ignite/codegen/SystemViewRowAttributeWalkerGenerator.java
+++ b/modules/codegen/src/main/java/org/apache/ignite/codegen/SystemViewRowAttributeWalkerGenerator.java
@@ -37,6 +37,7 @@ import org.apache.ignite.internal.managers.systemview.walker.Order;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.spi.systemview.SystemViewLocal;
 import org.apache.ignite.spi.systemview.jmx.SystemViewMBean;
+import org.apache.ignite.spi.systemview.view.BinaryMetadataView;
 import org.apache.ignite.spi.systemview.view.CacheGroupView;
 import org.apache.ignite.spi.systemview.view.CachePagesListView;
 import org.apache.ignite.spi.systemview.view.CacheView;
@@ -106,6 +107,7 @@ public class SystemViewRowAttributeWalkerGenerator {
         gen.generateAndWrite(PagesListView.class, DFLT_SRC_DIR);
         gen.generateAndWrite(CachePagesListView.class, DFLT_SRC_DIR);
         gen.generateAndWrite(PartitionStateView.class, DFLT_SRC_DIR);
+        gen.generateAndWrite(BinaryMetadataView.class, DFLT_SRC_DIR);
 
         gen.generateAndWrite(SqlSchemaView.class, INDEXING_SRC_DIR);
         gen.generateAndWrite(SqlTableView.class, INDEXING_SRC_DIR);
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/systemview/walker/BinaryMetadataViewWalker.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/systemview/walker/BinaryMetadataViewWalker.java
new file mode 100644
index 0000000..b770dd7
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/systemview/walker/BinaryMetadataViewWalker.java
@@ -0,0 +1,56 @@
+/*
+ * 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.managers.systemview.walker;
+
+import org.apache.ignite.spi.systemview.view.BinaryMetadataView;
+import org.apache.ignite.spi.systemview.view.SystemViewRowAttributeWalker;
+
+/**
+ * Generated by {@code org.apache.ignite.codegen.SystemViewRowAttributeWalkerGenerator}.
+ * {@link BinaryMetadataView} attributes walker.
+ * 
+ * @see BinaryMetadataView
+ */
+public class BinaryMetadataViewWalker implements SystemViewRowAttributeWalker<BinaryMetadataView> {
+    /** {@inheritDoc} */
+    @Override public void visitAll(AttributeVisitor v) {
+        v.accept(0, "typeId", int.class);
+        v.accept(1, "typeName", String.class);
+        v.accept(2, "affKeyFieldName", String.class);
+        v.accept(3, "fieldsCount", int.class);
+        v.accept(4, "fields", String.class);
+        v.accept(5, "schemasIds", String.class);
+        v.accept(6, "isEnum", boolean.class);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void visitAll(BinaryMetadataView row, AttributeWithValueVisitor v) {
+        v.acceptInt(0, "typeId", row.typeId());
+        v.accept(1, "typeName", String.class, row.typeName());
+        v.accept(2, "affKeyFieldName", String.class, row.affKeyFieldName());
+        v.acceptInt(3, "fieldsCount", row.fieldsCount());
+        v.accept(4, "fields", String.class, row.fields());
+        v.accept(5, "schemasIds", String.class, row.schemasIds());
+        v.acceptBoolean(6, "isEnum", row.isEnum());
+    }
+
+    /** {@inheritDoc} */
+    @Override public int count() {
+        return 7;
+    }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
index ac12880..9c99053 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
@@ -73,6 +73,7 @@ import org.apache.ignite.internal.binary.GridBinaryMarshaller;
 import org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl;
 import org.apache.ignite.internal.binary.streams.BinaryInputStream;
 import org.apache.ignite.internal.binary.streams.BinaryOffheapInputStream;
+import org.apache.ignite.internal.managers.systemview.walker.BinaryMetadataViewWalker;
 import org.apache.ignite.internal.processors.GridProcessorAdapter;
 import org.apache.ignite.internal.processors.cache.CacheDefaultBinaryAffinityKeyMapper;
 import org.apache.ignite.internal.processors.cache.CacheObject;
@@ -113,6 +114,7 @@ import org.apache.ignite.spi.IgniteNodeValidationResult;
 import org.apache.ignite.spi.discovery.DiscoveryDataBag;
 import org.apache.ignite.spi.discovery.DiscoveryDataBag.GridDiscoveryData;
 import org.apache.ignite.spi.discovery.IgniteDiscoveryThread;
+import org.apache.ignite.spi.systemview.view.BinaryMetadataView;
 import org.apache.ignite.thread.IgniteThread;
 import org.jetbrains.annotations.Nullable;
 
@@ -123,6 +125,7 @@ import static org.apache.ignite.IgniteSystemProperties.IGNITE_WAIT_SCHEMA_UPDATE
 import static org.apache.ignite.IgniteSystemProperties.getBoolean;
 import static org.apache.ignite.internal.GridComponent.DiscoveryDataExchangeType.BINARY_PROC;
 import static org.apache.ignite.internal.binary.BinaryUtils.mergeMetadata;
+import static org.apache.ignite.internal.processors.metric.impl.MetricUtils.metricName;
 
 /**
  * Binary processor implementation.
@@ -131,6 +134,12 @@ public class CacheObjectBinaryProcessorImpl extends GridProcessorAdapter impleme
     /** Immutable classes. */
     private static final Collection<Class<?>> IMMUTABLE_CLS = new HashSet<>();
 
+    /** @see BinaryMetadataView */
+    public static final String BINARY_METADATA_VIEW = metricName("binary", "metadata");
+
+    /** @see BinaryMetadataView */
+    public static final String BINARY_METADATA_DESC = "Binary metadata";
+
     /** */
     private volatile boolean discoveryStarted;
 
@@ -202,6 +211,9 @@ public class CacheObjectBinaryProcessorImpl extends GridProcessorAdapter impleme
         super(ctx);
 
         marsh = ctx.grid().configuration().getMarshaller();
+
+        ctx.systemView().registerView(BINARY_METADATA_VIEW, BINARY_METADATA_DESC, new BinaryMetadataViewWalker(),
+            metadataLocCache.values(), val -> new BinaryMetadataView(val.metadata()));
     }
 
     /**
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/systemview/view/BinaryMetadataView.java b/modules/core/src/main/java/org/apache/ignite/spi/systemview/view/BinaryMetadataView.java
new file mode 100644
index 0000000..681accd
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/spi/systemview/view/BinaryMetadataView.java
@@ -0,0 +1,85 @@
+/*
+ * 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.spi.systemview.view;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.ignite.internal.binary.BinaryMetadata;
+import org.apache.ignite.internal.binary.BinarySchema;
+import org.apache.ignite.internal.managers.systemview.walker.Order;
+import org.apache.ignite.internal.util.typedef.internal.U;
+
+/**
+ * {@link BinaryMetadata} representation for the {@link SystemView}.
+ */
+public class BinaryMetadataView {
+    /** Meta. */
+    private final BinaryMetadata meta;
+
+    /** @param meta Meta. */
+    public BinaryMetadataView(BinaryMetadata meta) {
+        this.meta = meta;
+    }
+
+    /** @return Type id. */
+    @Order
+    public int typeId() {
+        return meta.typeId();
+    }
+
+    /** @return Type name. */
+    @Order(1)
+    public String typeName() {
+        return meta.typeName();
+    }
+
+    /** @return Affinity key field name. */
+    @Order(2)
+    public String affKeyFieldName() {
+        return meta.affinityKeyFieldName();
+    }
+
+    /** @return Fields count. */
+    @Order(3)
+    public int fieldsCount() {
+        return meta.fields().size();
+    }
+
+    /** @return Fields. */
+    @Order(4)
+    public String fields() {
+        return U.toStringSafe(meta.fields());
+    }
+
+    /** @return Schema IDs registered for this type. */
+    @Order(5)
+    public String schemasIds() {
+        List<Integer> ids = new ArrayList<>(meta.schemas().size());
+
+        for (BinarySchema schema : meta.schemas())
+            ids.add(schema.schemaId());
+
+        return U.toStringSafe(ids);
+    }
+
+    /** @return {@code True} if this is enum type. */
+    @Order(6)
+    public boolean isEnum() {
+        return meta.isEnum();
+    }
+}
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/JmxExporterSpiTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/JmxExporterSpiTest.java
index 337092d..b393338 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/metric/JmxExporterSpiTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/JmxExporterSpiTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.metric;
 
+import java.lang.reflect.Field;
 import java.sql.Connection;
 import java.text.DateFormat;
 import java.time.LocalTime;
@@ -60,6 +61,8 @@ import org.apache.ignite.configuration.DataRegionConfiguration;
 import org.apache.ignite.configuration.DataStorageConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.binary.mutabletest.GridBinaryTestClasses.TestObjectAllTypes;
+import org.apache.ignite.internal.binary.mutabletest.GridBinaryTestClasses.TestObjectEnum;
 import org.apache.ignite.internal.client.thin.ProtocolVersion;
 import org.apache.ignite.internal.managers.systemview.walker.CachePagesListViewWalker;
 import org.apache.ignite.internal.metric.SystemViewSelfTest.TestPredicate;
@@ -92,6 +95,7 @@ import static org.apache.ignite.internal.processors.cache.ClusterCachesInfo.CACH
 import static org.apache.ignite.internal.processors.cache.GridCacheProcessor.CACHE_GRP_PAGE_LIST_VIEW;
 import static org.apache.ignite.internal.processors.cache.GridCacheUtils.cacheGroupId;
 import static org.apache.ignite.internal.processors.cache.GridCacheUtils.cacheId;
+import static org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl.BINARY_METADATA_VIEW;
 import static org.apache.ignite.internal.processors.cache.transactions.IgniteTxManager.TXS_MON_LIST;
 import static org.apache.ignite.internal.processors.continuous.GridContinuousProcessor.CQ_SYS_VIEW;
 import static org.apache.ignite.internal.processors.metric.GridMetricManager.CPU_LOAD;
@@ -1025,6 +1029,41 @@ public class JmxExporterSpiTest extends AbstractExporterSpiTest {
     }
 
     /** */
+    @Test
+    public void testBinaryMeta() {
+        IgniteCache<Integer, TestObjectAllTypes> c1 = ignite.createCache("test-all-types-cache");
+        IgniteCache<Integer, TestObjectEnum> c2 = ignite.createCache("test-enum-cache");
+
+        c1.put(1, new TestObjectAllTypes());
+        c2.put(1, TestObjectEnum.A);
+
+        TabularDataSupport view = systemView(BINARY_METADATA_VIEW);
+
+        assertNotNull(view);
+        assertEquals(2, view.size());
+
+        for (int i = 0; i < 2; i++) {
+            CompositeData meta = view.get(new Object[] {i});
+
+            if (Objects.equals(TestObjectEnum.class.getName(), meta.get("typeName"))) {
+                assertTrue((Boolean)meta.get("isEnum"));
+
+                assertEquals(0, meta.get("fieldsCount"));
+            }
+            else {
+                assertFalse((Boolean)meta.get("isEnum"));
+
+                Field[] fields = TestObjectAllTypes.class.getDeclaredFields();
+
+                assertEquals(fields.length, meta.get("fieldsCount"));
+
+                for (Field field : fields)
+                    assertTrue(meta.get("fields").toString().contains(field.getName()));
+            }
+        }
+    }
+
+    /** */
     private void createTestHistogram(MetricRegistry mreg) {
         long[] bounds = new long[] {50, 500};
 
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 d785256..5e904c6 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
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.metric;
 
+import java.lang.reflect.Field;
 import java.sql.Connection;
 import java.util.Arrays;
 import java.util.Collections;
@@ -56,6 +57,8 @@ import org.apache.ignite.configuration.ClientConfiguration;
 import org.apache.ignite.configuration.DataRegionConfiguration;
 import org.apache.ignite.configuration.DataStorageConfiguration;
 import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.binary.mutabletest.GridBinaryTestClasses.TestObjectAllTypes;
+import org.apache.ignite.internal.binary.mutabletest.GridBinaryTestClasses.TestObjectEnum;
 import org.apache.ignite.internal.client.thin.ProtocolVersion;
 import org.apache.ignite.internal.managers.systemview.walker.CachePagesListViewWalker;
 import org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager;
@@ -70,6 +73,7 @@ import org.apache.ignite.lang.IgniteClosure;
 import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.lang.IgniteRunnable;
 import org.apache.ignite.services.ServiceConfiguration;
+import org.apache.ignite.spi.systemview.view.BinaryMetadataView;
 import org.apache.ignite.spi.systemview.view.CacheGroupView;
 import org.apache.ignite.spi.systemview.view.CachePagesListView;
 import org.apache.ignite.spi.systemview.view.CacheView;
@@ -100,6 +104,7 @@ import static org.apache.ignite.internal.processors.cache.ClusterCachesInfo.CACH
 import static org.apache.ignite.internal.processors.cache.GridCacheProcessor.CACHE_GRP_PAGE_LIST_VIEW;
 import static org.apache.ignite.internal.processors.cache.GridCacheUtils.cacheGroupId;
 import static org.apache.ignite.internal.processors.cache.GridCacheUtils.cacheId;
+import static org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl.BINARY_METADATA_VIEW;
 import static org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager.DATA_REGION_PAGE_LIST_VIEW;
 import static org.apache.ignite.internal.processors.cache.transactions.IgniteTxManager.TXS_MON_LIST;
 import static org.apache.ignite.internal.processors.continuous.GridContinuousProcessor.CQ_SYS_VIEW;
@@ -1073,6 +1078,41 @@ public class SystemViewSelfTest extends GridCommonAbstractTest {
         }
     }
 
+    /** */
+    @Test
+    public void testBinaryMeta() throws Exception {
+        try (IgniteEx g = startGrid(0)) {
+            IgniteCache<Integer, TestObjectAllTypes> c1 = g.createCache("test-cache");
+            IgniteCache<Integer, TestObjectEnum> c2 = g.createCache("test-enum-cache");
+
+            c1.put(1, new TestObjectAllTypes());
+            c2.put(1, TestObjectEnum.A);
+
+            SystemView<BinaryMetadataView> view = g.context().systemView().view(BINARY_METADATA_VIEW);
+
+            assertNotNull(view);
+            assertEquals(2, view.size());
+
+            for (BinaryMetadataView meta : view) {
+                if (Objects.equals(TestObjectEnum.class.getName(), meta.typeName())) {
+                    assertTrue(meta.isEnum());
+
+                    assertEquals(0, meta.fieldsCount());
+                }
+                else {
+                    assertFalse(meta.isEnum());
+
+                    Field[] fields = TestObjectAllTypes.class.getDeclaredFields();
+
+                    assertEquals(fields.length, meta.fieldsCount());
+
+                    for (Field field : fields)
+                        assertTrue(meta.fields().contains(field.getName()));
+                }
+            }
+        }
+    }
+
     /** Test node filter. */
     public static class TestNodeFilter implements IgnitePredicate<ClusterNode> {
         /** {@inheritDoc} */
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/metric/SqlViewExporterSpiTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/metric/SqlViewExporterSpiTest.java
index 686b168..6104e6b 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/metric/SqlViewExporterSpiTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/metric/SqlViewExporterSpiTest.java
@@ -17,12 +17,14 @@
 
 package org.apache.ignite.internal.processors.cache.metric;
 
+import java.lang.reflect.Field;
 import java.sql.Connection;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Objects;
 import java.util.Properties;
 import java.util.Set;
 import java.util.UUID;
@@ -55,6 +57,8 @@ import org.apache.ignite.configuration.DataStorageConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.configuration.SqlConfiguration;
 import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.binary.mutabletest.GridBinaryTestClasses.TestObjectAllTypes;
+import org.apache.ignite.internal.binary.mutabletest.GridBinaryTestClasses.TestObjectEnum;
 import org.apache.ignite.internal.metric.AbstractExporterSpiTest;
 import org.apache.ignite.internal.metric.SystemViewSelfTest.TestPredicate;
 import org.apache.ignite.internal.metric.SystemViewSelfTest.TestRunnable;
@@ -451,7 +455,8 @@ public class SqlViewExporterSpiTest extends AbstractExporterSpiTest {
             "DATASTREAM_THREADPOOL_QUEUE",
             "DATA_REGION_PAGE_LISTS",
             "CACHE_GROUP_PAGE_LISTS",
-            "PARTITION_STATES"
+            "PARTITION_STATES",
+            "BINARY_METADATA"
         ));
 
         Set<String> actViews = new HashSet<>();
@@ -1071,6 +1076,51 @@ public class SqlViewExporterSpiTest extends AbstractExporterSpiTest {
         }
     }
 
+    /** */
+    @Test
+    public void testBinaryMeta() {
+        IgniteCache<Integer, TestObjectAllTypes> c1 = ignite0.createCache("test-cache");
+        IgniteCache<Integer, TestObjectEnum> c2 = ignite0.createCache("test-enum-cache");
+
+        execute(ignite0, "CREATE TABLE T1(ID LONG PRIMARY KEY, NAME VARCHAR(40), ACCOUNT BIGINT)");
+        execute(ignite0, "INSERT INTO T1(ID, NAME, ACCOUNT) VALUES(1, 'test', 1)");
+
+        c1.put(1, new TestObjectAllTypes());
+        c2.put(1, TestObjectEnum.A);
+
+        List<List<?>> view =
+            execute(ignite0, "SELECT TYPE_NAME, FIELDS_COUNT, FIELDS, IS_ENUM FROM SYS.BINARY_METADATA");
+
+        assertNotNull(view);
+        assertEquals(3, view.size());
+
+        for (List<?> meta : view) {
+            if (Objects.equals(TestObjectEnum.class.getName(), meta.get(0))) {
+                assertTrue((Boolean)meta.get(3));
+
+                assertEquals(0, meta.get(1));
+            }
+            else if (Objects.equals(TestObjectAllTypes.class.getName(), meta.get(0))) {
+                assertFalse((Boolean)meta.get(3));
+
+                Field[] fields = TestObjectAllTypes.class.getDeclaredFields();
+
+                assertEquals(fields.length, meta.get(1));
+
+                for (Field field : fields)
+                    assertTrue(meta.get(2).toString().contains(field.getName()));
+            }
+            else {
+                assertFalse((Boolean)meta.get(3));
+
+                assertEquals(2, meta.get(1));
+
+                assertTrue(meta.get(2).toString().contains("NAME"));
+                assertTrue(meta.get(2).toString().contains("ACCOUNT"));
+            }
+        }
+    }
+
     /**
      * Execute query on given node.
      *