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 bbbb0ab88a6 IGNITE-18700 Configuration system view (#10512)
bbbb0ab88a6 is described below

commit bbbb0ab88a683d2ce69bfa51307cdb869808680e
Author: Nikolay <[email protected]>
AuthorDate: Fri Feb 3 18:52:51 2023 +0300

    IGNITE-18700 Configuration system view (#10512)
---
 docs/_docs/monitoring-metrics/system-views.adoc    |  14 ++
 .../internal/jdbc2/JdbcMetadataSelfTest.java       |   1 +
 .../ignite/jdbc/thin/JdbcThinMetadataSelfTest.java |   3 +
 .../SystemViewRowAttributeWalkerGenerator.java     |   2 +
 .../apache/ignite/util/SystemViewCommandTest.java  |   1 +
 .../org/apache/ignite/IgniteSystemProperties.java  |  10 +
 .../org/apache/ignite/internal/IgniteKernal.java   |  23 +++
 .../systemview/IgniteConfigurationIterable.java    | 223 +++++++++++++++++++++
 .../systemview/walker/ConfigurationViewWalker.java |  46 +++++
 .../handlers/top/GridTopologyCommandHandler.java   |   3 +-
 .../apache/ignite/internal/util/IgniteUtils.java   |   5 +-
 .../spi/systemview/view/ConfigurationView.java     |  51 +++++
 .../ignite/internal/metric/SystemViewSelfTest.java |  54 +++++
 .../cache/metric/SqlViewExporterSpiTest.java       |  13 +-
 .../processors/query/SqlSystemViewsSelfTest.java   |  46 +++++
 15 files changed, 487 insertions(+), 8 deletions(-)

diff --git a/docs/_docs/monitoring-metrics/system-views.adoc 
b/docs/_docs/monitoring-metrics/system-views.adoc
index d4bd9658c38..55f4dea139e 100644
--- a/docs/_docs/monitoring-metrics/system-views.adoc
+++ b/docs/_docs/monitoring-metrics/system-views.adoc
@@ -331,6 +331,20 @@ The NODE_ATTRIBUTES view contains the attributes of all 
nodes.
 
 |===
 
+== CONFIGURATION
+
+
+The CONFIGURATION view contains the configuration properties of node.
+
+[{table_opts}]
+|===
+| Column |Data Type |Description
+
+|NAME |VARCHAR |Configuration property name.
+|VALUE |VARCHAR |Configuration property value.
+
+|===
+
 == BASELINE_NODES
 
 
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 c476bf51534..5de43a1b124 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
@@ -334,6 +334,7 @@ public class JdbcMetadataSelfTest extends 
GridCommonAbstractTest {
             "SCAN_QUERIES",
             "NODES",
             "NODE_ATTRIBUTES",
+            "CONFIGURATION",
             "NODE_METRICS",
             "SCHEMAS",
             "TABLES",
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 dc2e608af60..9d5e4e08d96 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
@@ -425,6 +425,7 @@ public class JdbcThinMetadataSelfTest extends 
JdbcThinAbstractSelfTest {
                 "SYS.JOBS",
                 "SYS.SQL_QUERIES_HISTORY",
                 "SYS.NODES",
+                "SYS.CONFIGURATION",
                 "SYS.SCHEMAS",
                 "SYS.NODE_METRICS",
                 "SYS.BASELINE_NODES",
@@ -808,6 +809,8 @@ public class JdbcThinMetadataSelfTest extends 
JdbcThinAbstractSelfTest {
                 "SYS.NODE_ATTRIBUTES.NODE_ID.null",
                 "SYS.NODE_ATTRIBUTES.NAME.null",
                 "SYS.NODE_ATTRIBUTES.VALUE.null",
+                "SYS.CONFIGURATION.NAME.null",
+                "SYS.CONFIGURATION.VALUE.null",
                 "SYS.NODE_METRICS.NODE_ID.null",
                 "SYS.NODE_METRICS.LAST_UPDATE_TIME.null",
                 "SYS.NODE_METRICS.MAX_ACTIVE_JOBS.null",
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 c04e97773fe..d57cd1e20cd 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
@@ -51,6 +51,7 @@ import 
org.apache.ignite.spi.systemview.view.ClientConnectionView;
 import org.apache.ignite.spi.systemview.view.ClusterNodeView;
 import org.apache.ignite.spi.systemview.view.ComputeJobView;
 import org.apache.ignite.spi.systemview.view.ComputeTaskView;
+import org.apache.ignite.spi.systemview.view.ConfigurationView;
 import org.apache.ignite.spi.systemview.view.ContinuousQueryView;
 import org.apache.ignite.spi.systemview.view.MetastorageView;
 import org.apache.ignite.spi.systemview.view.MetricsView;
@@ -146,6 +147,7 @@ public class SystemViewRowAttributeWalkerGenerator {
         gen.generateAndWrite(SnapshotView.class, DFLT_SRC_DIR);
         gen.generateAndWrite(MetricsView.class, DFLT_SRC_DIR);
         gen.generateAndWrite(PagesTimestampHistogramView.class, DFLT_SRC_DIR);
+        gen.generateAndWrite(ConfigurationView.class, DFLT_SRC_DIR);
 
         gen.generateAndWrite(SqlSchemaView.class, DFLT_SRC_DIR);
         gen.generateAndWrite(SqlTableView.class, DFLT_SRC_DIR);
diff --git 
a/modules/control-utility/src/test/java/org/apache/ignite/util/SystemViewCommandTest.java
 
b/modules/control-utility/src/test/java/org/apache/ignite/util/SystemViewCommandTest.java
index bf788fc6b27..0e29abe8c72 100644
--- 
a/modules/control-utility/src/test/java/org/apache/ignite/util/SystemViewCommandTest.java
+++ 
b/modules/control-utility/src/test/java/org/apache/ignite/util/SystemViewCommandTest.java
@@ -453,6 +453,7 @@ public class SystemViewCommandTest extends 
GridCommandHandlerClusterByClassAbstr
             "NODES",
             "SCHEMAS",
             "NODE_METRICS",
+            "CONFIGURATION",
             "BASELINE_NODES",
             "BASELINE_NODE_ATTRIBUTES",
             "INDEXES",
diff --git 
a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java 
b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
index 5ec174b6f59..56078265690 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
@@ -2099,6 +2099,16 @@ public final class IgniteSystemProperties {
     @IgniteExperimental
     public static final String IGNITE_SNAPSHOT_SEQUENTIAL_WRITE = 
"IGNITE_SNAPSHOT_SEQUENTIAL_WRITE";
 
+    /**
+     * Comma separated packages list to expose in configuration view.
+     * The default value is null.
+     * @see 
org.apache.ignite.internal.managers.systemview.GridSystemViewManager#CFG_VIEW
+     * @see org.apache.ignite.spi.systemview.view.ConfigurationView
+     */
+    @SystemProperty(value = "Packages list to expose in configuration view")
+    @IgniteExperimental
+    public static final String IGNITE_CONFIGURATION_VIEW_PACKAGES = 
"IGNITE_CONFIGURATION_VIEW_PACKAGES";
+
     /**
      * Enforces singleton.
      */
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java 
b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
index 0da2c0d14e7..f9015c79c58 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
@@ -108,6 +108,8 @@ import 
org.apache.ignite.internal.managers.failover.GridFailoverManager;
 import org.apache.ignite.internal.managers.indexing.GridIndexingManager;
 import 
org.apache.ignite.internal.managers.loadbalancer.GridLoadBalancerManager;
 import org.apache.ignite.internal.managers.systemview.GridSystemViewManager;
+import 
org.apache.ignite.internal.managers.systemview.IgniteConfigurationIterable;
+import 
org.apache.ignite.internal.managers.systemview.walker.ConfigurationViewWalker;
 import org.apache.ignite.internal.managers.tracing.GridTracingManager;
 import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
 import org.apache.ignite.internal.plugin.IgniteLogInfoProvider;
@@ -213,6 +215,7 @@ import 
org.apache.ignite.spi.tracing.TracingConfigurationManager;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import static java.util.Collections.singleton;
 import static java.util.Optional.ofNullable;
 import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_BINARY_MARSHALLER_USE_STRING_SERIALIZATION_VER_2;
 import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID;
@@ -350,6 +353,12 @@ public class IgniteKernal implements IgniteEx, 
Externalizable {
     /** System line separator. */
     public static final String NL = U.nl();
 
+    /** Name of the configuration system view. */
+    public static final String CFG_VIEW = "configuration";
+
+    /** Description of the configuration system view. */
+    public static final String CFG_VIEW_DESC = "Node configuration";
+
     /**
      * Default interval of checking thread pool state for the starvation. Will 
be used only if the
      * {@link IgniteSystemProperties#IGNITE_STARVATION_CHECK_INTERVAL} system 
property is not set.
@@ -1193,6 +1202,8 @@ public class IgniteKernal implements IgniteEx, 
Externalizable {
 
             registerMetrics();
 
+            registerConfigurationSystemView();
+
             ctx.cluster().registerMetrics();
 
             // Register MBeans.
@@ -3440,6 +3451,18 @@ public class IgniteKernal implements IgniteEx, 
Externalizable {
         return ctx.io().sendIoTest(nodes, payload, procFromNioThread);
     }
 
+    /** Registers configuration system view. */
+    private void registerConfigurationSystemView() {
+        ctx.systemView().registerInnerCollectionView(
+            CFG_VIEW,
+            CFG_VIEW_DESC,
+            new ConfigurationViewWalker(),
+            singleton(ctx.config()),
+            IgniteConfigurationIterable::new,
+            (cfg, view) -> view
+        );
+    }
+
     /**
      * Registers metrics.
      */
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/managers/systemview/IgniteConfigurationIterable.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/managers/systemview/IgniteConfigurationIterable.java
new file mode 100644
index 00000000000..ad900ff2039
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/managers/systemview/IgniteConfigurationIterable.java
@@ -0,0 +1,223 @@
+/*
+ * 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;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.TreeMap;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteSystemProperties;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.util.lang.GridTuple3;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.spi.systemview.view.ConfigurationView;
+import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_CONFIGURATION_VIEW_PACKAGES;
+import static 
org.apache.ignite.internal.processors.metric.impl.MetricUtils.metricName;
+import static org.apache.ignite.internal.util.IgniteUtils.IGNITE_PKG;
+
+/**
+ * Responsibility of this class it to recursively iterate {@link 
IgniteConfiguration} object
+ * and expose all properties in form of String pairs.
+ */
+public class IgniteConfigurationIterable implements 
Iterable<ConfigurationView> {
+    /** Packages to expose objects from. */
+    private final List<String> pkgs;
+
+    /** Iterators queue. */
+    private final Queue<GridTuple3<Object, Iterator<Map.Entry<String, 
Method>>, String>> iters = new LinkedList<>();
+
+    /**
+     * @param cfg Configuration to iterate.
+     */
+    public IgniteConfigurationIterable(IgniteConfiguration cfg) {
+        String pkgsProp = 
IgniteSystemProperties.getString(IGNITE_CONFIGURATION_VIEW_PACKAGES);
+
+        pkgs = new ArrayList<>(F.isEmpty(pkgsProp)
+            ? Collections.emptyList()
+            : Arrays.asList(pkgsProp.split(","))
+        );
+
+        pkgs.add(IGNITE_PKG);
+
+        addToQueue(cfg, "");
+    }
+
+    /** {@inheritDoc} */
+    @Override public Iterator<ConfigurationView> iterator() {
+        return new Iterator<ConfigurationView>() {
+            private ConfigurationView next;
+
+            /** {@inheritDoc} */
+            @Override public boolean hasNext() {
+                advance();
+
+                return next != null;
+            }
+
+            private void advance() {
+                if (next != null)
+                    return;
+
+                while (!iters.isEmpty() && !iters.peek().get2().hasNext())
+                    iters.remove();
+
+                if (!iters.isEmpty()) {
+                    GridTuple3<Object, Iterator<Map.Entry<String, Method>>, 
String> curr = iters.peek();
+
+                    try {
+                        Map.Entry<String, Method> prop = curr.get2().next();
+
+                        String name = curr.get3().isEmpty() ? prop.getKey() : 
metricName(curr.get3(), prop.getKey());
+
+                        Object val = prop.getValue().invoke(curr.get1());
+
+                        if (addToQueue(val, name)) {
+                            advance();
+
+                            return;
+                        }
+
+                        next = new ConfigurationView(
+                            name,
+                            val != null && val.getClass().isArray()
+                                ? S.arrayToString(val)
+                                : U.toStringSafe(val)
+                        );
+                    }
+                    catch (IllegalAccessException | InvocationTargetException 
e) {
+                        throw new IgniteException(e);
+                    }
+                }
+            }
+
+            /** {@inheritDoc} */
+            @Override public ConfigurationView next() {
+                if (next == null)
+                    advance();
+
+                ConfigurationView next0 = next;
+
+                if (next0 == null)
+                    throw new NoSuchElementException();
+
+                next = null;
+
+                return next0;
+            }
+        };
+    }
+
+    /**
+     * If {@code val} is configuration bean that must be recursively exposed 
by the view then
+     * it will be added to the {@link #iters} queue.
+     *
+     * @return {@code True} if {@code val} was added to {@link #iters} queue, 
{@code false} otherwise.
+     */
+    private boolean addToQueue(Object val, String prefix) {
+        if (val == null || val.getClass().isEnum())
+            return false;
+
+        Class<?> cls = val.getClass();
+
+        boolean isArray = cls.isArray();
+
+        if (isArray)
+            cls = cls.getComponentType();
+
+        if (!checkPkg(cls.getName()))
+            return false;
+
+        if (isArray) {
+            int length = Array.getLength(val);
+
+            if (length == 0)
+                return false;
+
+            for (int i = 0; i < length; i++) {
+                Object el = Array.get(val, i);
+                iters.add(F.t(el, props(el.getClass()), prefix + '[' + i + 
']'));
+            }
+        }
+
+        iters.add(F.t(val, props(val.getClass()), prefix));
+
+        return true;
+    }
+
+    /**
+     * @param cls Class to find properties.
+     * @return Iterator of object properties.
+     */
+    private Iterator<Map.Entry<String, Method>> props(Class<?> cls) {
+        Map<String, Method> props = new TreeMap<>(); // TreeMap to keep 
properties sorted.
+
+        for (; cls != Object.class; cls = cls.getSuperclass()) {
+            for (Method mtd : cls.getMethods()) {
+                if (mtd.getName().startsWith("set")) {
+                    String propName = mtd.getName().substring(3);
+
+                    Method getter = methodOrNull(cls, "get" + propName);
+
+                    if (getter == null)
+                        getter = methodOrNull(cls, "is" + propName);
+
+                    if (getter != null && !props.containsKey(propName))
+                        props.put(propName, getter);
+                }
+            }
+        }
+
+        return props.entrySet().iterator();
+    }
+
+    /**
+     * @param cls Class to get method from.
+     * @param name Name of the method.
+     * @return Method if exists, {@code null} otherwise.
+     */
+    private static Method methodOrNull(Class<?> cls, String name) {
+        try {
+            return cls.getMethod(name);
+        }
+        catch (NoSuchMethodException ignore) {
+            return null;
+        }
+    }
+
+    /** */
+    private boolean checkPkg(String name) {
+        for (String pkg : pkgs) {
+            if (name.startsWith(pkg))
+                return true;
+        }
+
+        return false;
+    }
+}
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/managers/systemview/walker/ConfigurationViewWalker.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/managers/systemview/walker/ConfigurationViewWalker.java
new file mode 100644
index 00000000000..2e98fc95f19
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/managers/systemview/walker/ConfigurationViewWalker.java
@@ -0,0 +1,46 @@
+/*
+ * 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.ConfigurationView;
+import org.apache.ignite.spi.systemview.view.SystemViewRowAttributeWalker;
+
+/**
+ * Generated by {@code 
org.apache.ignite.codegen.SystemViewRowAttributeWalkerGenerator}.
+ * {@link ConfigurationView} attributes walker.
+ * 
+ * @see ConfigurationView
+ */
+public class ConfigurationViewWalker implements 
SystemViewRowAttributeWalker<ConfigurationView> {
+    /** {@inheritDoc} */
+    @Override public void visitAll(AttributeVisitor v) {
+        v.accept(0, "name", String.class);
+        v.accept(1, "value", String.class);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void visitAll(ConfigurationView row, 
AttributeWithValueVisitor v) {
+        v.accept(0, "name", String.class, row.name());
+        v.accept(1, "value", String.class, row.value());
+    }
+
+    /** {@inheritDoc} */
+    @Override public int count() {
+        return 2;
+    }
+}
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/top/GridTopologyCommandHandler.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/top/GridTopologyCommandHandler.java
index 99529455375..7b0d046115b 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/top/GridTopologyCommandHandler.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/top/GridTopologyCommandHandler.java
@@ -62,6 +62,7 @@ import static 
org.apache.ignite.internal.IgniteNodeAttributes.ATTR_SECURITY_SUBJ
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_TX_CONFIG;
 import static org.apache.ignite.internal.processors.rest.GridRestCommand.NODE;
 import static 
org.apache.ignite.internal.processors.rest.GridRestCommand.TOPOLOGY;
+import static org.apache.ignite.internal.util.IgniteUtils.IGNITE_PKG;
 
 /**
  * Command handler for API requests.
@@ -299,7 +300,7 @@ public class GridTopologyCommandHandler extends 
GridRestCommandHandlerAdapter {
             for (Iterator<Map.Entry<String, Object>> i = 
attrs.entrySet().iterator(); i.hasNext();) {
                 Map.Entry<String, Object> e = i.next();
 
-                if (!e.getKey().startsWith("org.apache.ignite.") && 
!e.getKey().startsWith("plugins.") &&
+                if (!e.getKey().startsWith(IGNITE_PKG) && 
!e.getKey().startsWith("plugins.") &&
                     System.getProperty(e.getKey()) == null) {
                     i.remove();
 
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java 
b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
index 4e6754e2a4c..135e1119401 100755
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
@@ -400,6 +400,9 @@ public abstract class IgniteUtils {
     /** Alphanumeric with underscore regexp pattern. */
     private static final Pattern ALPHANUMERIC_UNDERSCORE_PATTERN = 
Pattern.compile("^[a-zA-Z_0-9]+$");
 
+    /** Ignite package. */
+    public static final String IGNITE_PKG = "org.apache.ignite.";
+
     /** Project home directory. */
     private static volatile GridTuple<String> ggHome;
 
@@ -6827,7 +6830,7 @@ public abstract class IgniteUtils {
     public static String compact(String s) {
         return s.replace("org.apache.ignite.internal.visor.", "o.a.i.i.v.").
             replace("org.apache.ignite.internal.", "o.a.i.i.").
-            replace("org.apache.ignite.", "o.a.i.");
+            replace(IGNITE_PKG, "o.a.i.");
     }
 
     /**
diff --git 
a/modules/core/src/main/java/org/apache/ignite/spi/systemview/view/ConfigurationView.java
 
b/modules/core/src/main/java/org/apache/ignite/spi/systemview/view/ConfigurationView.java
new file mode 100644
index 00000000000..b78bd529085
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/spi/systemview/view/ConfigurationView.java
@@ -0,0 +1,51 @@
+/*
+ * 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 org.apache.ignite.internal.managers.systemview.walker.Order;
+
+/**
+ * Configuration value representation for a {@link SystemView}.
+ */
+public class ConfigurationView {
+    /** Name of the configuration property. */
+    private final String name;
+
+    /** Value of the configuration property. */
+    private final String val;
+
+    /**
+     * @param name Name of the configuration property.
+     * @param val Value of the configuration property.
+     */
+    public ConfigurationView(String name, String val) {
+        this.name = name;
+        this.val = val;
+    }
+
+    /** @return Name of the configuration property. */
+    @Order
+    public String name() {
+        return name;
+    }
+
+    /** @return Value of the configuration property. */
+    public String value() {
+        return val;
+    }
+}
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 8ba9ea29283..243d95e6861 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
@@ -22,6 +22,7 @@ import java.sql.Connection;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -72,6 +73,7 @@ import org.apache.ignite.configuration.ClientConfiguration;
 import org.apache.ignite.configuration.CollectionConfiguration;
 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.IgniteInternalFuture;
 import 
org.apache.ignite.internal.binary.mutabletest.GridBinaryTestClasses.TestObjectAllTypes;
@@ -107,6 +109,7 @@ import org.apache.ignite.spi.systemview.view.CacheView;
 import org.apache.ignite.spi.systemview.view.ClientConnectionView;
 import org.apache.ignite.spi.systemview.view.ClusterNodeView;
 import org.apache.ignite.spi.systemview.view.ComputeTaskView;
+import org.apache.ignite.spi.systemview.view.ConfigurationView;
 import org.apache.ignite.spi.systemview.view.ContinuousQueryView;
 import org.apache.ignite.spi.systemview.view.FiltrableSystemView;
 import org.apache.ignite.spi.systemview.view.MetastorageView;
@@ -137,6 +140,8 @@ import org.jetbrains.annotations.Nullable;
 import org.junit.Test;
 
 import static 
org.apache.ignite.configuration.AtomicConfiguration.DFLT_ATOMIC_SEQUENCE_RESERVE_SIZE;
+import static org.apache.ignite.events.EventType.EVT_CONSISTENCY_VIOLATION;
+import static org.apache.ignite.internal.IgniteKernal.CFG_VIEW;
 import static 
org.apache.ignite.internal.managers.discovery.GridDiscoveryManager.NODES_SYS_VIEW;
 import static 
org.apache.ignite.internal.managers.discovery.GridDiscoveryManager.NODE_ATTRIBUTES_SYS_VIEW;
 import static 
org.apache.ignite.internal.managers.discovery.GridDiscoveryManager.NODE_METRICS_SYS_VIEW;
@@ -174,6 +179,7 @@ import static 
org.apache.ignite.internal.processors.pool.PoolProcessor.STREAM_PO
 import static 
org.apache.ignite.internal.processors.pool.PoolProcessor.SYS_POOL_QUEUE_VIEW;
 import static 
org.apache.ignite.internal.processors.service.IgniteServiceProcessor.SVCS_VIEW;
 import static 
org.apache.ignite.internal.processors.task.GridTaskProcessor.TASKS_VIEW;
+import static org.apache.ignite.internal.util.IgniteUtils.MB;
 import static org.apache.ignite.internal.util.IgniteUtils.toStringSafe;
 import static org.apache.ignite.internal.util.lang.GridFunc.alwaysTrue;
 import static org.apache.ignite.internal.util.lang.GridFunc.identity;
@@ -2318,6 +2324,54 @@ public class SystemViewSelfTest extends 
GridCommonAbstractTest {
         }
     }
 
+    /** */
+    @Test
+    public void testConfigurationView() throws Exception {
+        IgniteConfiguration icfg = new IgniteConfiguration();
+
+        long expMaxSize = 10 * MB;
+
+        String expName = "my-instance";
+
+        String expDrName = "my-dr";
+
+        icfg.setIgniteInstanceName(expName)
+            .setIncludeEventTypes(EVT_CONSISTENCY_VIOLATION);
+        icfg.setDataStorageConfiguration(new DataStorageConfiguration()
+            .setDefaultDataRegionConfiguration(
+                new DataRegionConfiguration()
+                    .setLazyMemoryAllocation(false))
+            .setDataRegionConfigurations(
+                new DataRegionConfiguration()
+                    .setName(expDrName)
+                    .setMaxSize(expMaxSize)));
+
+        try (IgniteEx ignite = startGrid(icfg)) {
+            Map<String, String> viewContent = new HashMap<>();
+
+            ignite.context().systemView().<ConfigurationView>view(CFG_VIEW)
+                .forEach(view -> viewContent.put(view.name(), view.value()));
+
+            assertEquals(expName, viewContent.get("IgniteInstanceName"));
+            assertEquals(
+                "false",
+                
viewContent.get("DataStorageConfiguration.DefaultDataRegionConfiguration.LazyMemoryAllocation")
+            );
+            assertEquals(expDrName, 
viewContent.get("DataStorageConfiguration.DataRegionConfigurations[0].Name"));
+            assertEquals(
+                Long.toString(expMaxSize),
+                
viewContent.get("DataStorageConfiguration.DataRegionConfigurations[0].MaxSize")
+            );
+            assertEquals(
+                CacheAtomicityMode.TRANSACTIONAL.name(),
+                viewContent.get("CacheConfiguration[0].AtomicityMode")
+            );
+            assertTrue(viewContent.containsKey("AddressResolver"));
+            assertNull(viewContent.get("AddressResolver"));
+            assertEquals("[" + EVT_CONSISTENCY_VIOLATION + ']', 
viewContent.get("IncludeEventTypes"));
+        }
+    }
+
     /** 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 8402b36cd1e..d8cd04f86dd 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
@@ -160,7 +160,7 @@ public class SqlViewExporterSpiTest extends 
AbstractExporterSpiTest {
 
     /** */
     @Test
-    public void testEmptyFilter() throws Exception {
+    public void testEmptyFilter() {
         List<List<?>> res = execute(ignite0, "SELECT * FROM SYS.METRICS");
 
         assertNotNull(res);
@@ -169,7 +169,7 @@ public class SqlViewExporterSpiTest extends 
AbstractExporterSpiTest {
 
     /** */
     @Test
-    public void testDataRegionMetrics() throws Exception {
+    public void testDataRegionMetrics() {
         List<List<?>> res = execute(ignite0,
             "SELECT REPLACE(name, 'io.dataregion.persistent.'), value, 
description FROM SYS.METRICS");
 
@@ -198,7 +198,7 @@ public class SqlViewExporterSpiTest extends 
AbstractExporterSpiTest {
 
     /** */
     @Test
-    public void testCachesView() throws Exception {
+    public void testCachesView() {
         Set<String> cacheNames = new HashSet<>(asList("cache-1", "cache-2"));
 
         for (String name : cacheNames)
@@ -216,7 +216,7 @@ public class SqlViewExporterSpiTest extends 
AbstractExporterSpiTest {
 
     /** */
     @Test
-    public void testCacheGroupsView() throws Exception {
+    public void testCacheGroupsView() {
         Set<String> grpNames = new HashSet<>(asList("grp-1", "grp-2"));
 
         for (String grpName : grpNames)
@@ -279,7 +279,7 @@ public class SqlViewExporterSpiTest extends 
AbstractExporterSpiTest {
 
     /** */
     @Test
-    public void testServices() throws Exception {
+    public void testServices() {
         ServiceConfiguration srvcCfg = new ServiceConfiguration();
 
         srvcCfg.setName("service");
@@ -408,7 +408,7 @@ public class SqlViewExporterSpiTest extends 
AbstractExporterSpiTest {
 
     /** */
     @Test
-    public void testViews() throws Exception {
+    public void testViews() {
         Set<String> expViews = new TreeSet<>(asList(
             "METRICS",
             "SERVICES",
@@ -420,6 +420,7 @@ public class SqlViewExporterSpiTest extends 
AbstractExporterSpiTest {
             "NODES",
             "SCHEMAS",
             "NODE_METRICS",
+            "CONFIGURATION",
             "BASELINE_NODES",
             "BASELINE_NODE_ATTRIBUTES",
             "INDEXES",
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/SqlSystemViewsSelfTest.java
 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/SqlSystemViewsSelfTest.java
index 196e057f7c7..bdbe98fad72 100644
--- 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/SqlSystemViewsSelfTest.java
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/SqlSystemViewsSelfTest.java
@@ -31,6 +31,7 @@ import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.Callable;
 import java.util.concurrent.TimeUnit;
+import java.util.function.BiConsumer;
 import java.util.stream.Collectors;
 import java.util.stream.LongStream;
 import javax.cache.Cache;
@@ -86,7 +87,9 @@ import org.junit.Test;
 
 import static java.util.Arrays.asList;
 import static java.util.stream.Collectors.toSet;
+import static org.apache.ignite.events.EventType.EVT_CONSISTENCY_VIOLATION;
 import static 
org.apache.ignite.internal.processors.cache.persistence.metastorage.MetaStorage.METASTORAGE_CACHE_NAME;
+import static org.apache.ignite.internal.util.IgniteUtils.MB;
 import static org.apache.ignite.testframework.GridTestUtils.waitForCondition;
 import static org.junit.Assert.assertNotEquals;
 
@@ -1693,6 +1696,49 @@ public class SqlSystemViewsSelfTest extends 
AbstractIndexingCommonTest {
         assertEqualsCollections(elevenExpVals, durationMetrics);
     }
 
+    /** */
+    @Test
+    public void testConfigurationView() throws Exception {
+        IgniteConfiguration icfg = new IgniteConfiguration();
+
+        long expMaxSize = 10 * MB;
+
+        String expName = "my-instance";
+
+        String expDrName = "my-dr";
+
+        icfg.setIgniteInstanceName(expName)
+            .setIncludeEventTypes(EVT_CONSISTENCY_VIOLATION);
+        icfg.setDataStorageConfiguration(new DataStorageConfiguration()
+            .setDefaultDataRegionConfiguration(
+                new DataRegionConfiguration()
+                    .setLazyMemoryAllocation(false))
+            .setDataRegionConfigurations(
+                new DataRegionConfiguration()
+                    .setName(expDrName)
+                    .setMaxSize(expMaxSize)));
+
+        try (IgniteEx srv = startGrid(icfg)) {
+            srv.createCache(DEFAULT_CACHE_NAME);
+
+            BiConsumer<String, String> checker = (name, val) -> assertEquals(
+                val,
+                execSql(srv, "SELECT VALUE FROM SYS.CONFIGURATION WHERE NAME = 
?", name).get(0).get(0)
+            );
+
+            checker.accept("IgniteInstanceName", expName);
+            
checker.accept("DataStorageConfiguration.DefaultDataRegionConfiguration.LazyMemoryAllocation",
 "false");
+            
checker.accept("DataStorageConfiguration.DataRegionConfigurations[0].Name", 
expDrName);
+            checker.accept(
+                "DataStorageConfiguration.DataRegionConfigurations[0].MaxSize",
+                Long.toString(expMaxSize)
+            );
+            checker.accept("CacheConfiguration[0].AtomicityMode", 
CacheAtomicityMode.TRANSACTIONAL.name());
+            checker.accept("AddressResolver", null);
+            checker.accept("IncludeEventTypes", "[" + 
EVT_CONSISTENCY_VIOLATION + ']');
+        }
+    }
+
     /**
      * Mock for {@link ClusterMetricsImpl} that always returns big (more than 
24h) duration for all duration metrics.
      */


Reply via email to