You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by tl...@apache.org on 2020/09/23 07:23:32 UTC
[ignite] branch master updated: IGNITE-13186 Commands for
control.sh to manage properties at the distributed metastore (#8208)
This is an automated email from the ASF dual-hosted git repository.
tledkov 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 0f208ca IGNITE-13186 Commands for control.sh to manage properties at the distributed metastore (#8208)
0f208ca is described below
commit 0f208caf21247866117c33d1f085b7eb542c497a
Author: tledkov <tl...@gridgain.com>
AuthorDate: Wed Sep 23 10:23:10 2020 +0300
IGNITE-13186 Commands for control.sh to manage properties at the distributed metastore
(#8208)
---
.../ignite/internal/commandline/CommandList.java | 6 +-
.../commandline/property/PropertyCommand.java | 100 +++++++++++++++
.../property/PropertySubCommandsList.java | 73 +++++++++++
.../subcommands/PropertyAbstractSubCommand.java | 105 ++++++++++++++++
.../property/subcommands/PropertyGetCommand.java | 63 ++++++++++
.../property/subcommands/PropertyHelpCommand.java | 49 ++++++++
.../property/subcommands/PropertyListCommand.java | 50 ++++++++
.../property/subcommands/PropertySetCommand.java | 72 +++++++++++
.../commandline/CommandHandlerParsingTest.java | 3 +-
.../testsuites/IgniteControlUtilityTestSuite.java | 3 +
.../util/GridCommandHandlerClusterByClassTest.java | 2 +-
.../util/GridCommandHandlerPropertiesTest.java | 138 +++++++++++++++++++++
.../ignite/internal/cluster/IgniteClusterImpl.java | 9 +-
.../commandline/property/PropertyArgs.java | 117 +++++++++++++++++
.../property/tasks/PropertiesListResult.java | 73 +++++++++++
.../property/tasks/PropertiesListTask.java | 84 +++++++++++++
.../property/tasks/PropertyOperationResult.java | 71 +++++++++++
.../commandline/property/tasks/PropertyTask.java | 111 +++++++++++++++++
.../distributed/DistributedBooleanProperty.java | 3 +-
.../distributed/DistributedChangeableProperty.java | 6 +
.../distributed/DistributedComparableProperty.java | 6 +-
.../DistributedConfigurationProcessor.java | 25 ++++
.../distributed/DistributedEnumProperty.java | 46 ++++---
.../distributed/DistributedLongProperty.java | 3 +-
.../distributed/SimpleDistributedProperty.java | 69 ++++++++++-
.../DistributedTracingConfiguration.java | 8 +-
.../ignite/plugin/security/SecurityPermission.java | 8 +-
.../main/resources/META-INF/classnames.properties | 5 +
...ridCommandHandlerClusterByClassTest_help.output | 12 ++
...andHandlerClusterByClassWithSSLTest_help.output | 12 ++
.../query/h2/DistributedSqlConfiguration.java | 12 +-
31 files changed, 1301 insertions(+), 43 deletions(-)
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandList.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandList.java
index 4190604..b6a221b 100644
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandList.java
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandList.java
@@ -21,6 +21,7 @@ import org.apache.ignite.internal.commandline.cache.CacheCommands;
import org.apache.ignite.internal.commandline.diagnostic.DiagnosticCommand;
import org.apache.ignite.internal.commandline.encryption.EncryptionCommand;
import org.apache.ignite.internal.commandline.meta.MetadataCommand;
+import org.apache.ignite.internal.commandline.property.PropertyCommand;
import org.apache.ignite.internal.commandline.query.KillCommand;
import org.apache.ignite.internal.commandline.snapshot.SnapshotCommand;
@@ -77,7 +78,10 @@ public enum CommandList {
TRACING_CONFIGURATION("--tracing-configuration", new TracingConfigurationCommand()),
/** Warm-up command. */
- WARM_UP("--warm-up", new WarmUpCommand());
+ WARM_UP("--warm-up", new WarmUpCommand()),
+
+ /** Commands to manage distributed properties. */
+ PROPERTY("--property", new PropertyCommand());
/** Private values copy so there's no need in cloning it every time. */
private static final CommandList[] VALUES = CommandList.values();
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/property/PropertyCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/property/PropertyCommand.java
new file mode 100644
index 0000000..bee355f
--- /dev/null
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/property/PropertyCommand.java
@@ -0,0 +1,100 @@
+/*
+ * 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.commandline.property;
+
+import java.util.logging.Logger;
+import org.apache.ignite.internal.client.GridClientConfiguration;
+import org.apache.ignite.internal.commandline.Command;
+import org.apache.ignite.internal.commandline.CommandArgIterator;
+import org.apache.ignite.internal.processors.configuration.distributed.DistributedChangeableProperty;
+
+import static org.apache.ignite.internal.commandline.Command.usage;
+import static org.apache.ignite.internal.commandline.CommandList.PROPERTY;
+import static org.apache.ignite.internal.commandline.property.PropertySubCommandsList.GET;
+import static org.apache.ignite.internal.commandline.property.PropertySubCommandsList.HELP;
+import static org.apache.ignite.internal.commandline.property.PropertySubCommandsList.LIST;
+import static org.apache.ignite.internal.commandline.property.PropertySubCommandsList.SET;
+
+/**
+ * Command to manage distributed properties (see {@link DistributedChangeableProperty})
+ */
+public class PropertyCommand implements Command<Object> {
+ /**
+ *
+ */
+ private Command<?> delegate;
+
+ /** {@inheritDoc} */
+ @Override public void printUsage(Logger log) {
+ usage(log, "Print property command help:",
+ PROPERTY,
+ HELP.toString()
+ );
+
+ usage(log, "Print list of available properties:",
+ PROPERTY,
+ LIST.toString()
+ );
+
+ usage(log, "Get the property value",
+ PROPERTY,
+ GET.toString(),
+ PropertyArgs.NAME,
+ "<property_name>");
+
+ usage(log, "Set the property value",
+ PROPERTY,
+ SET.toString(),
+ PropertyArgs.NAME,
+ "<property_name>",
+ PropertyArgs.VAL,
+ "<property_value>");
+ }
+
+ /** {@inheritDoc} */
+ @Override public String name() {
+ return PROPERTY.toCommandName();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void parseArguments(CommandArgIterator argIter) {
+ PropertySubCommandsList subcommand = PropertySubCommandsList.parse(argIter.nextArg("Expected property action."));
+
+ if (subcommand == null)
+ throw new IllegalArgumentException("Expected correct property action.");
+
+ delegate = subcommand.command();
+
+ delegate.parseArguments(argIter);
+ }
+
+ /** {@inheritDoc} */
+ @Override public String confirmationPrompt() {
+ return delegate != null ? delegate.confirmationPrompt() : null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Object execute(GridClientConfiguration clientCfg, Logger log) throws Exception {
+ return delegate.execute(clientCfg, log);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Object arg() {
+ return delegate.arg();
+ }
+}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/property/PropertySubCommandsList.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/property/PropertySubCommandsList.java
new file mode 100644
index 0000000..c24ec07
--- /dev/null
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/property/PropertySubCommandsList.java
@@ -0,0 +1,73 @@
+/*
+ * 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.commandline.property;
+
+import org.apache.ignite.internal.commandline.Command;
+import org.apache.ignite.internal.commandline.property.subcommands.PropertyGetCommand;
+import org.apache.ignite.internal.commandline.property.subcommands.PropertyHelpCommand;
+import org.apache.ignite.internal.commandline.property.subcommands.PropertyListCommand;
+import org.apache.ignite.internal.commandline.property.subcommands.PropertySetCommand;
+
+/** */
+public enum PropertySubCommandsList {
+ /** */
+ HELP("help", new PropertyHelpCommand()),
+ /** */
+ LIST("list", new PropertyListCommand()),
+ /** */
+ GET("get", new PropertyGetCommand()),
+ /** */
+ SET("set", new PropertySetCommand());
+
+ /** */
+ private final String name;
+
+ /** */
+ private final Command<?> cmd;
+
+ /** */
+ PropertySubCommandsList(String name, Command<?> cmd) {
+ this.name = name;
+ this.cmd = cmd;
+ }
+
+ /** */
+ public String text() {
+ return name;
+ }
+
+ /** */
+ public Command<?> command() {
+ return cmd;
+ }
+
+ /** */
+ public static PropertySubCommandsList parse(String name) {
+ for (PropertySubCommandsList cmd : values()) {
+ if (cmd.name.equalsIgnoreCase(name))
+ return cmd;
+ }
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return name;
+ }
+}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/property/subcommands/PropertyAbstractSubCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/property/subcommands/PropertyAbstractSubCommand.java
new file mode 100644
index 0000000..251ae21
--- /dev/null
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/property/subcommands/PropertyAbstractSubCommand.java
@@ -0,0 +1,105 @@
+/*
+ * 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.commandline.property.subcommands;
+
+import java.util.Collection;
+import java.util.logging.Logger;
+import org.apache.ignite.internal.client.GridClient;
+import org.apache.ignite.internal.client.GridClientCompute;
+import org.apache.ignite.internal.client.GridClientConfiguration;
+import org.apache.ignite.internal.client.GridClientDisconnectedException;
+import org.apache.ignite.internal.client.GridClientNode;
+import org.apache.ignite.internal.commandline.Command;
+import org.apache.ignite.internal.commandline.CommandArgIterator;
+import org.apache.ignite.internal.commandline.CommandLogger;
+import org.apache.ignite.internal.dto.IgniteDataTransferObject;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.visor.VisorTaskArgument;
+
+/** */
+public abstract class PropertyAbstractSubCommand<
+ MetadataArgsDto extends IgniteDataTransferObject,
+ MetadataResultDto extends IgniteDataTransferObject>
+ implements Command<MetadataArgsDto> {
+ /** */
+ private MetadataArgsDto args;
+
+ /** {@inheritDoc} */
+ @Override public final void printUsage(Logger log) {
+ throw new UnsupportedOperationException("printUsage");
+ }
+
+ /** {@inheritDoc} */
+ @Override public final void parseArguments(CommandArgIterator argIter) {
+ args = parseArguments0(argIter);
+ }
+
+ /** {@inheritDoc} */
+ @Override public final Object execute(GridClientConfiguration clientCfg, Logger log) throws Exception {
+ try (GridClient client = Command.startClient(clientCfg)) {
+ GridClientCompute compute = client.compute();
+
+ // Try to find connectable server nodes.
+ Collection<GridClientNode> nodes = compute.nodes((n) -> n.connectable() && !n.isClient());
+
+ if (F.isEmpty(nodes)) {
+ nodes = compute.nodes(GridClientNode::connectable);
+
+ if (F.isEmpty(nodes))
+ throw new GridClientDisconnectedException("Connectable nodes not found", null);
+ }
+
+ GridClientNode node = nodes.stream()
+ .findAny().orElse(null);
+
+ if (node == null)
+ node = compute.balancer().balancedNode(nodes);
+
+ MetadataResultDto res = compute.projection(node).execute(
+ taskName(),
+ new VisorTaskArgument<>(node.nodeId(), arg(), false)
+ );
+
+ printResult(res, log);
+ }
+ catch (Throwable e) {
+ log.severe("Failed to execute metadata command='" + name() + "'");
+ log.severe(CommandLogger.errorMessage(e));
+
+ throw e;
+ }
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public final MetadataArgsDto arg() {
+ return args;
+ }
+
+ /** */
+ protected abstract String taskName();
+
+ /** */
+ protected MetadataArgsDto parseArguments0(CommandArgIterator argIter) {
+ return null;
+ }
+
+ /** */
+ protected abstract void printResult(MetadataResultDto res, Logger log);
+}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/property/subcommands/PropertyGetCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/property/subcommands/PropertyGetCommand.java
new file mode 100644
index 0000000..1390b89
--- /dev/null
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/property/subcommands/PropertyGetCommand.java
@@ -0,0 +1,63 @@
+/*
+ * 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.commandline.property.subcommands;
+
+import java.util.logging.Logger;
+import org.apache.ignite.internal.commandline.CommandArgIterator;
+import org.apache.ignite.internal.commandline.property.PropertyArgs;
+import org.apache.ignite.internal.commandline.property.PropertySubCommandsList;
+import org.apache.ignite.internal.commandline.property.tasks.PropertyOperationResult;
+import org.apache.ignite.internal.commandline.property.tasks.PropertyTask;
+
+/** */
+public class PropertyGetCommand extends PropertyAbstractSubCommand<PropertyArgs, PropertyOperationResult>
+{
+ /** {@inheritDoc} */
+ @Override protected String taskName() {
+ return PropertyTask.class.getName();
+ }
+
+ /** {@inheritDoc} */
+ @Override public PropertyArgs parseArguments0(CommandArgIterator argIter) {
+ String name = null;
+
+ while (argIter.hasNextSubArg() && name == null) {
+ String optName = argIter.nextArg("Expecting " + PropertyArgs.NAME);
+
+ if (PropertyArgs.NAME.equals(optName))
+ name = argIter.nextArg("property name");
+ }
+
+ if (name == null) {
+ throw new IllegalArgumentException("Property name is not specified. " +
+ "Please use the option: --name <property_name>");
+ }
+
+ return new PropertyArgs(name, null, PropertyArgs.Action.GET);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void printResult(PropertyOperationResult res, Logger log) {
+ log.info(arg().name() + " = " + res.value());
+ }
+
+ /** {@inheritDoc} */
+ @Override public String name() {
+ return PropertySubCommandsList.GET.text();
+ }
+}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/property/subcommands/PropertyHelpCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/property/subcommands/PropertyHelpCommand.java
new file mode 100644
index 0000000..61f3080
--- /dev/null
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/property/subcommands/PropertyHelpCommand.java
@@ -0,0 +1,49 @@
+/*
+ * 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.commandline.property.subcommands;
+
+import java.util.logging.Logger;
+import org.apache.ignite.internal.client.GridClientConfiguration;
+import org.apache.ignite.internal.commandline.Command;
+import org.apache.ignite.internal.commandline.meta.MetadataCommand;
+import org.apache.ignite.internal.commandline.meta.MetadataSubCommandsList;
+
+/** */
+public class PropertyHelpCommand implements Command<Void> {
+ /** {@inheritDoc} */
+ @Override public void printUsage(Logger log) {
+ throw new UnsupportedOperationException("printUsage");
+ }
+
+ /** {@inheritDoc} */
+ @Override public Object execute(GridClientConfiguration clientCfg, Logger log) throws Exception {
+ new MetadataCommand().printUsage(log);
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Void arg() {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String name() {
+ return MetadataSubCommandsList.HELP.text();
+ }
+}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/property/subcommands/PropertyListCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/property/subcommands/PropertyListCommand.java
new file mode 100644
index 0000000..c63f32a
--- /dev/null
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/property/subcommands/PropertyListCommand.java
@@ -0,0 +1,50 @@
+/*
+ * 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.commandline.property.subcommands;
+
+import java.util.logging.Logger;
+import org.apache.ignite.internal.commandline.CommandArgIterator;
+import org.apache.ignite.internal.commandline.meta.subcommands.VoidDto;
+import org.apache.ignite.internal.commandline.property.PropertySubCommandsList;
+import org.apache.ignite.internal.commandline.property.tasks.PropertiesListResult;
+import org.apache.ignite.internal.commandline.property.tasks.PropertiesListTask;
+
+/** */
+public class PropertyListCommand extends PropertyAbstractSubCommand<VoidDto, PropertiesListResult>
+{
+ /** {@inheritDoc} */
+ @Override protected String taskName() {
+ return PropertiesListTask.class.getName();
+ }
+
+ /** {@inheritDoc} */
+ @Override public VoidDto parseArguments0(CommandArgIterator argIter) {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void printResult(PropertiesListResult res, Logger log) {
+ for (String prop : res.properties())
+ log.info(prop);
+ }
+
+ /** {@inheritDoc} */
+ @Override public String name() {
+ return PropertySubCommandsList.LIST.text();
+ }
+}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/property/subcommands/PropertySetCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/property/subcommands/PropertySetCommand.java
new file mode 100644
index 0000000..bb0ee3a
--- /dev/null
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/property/subcommands/PropertySetCommand.java
@@ -0,0 +1,72 @@
+/*
+ * 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.commandline.property.subcommands;
+
+import java.util.logging.Logger;
+import org.apache.ignite.internal.commandline.CommandArgIterator;
+import org.apache.ignite.internal.commandline.property.PropertyArgs;
+import org.apache.ignite.internal.commandline.property.PropertySubCommandsList;
+import org.apache.ignite.internal.commandline.property.tasks.PropertyOperationResult;
+import org.apache.ignite.internal.commandline.property.tasks.PropertyTask;
+
+/** */
+public class PropertySetCommand extends PropertyAbstractSubCommand<PropertyArgs, PropertyOperationResult>
+{
+ /** {@inheritDoc} */
+ @Override protected String taskName() {
+ return PropertyTask.class.getName();
+ }
+
+ /** {@inheritDoc} */
+ @Override public PropertyArgs parseArguments0(CommandArgIterator argIter) {
+ String name = null;
+ String val = null;
+
+ while (argIter.hasNextSubArg() && (name == null || val == null)) {
+ String optName = argIter.nextArg("Expecting " + (name == null ? PropertyArgs.NAME : PropertyArgs.VAL));
+
+ if (PropertyArgs.NAME.equals(optName))
+ name = argIter.nextArg("property name");
+
+ if (PropertyArgs.VAL.equals(optName))
+ val = argIter.nextArg("property value");
+ }
+
+ if (name == null) {
+ throw new IllegalArgumentException("Property name is not specified. " +
+ "Please the option: --name <property_name>");
+ }
+
+ if (val == null) {
+ throw new IllegalArgumentException("Property name is not specified. " +
+ "Please the option: --name <property_name>");
+ }
+
+ return new PropertyArgs(name, val, PropertyArgs.Action.SET);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void printResult(PropertyOperationResult res, Logger log) {
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
+ @Override public String name() {
+ return PropertySubCommandsList.SET.text();
+ }
+}
diff --git a/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/CommandHandlerParsingTest.java b/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/CommandHandlerParsingTest.java
index 1066ca7..2dade20 100644
--- a/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/CommandHandlerParsingTest.java
+++ b/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/CommandHandlerParsingTest.java
@@ -1030,6 +1030,7 @@ public class CommandHandlerParsingTest {
cmd == CommandList.SNAPSHOT ||
cmd == CommandList.CLUSTER_CHANGE_TAG ||
cmd == CommandList.METADATA ||
- cmd == CommandList.WARM_UP;
+ cmd == CommandList.WARM_UP ||
+ cmd == CommandList.PROPERTY;
}
}
diff --git a/modules/control-utility/src/test/java/org/apache/ignite/testsuites/IgniteControlUtilityTestSuite.java b/modules/control-utility/src/test/java/org/apache/ignite/testsuites/IgniteControlUtilityTestSuite.java
index e21f474..f4e8df4 100644
--- a/modules/control-utility/src/test/java/org/apache/ignite/testsuites/IgniteControlUtilityTestSuite.java
+++ b/modules/control-utility/src/test/java/org/apache/ignite/testsuites/IgniteControlUtilityTestSuite.java
@@ -34,6 +34,7 @@ import org.apache.ignite.util.GridCommandHandlerIndexingClusterByClassWithSSLTes
import org.apache.ignite.util.GridCommandHandlerIndexingTest;
import org.apache.ignite.util.GridCommandHandlerIndexingWithSSLTest;
import org.apache.ignite.util.GridCommandHandlerMetadataTest;
+import org.apache.ignite.util.GridCommandHandlerPropertiesTest;
import org.apache.ignite.util.GridCommandHandlerSslTest;
import org.apache.ignite.util.GridCommandHandlerTest;
import org.apache.ignite.util.GridCommandHandlerTracingConfigurationTest;
@@ -76,6 +77,8 @@ import org.junit.runners.Suite;
GridCommandHandlerIndexRebuildStatusTest.class,
GridCommandHandlerTracingConfigurationTest.class,
+
+ GridCommandHandlerPropertiesTest.class,
})
public class IgniteControlUtilityTestSuite {
}
diff --git a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerClusterByClassTest.java b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerClusterByClassTest.java
index 2d854af..4403e38 100644
--- a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerClusterByClassTest.java
+++ b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerClusterByClassTest.java
@@ -128,7 +128,7 @@ public class GridCommandHandlerClusterByClassTest extends GridCommandHandlerClus
protected static final String ERROR_STACK_TRACE_PREFIX = "Error stack trace:";
/**
- * Very basic tests for running the command in different enviroment which other command are running in.
+ * Very basic tests for running the command in different environment which other command are running in.
*/
@Test
public void testFindAndDeleteGarbage() {
diff --git a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerPropertiesTest.java b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerPropertiesTest.java
new file mode 100644
index 0000000..111b5c0
--- /dev/null
+++ b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerPropertiesTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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.util;
+
+import java.io.Serializable;
+import java.util.Set;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.configuration.distributed.DistributedChangeableProperty;
+import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing;
+import org.apache.ignite.internal.util.typedef.G;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_INVALID_ARGUMENTS;
+import static org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_OK;
+import static org.apache.ignite.testframework.GridTestUtils.assertContains;
+
+/**
+ * Checks command line property commands.
+ */
+public class GridCommandHandlerPropertiesTest extends GridCommandHandlerClusterByClassAbstractTest {
+ /** */
+ @Before
+ public void init() {
+ injectTestSystemOut();
+ }
+
+ /** */
+ @After
+ public void clear() {
+ }
+
+ /**
+ * Check the command '--property list'.
+ * Steps:
+ */
+ @Test
+ public void testList() {
+ assertEquals(EXIT_CODE_OK, execute("--property", "list"));
+
+ String out = testOut.toString();
+
+ for (DistributedChangeableProperty<Serializable> pd : crd.context()
+ .distributedConfiguration().properties())
+ assertContains(log, out, pd.getName());
+ }
+
+ /**
+ * Check the command '--property get'.
+ * Steps:
+ */
+ @Test
+ public void testGet() {
+ for (DistributedChangeableProperty<Serializable> pd : crd.context()
+ .distributedConfiguration().properties()) {
+ assertEquals(EXIT_CODE_OK, execute("--property", "get", "--name", pd.getName()));
+ String out = testOut.toString();
+
+ assertContains(log, out, pd.getName() + " = " + pd.get());
+ }
+ }
+
+ /**
+ * Check the set command fro property 'sql.disabledFunctions'.
+ * Steps:
+ */
+ @Test
+ public void testPropertyDisabledSqlFunctions() {
+ assertEquals(
+ EXIT_CODE_OK,
+ execute(
+ "--property", "set",
+ "--name", "sql.disabledFunctions",
+ "--val", "LENGTH, SESSION_ID"
+ )
+ );
+
+ for (Ignite ign : G.allGrids()) {
+ Set<String> disabledFuncs = ((IgniteH2Indexing)((IgniteEx)ign).context().query().getIndexing())
+ .distributedConfiguration().disabledFunctions();
+
+ assertEquals(2, disabledFuncs.size());
+
+ assertTrue(disabledFuncs.contains("LENGTH"));
+ assertTrue(disabledFuncs.contains("SESSION_ID"));
+ }
+ }
+
+ /**
+ * Check the set command fro property 'sql.defaultQueryTimeout'.
+ * Steps:
+ */
+ @Test
+ public void testPropertyDefaultQueryTimeout() {
+ int dfltVal = ((IgniteH2Indexing)crd.context().query().getIndexing())
+ .distributedConfiguration().defaultQueryTimeout();
+
+ int newVal = dfltVal + 1000;
+
+ assertEquals(EXIT_CODE_OK, execute("--property", "set", "--name", "sql.defaultQueryTimeout", "--val",
+ Integer.toString(newVal)));
+
+ for (Ignite ign : G.allGrids()) {
+ assertEquals(
+ "Invalid default query timeout on node: " + ign.name(),
+ newVal,
+ ((IgniteH2Indexing)((IgniteEx)ign).context().query().getIndexing())
+ .distributedConfiguration().defaultQueryTimeout()
+ );
+ }
+
+ assertEquals(
+ EXIT_CODE_INVALID_ARGUMENTS,
+ execute(
+ "--property", "set",
+ "--name", "sql.defaultQueryTimeout",
+ "--val", "invalidVal"
+ )
+ );
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/cluster/IgniteClusterImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/cluster/IgniteClusterImpl.java
index df1ad33..6ee7da9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/cluster/IgniteClusterImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/cluster/IgniteClusterImpl.java
@@ -116,12 +116,9 @@ public class IgniteClusterImpl extends ClusterGroupAdapter implements IgniteClus
/** Property for update policy of shutdown. */
private DistributedEnumProperty<ShutdownPolicy> shutdown = new DistributedEnumProperty<>(
"shutdown.policy",
- (ordinal) -> {
- return ordinal == null ? null : ShutdownPolicy.fromOrdinal(ordinal);
- },
- (policy) -> {
- return policy == null ? null : policy.index();
- }
+ (ordinal) -> ordinal == null ? null : ShutdownPolicy.fromOrdinal(ordinal),
+ (policy) -> policy == null ? null : policy.index(),
+ ShutdownPolicy.class
);
/**
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/commandline/property/PropertyArgs.java b/modules/core/src/main/java/org/apache/ignite/internal/commandline/property/PropertyArgs.java
new file mode 100644
index 0000000..d998369
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/commandline/property/PropertyArgs.java
@@ -0,0 +1,117 @@
+/*
+ * 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.commandline.property;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.apache.ignite.internal.dto.IgniteDataTransferObject;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.Nullable;
+
+/** */
+public class PropertyArgs extends IgniteDataTransferObject {
+ /** Serial version uid. */
+ private static final long serialVersionUID = 0L;
+
+ /** Property name argument name. */
+ public static final String NAME = "--name";
+
+ /** Type value argument name . */
+ public static final String VAL = "--val";
+
+ /** Property name . */
+ private String name;
+
+ /** Property's value. */
+ private String val;
+
+ /** Action. */
+ private Action action;
+
+ /**
+ * Default constructor.
+ */
+ public PropertyArgs() {
+ // No-op.
+ }
+
+ /** */
+ public PropertyArgs(String name, String val, Action action) {
+ assert name != null;
+
+ this.name = name;
+ this.val = val;
+ this.action = action;
+ }
+
+ /** */
+ public String name() {
+ return name;
+ }
+
+ /** */
+ public String value() {
+ return val;
+ }
+
+ /** */
+ public Action action() {
+ return action;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void writeExternalData(ObjectOutput out) throws IOException {
+ U.writeString(out, name);
+ U.writeString(out, val);
+ out.writeByte(action.ordinal());
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void readExternalData(byte protoVer, ObjectInput in) throws IOException, ClassNotFoundException {
+ name = U.readString(in);
+ val = U.readString(in);
+ action = Action.fromOrdinal(in.readByte());
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return name + "=" + val;
+ }
+
+ /**
+ *
+ */
+ public enum Action {
+ /** */
+ GET,
+
+ /** */
+ SET;
+
+ /** Enumerated values. */
+ private static final Action[] VALS = values();
+
+ /**
+ * Efficiently gets enumerated value from its ordinal.
+ */
+ @Nullable public static Action fromOrdinal(int ord) {
+ return ord >= 0 && ord < VALS.length ? VALS[ord] : null;
+ }
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/commandline/property/tasks/PropertiesListResult.java b/modules/core/src/main/java/org/apache/ignite/internal/commandline/property/tasks/PropertiesListResult.java
new file mode 100644
index 0000000..7c35077
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/commandline/property/tasks/PropertiesListResult.java
@@ -0,0 +1,73 @@
+/*
+ * 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.commandline.property.tasks;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collection;
+import java.util.Collections;
+import org.apache.ignite.internal.dto.IgniteDataTransferObject;
+import org.apache.ignite.internal.processors.task.GridInternal;
+import org.apache.ignite.internal.util.typedef.internal.U;
+
+/**
+ * List of the distributed properties names.
+ */
+@GridInternal
+public class PropertiesListResult extends IgniteDataTransferObject {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** Properties names. */
+ private Collection<String> props = Collections.emptyList();
+
+ /**
+ * Constructor for optimized marshaller.
+ */
+ public PropertiesListResult() {
+ // No-op.
+ }
+
+ /**
+ * @param props Properties.
+ */
+ public PropertiesListResult(Collection<String> props) {
+ this.props = props;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void writeExternalData(ObjectOutput out) throws IOException {
+ U.writeCollection(out, props);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void readExternalData(
+ byte protoVer,
+ ObjectInput in
+ ) throws IOException, ClassNotFoundException {
+ props = U.readCollection(in);
+ }
+
+ /**
+ * @return Properties (name, description) collection.
+ */
+ public Collection<String> properties() {
+ return props;
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/commandline/property/tasks/PropertiesListTask.java b/modules/core/src/main/java/org/apache/ignite/internal/commandline/property/tasks/PropertiesListTask.java
new file mode 100644
index 0000000..a23f734
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/commandline/property/tasks/PropertiesListTask.java
@@ -0,0 +1,84 @@
+/*
+ * 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.commandline.property.tasks;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.compute.ComputeJobResult;
+import org.apache.ignite.internal.commandline.meta.subcommands.VoidDto;
+import org.apache.ignite.internal.processors.task.GridInternal;
+import org.apache.ignite.internal.visor.VisorJob;
+import org.apache.ignite.internal.visor.VisorMultiNodeTask;
+import org.jetbrains.annotations.Nullable;
+
+import static org.apache.ignite.plugin.security.SecurityPermission.ADMIN_READ_DISTRIBUTED_PROPERTY;
+
+/**
+ * Task for property operations.
+ */
+@GridInternal
+public class PropertiesListTask extends VisorMultiNodeTask<VoidDto, PropertiesListResult, PropertiesListResult> {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** {@inheritDoc} */
+ @Override protected VisorJob<VoidDto, PropertiesListResult> job(VoidDto arg) {
+ return new PropertiesListJob(debug);
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override protected PropertiesListResult reduce0(List<ComputeJobResult> results) {
+ if (results.isEmpty())
+ throw new IgniteException("Empty job results");
+
+ if (results.size() > 1)
+ throw new IgniteException("Invalid job results: " + results);
+
+ if (results.get(0).getException() != null)
+ throw results.get(0).getException();
+ else
+ return results.get(0).getData();
+ }
+
+ /**
+ * Job for property operations (get/set).
+ */
+ private static class PropertiesListJob extends VisorJob<VoidDto, PropertiesListResult> {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * @param debug Debug.
+ */
+ protected PropertiesListJob(boolean debug) {
+ super(null, debug);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected PropertiesListResult run(@Nullable VoidDto arg) {
+ ignite.context().security().authorize(ADMIN_READ_DISTRIBUTED_PROPERTY);
+
+ return new PropertiesListResult(
+ ignite.context().distributedConfiguration().properties().stream()
+ .map(pd -> pd.getName())
+ .collect(Collectors.toList())
+ );
+ }
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/commandline/property/tasks/PropertyOperationResult.java b/modules/core/src/main/java/org/apache/ignite/internal/commandline/property/tasks/PropertyOperationResult.java
new file mode 100644
index 0000000..9f5a899
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/commandline/property/tasks/PropertyOperationResult.java
@@ -0,0 +1,71 @@
+/*
+ * 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.commandline.property.tasks;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.apache.ignite.internal.dto.IgniteDataTransferObject;
+import org.apache.ignite.internal.processors.task.GridInternal;
+import org.apache.ignite.internal.util.typedef.internal.U;
+
+/**
+ * Result of an operation with property.
+ */
+@GridInternal
+public class PropertyOperationResult extends IgniteDataTransferObject {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** Property value. */
+ private String val;
+
+ /**
+ * Constructor for optimized marshaller.
+ */
+ public PropertyOperationResult() {
+ // No-op.
+ }
+
+ /**
+ * @param val Value.
+ */
+ public PropertyOperationResult(String val) {
+ this.val = val;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void writeExternalData(ObjectOutput out) throws IOException {
+ U.writeString(out, val);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void readExternalData(
+ byte protoVer,
+ ObjectInput in
+ ) throws IOException, ClassNotFoundException {
+ val = U.readString(in);
+ }
+
+ /**
+ * @return Property value.
+ */
+ public String value() {
+ return val;
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/commandline/property/tasks/PropertyTask.java b/modules/core/src/main/java/org/apache/ignite/internal/commandline/property/tasks/PropertyTask.java
new file mode 100644
index 0000000..aa2ade7
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/commandline/property/tasks/PropertyTask.java
@@ -0,0 +1,111 @@
+/*
+ * 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.commandline.property.tasks;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Objects;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.compute.ComputeJobResult;
+import org.apache.ignite.internal.commandline.property.PropertyArgs;
+import org.apache.ignite.internal.processors.configuration.distributed.DistributedChangeableProperty;
+import org.apache.ignite.internal.processors.task.GridInternal;
+import org.apache.ignite.internal.visor.VisorJob;
+import org.apache.ignite.internal.visor.VisorMultiNodeTask;
+import org.jetbrains.annotations.Nullable;
+
+import static org.apache.ignite.plugin.security.SecurityPermission.ADMIN_READ_DISTRIBUTED_PROPERTY;
+import static org.apache.ignite.plugin.security.SecurityPermission.ADMIN_WRITE_DISTRIBUTED_PROPERTY;
+
+/**
+ * Task for property operations.
+ */
+@GridInternal
+public class PropertyTask extends VisorMultiNodeTask<PropertyArgs, PropertyOperationResult, PropertyOperationResult> {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** {@inheritDoc} */
+ @Override protected VisorJob<PropertyArgs, PropertyOperationResult> job(PropertyArgs arg) {
+ return new PropertyJob(arg, debug);
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override protected PropertyOperationResult reduce0(List<ComputeJobResult> results) {
+ if (results.isEmpty())
+ throw new IgniteException("Empty job results");
+
+ if (results.size() > 1)
+ throw new IgniteException("Invalid job results: " + results);
+
+ if (results.get(0).getException() != null)
+ throw results.get(0).getException();
+ else
+ return results.get(0).getData();
+ }
+
+ /**
+ * Job for getting binary metadata.
+ */
+ private static class PropertyJob extends VisorJob<PropertyArgs, PropertyOperationResult> {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * @param arg Argument.
+ * @param debug Debug.
+ */
+ protected PropertyJob(@Nullable PropertyArgs arg, boolean debug) {
+ super(arg, debug);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected PropertyOperationResult run(@Nullable PropertyArgs arg) {
+ DistributedChangeableProperty<Serializable> prop =
+ ignite.context().distributedConfiguration().property(arg.name());
+
+ if (prop == null)
+ throw new IllegalArgumentException("Property doesn't not exist [name=" + arg.name() + ']');
+
+ switch (arg.action()) {
+ case GET:
+ ignite.context().security().authorize(ADMIN_READ_DISTRIBUTED_PROPERTY);
+
+ return new PropertyOperationResult(Objects.toString(prop.get()));
+
+ case SET:
+ ignite.context().security().authorize(ADMIN_WRITE_DISTRIBUTED_PROPERTY);
+
+ try {
+ prop.propagate(prop.parse(arg.value()));
+ }
+ catch (IgniteCheckedException e) {
+ throw new IgniteException(e);
+ }
+
+ return new PropertyOperationResult(null);
+
+ default:
+ assert false : "unexpected state";
+
+ return null;
+ }
+ }
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedBooleanProperty.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedBooleanProperty.java
index 878ebb0..934a32a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedBooleanProperty.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedBooleanProperty.java
@@ -21,10 +21,9 @@ package org.apache.ignite.internal.processors.configuration.distributed;
* Implementation of {@link DistributedProperty} for {@link Boolean}.
*/
public class DistributedBooleanProperty extends SimpleDistributedProperty<Boolean> {
-
/** {@inheritDoc} */
DistributedBooleanProperty(String name) {
- super(name);
+ super(name, Boolean::parseBoolean);
}
/**
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedChangeableProperty.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedChangeableProperty.java
index dfd4a25..36c89f0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedChangeableProperty.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedChangeableProperty.java
@@ -42,4 +42,10 @@ public interface DistributedChangeableProperty<T extends Serializable> extends D
* @param newVal New value.
*/
void localUpdate(Serializable newVal);
+
+ /**
+ * @param str String representation of the property value.
+ * @return Property value.
+ */
+ T parse(String str);
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedComparableProperty.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedComparableProperty.java
index 2e646d7..7ec38a3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedComparableProperty.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedComparableProperty.java
@@ -19,15 +19,15 @@ package org.apache.ignite.internal.processors.configuration.distributed;
import java.io.Serializable;
import java.util.Objects;
+import java.util.function.Function;
/**
* Implementation of {@link DistributedProperty} for {@link Comparable}.
*/
public class DistributedComparableProperty<T extends Comparable<T> & Serializable> extends SimpleDistributedProperty<T> {
-
/** {@inheritDoc} */
- DistributedComparableProperty(String name) {
- super(name);
+ DistributedComparableProperty(String name, Function<String, T> parser) {
+ super(name, parser);
}
/** */
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedConfigurationProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedConfigurationProcessor.java
index e89de39..5316f62 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedConfigurationProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedConfigurationProcessor.java
@@ -19,8 +19,10 @@ package org.apache.ignite.internal.processors.configuration.distributed;
import java.io.Serializable;
import java.util.Arrays;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.processors.GridProcessorAdapter;
@@ -154,6 +156,29 @@ public class DistributedConfigurationProcessor extends GridProcessorAdapter impl
}
/**
+ * @return Public properties.
+ */
+ public List<DistributedChangeableProperty<Serializable>> properties() {
+ return props.values().stream()
+ .filter(p -> p instanceof DistributedChangeableProperty)
+ .map(p -> (DistributedChangeableProperty<Serializable>)p)
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * @param name Property name.
+ * @return Public property.
+ */
+ public DistributedChangeableProperty<Serializable> property(String name) {
+ DistributedChangeableProperty<?> p = props.get(name);
+
+ if (!(p instanceof DistributedChangeableProperty))
+ return null;
+ else
+ return (DistributedChangeableProperty<Serializable>)p;
+ }
+
+ /**
* Execute all allowable actions until current action on given property.
*
* @param prop Property which action should be executed on.
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedEnumProperty.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedEnumProperty.java
index 10741dc..7632554 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedEnumProperty.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedEnumProperty.java
@@ -18,6 +18,9 @@
package org.apache.ignite.internal.processors.configuration.distributed;
import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.stream.Collectors;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
import org.apache.ignite.internal.util.typedef.internal.S;
@@ -38,38 +41,29 @@ public class DistributedEnumProperty<T extends Enum> implements DistributedChang
private final IgniteClosure<Integer, T> fromOrdinalFunc;
/** Function converts an enumeration value to an integer for stored in meta storage. */
- private final IgniteClosure<T, Integer> toOredinalFunc;
+ private final IgniteClosure<T, Integer> toOrdinalFunc;
- /**
- * Property constructor.
- *
- * @param name Name of property.
- * @param fromOrdinalFunc Function reflects an integer to an enumiration value.
- */
- public DistributedEnumProperty(
- String name,
- IgniteClosure<Integer, T> fromOrdinalFunc
- ) {
- this(name, fromOrdinalFunc, (T value) -> {
- return value == null ? null : value.ordinal();
- });
- }
+ /** Enum name-values map to parse string representation. */
+ private final Map<String, T> values;
/**
* Property constructor.
*
* @param name Name of property.
* @param fromOrdinalFunc Function reflects an integer to an enumiration value.
- * @param toOredinalFunc Function converts an enumeration value to an integer.
+ * @param toOrdinalFunc Function converts an enumeration value to an integer.
*/
public DistributedEnumProperty(
String name,
IgniteClosure<Integer, T> fromOrdinalFunc,
- IgniteClosure<T, Integer> toOredinalFunc
+ IgniteClosure<T, Integer> toOrdinalFunc,
+ Class<T> enumCls
) {
- this.internal = new SimpleDistributedProperty<>(name);
+ this.internal = new SimpleDistributedProperty<>(name, null);
this.fromOrdinalFunc = fromOrdinalFunc;
- this.toOredinalFunc = toOredinalFunc;
+ this.toOrdinalFunc = toOrdinalFunc;
+ this.values = Arrays.stream(enumCls.getEnumConstants())
+ .collect(Collectors.toMap(e -> e.name().toLowerCase(), e -> e));
}
/** {@inheritDoc} */
@@ -140,7 +134,7 @@ public class DistributedEnumProperty<T extends Enum> implements DistributedChang
* @return Ordinal or {@code null}.
*/
private Integer ordinalOrNull(T val) {
- return val == null ? null : toOredinalFunc.apply(val);
+ return val == null ? null : toOrdinalFunc.apply(val);
}
/**
@@ -154,6 +148,18 @@ public class DistributedEnumProperty<T extends Enum> implements DistributedChang
}
/** {@inheritDoc} */
+ @Override public T parse(String str) {
+ T t = values.get(str.toLowerCase());
+
+ if (t == null) {
+ throw new IllegalArgumentException("Unknown value for enum property " +
+ "[value=" + str + ", name=" + internal.getName());
+ }
+
+ return t;
+ }
+
+ /** {@inheritDoc} */
@Override public String toString() {
return S.toString(DistributedEnumProperty.class, this);
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedLongProperty.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedLongProperty.java
index 38b1ad0..fbfd316 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedLongProperty.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/DistributedLongProperty.java
@@ -21,10 +21,9 @@ package org.apache.ignite.internal.processors.configuration.distributed;
* Implementation of {@link DistributedProperty} for {@link Long}.
*/
public class DistributedLongProperty extends DistributedComparableProperty<Long> {
-
/** {@inheritDoc} */
DistributedLongProperty(String name) {
- super(name);
+ super(name, Long::parseLong);
}
/**
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/SimpleDistributedProperty.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/SimpleDistributedProperty.java
index 9819197..5753d30 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/SimpleDistributedProperty.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/configuration/distributed/SimpleDistributedProperty.java
@@ -18,8 +18,12 @@
package org.apache.ignite.internal.processors.configuration.distributed;
import java.io.Serializable;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.function.Function;
import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteException;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.typedef.internal.S;
@@ -48,11 +52,17 @@ public class SimpleDistributedProperty<T extends Serializable> implements Distri
@GridToStringExclude
private volatile PropertyUpdateClosure clusterWideUpdater;
+ /** Property value parser. */
+ @GridToStringExclude
+ private final Function<String, T> parser;
+
/**
* @param name Name of property.
+ * @param parser Property value parser.
*/
- public SimpleDistributedProperty(String name) {
+ public SimpleDistributedProperty(String name, Function<String, T> parser) {
this.name = name;
+ this.parser = parser;
}
/** {@inheritDoc} */
@@ -132,7 +142,64 @@ public class SimpleDistributedProperty<T extends Serializable> implements Distri
}
/** {@inheritDoc} */
+ @Override public T parse(String str) {
+ if (parser == null)
+ throw new IgniteException("The parser is not specified for property [name=" + name + ']');
+
+ return parser.apply(str);
+ }
+
+ /** {@inheritDoc} */
@Override public String toString() {
return S.toString(SimpleDistributedProperty.class, this);
}
+
+ /**
+ * @param val String to parse.
+ * @return Integer value.
+ */
+ public static Integer parseNonNegativeInteger(String val) {
+ if (val == null || val.trim().isEmpty())
+ return null;
+
+ int intVal = Integer.parseInt(val);
+
+ if (intVal < 0)
+ throw new IllegalArgumentException("The value must not be negative");
+
+ return intVal;
+ }
+
+ /**
+ * @param val String to parse.
+ * @return Long value.
+ */
+ public static Long parseNonNegativeLong(String val) {
+ if (val == null || val.trim().isEmpty())
+ return null;
+
+ long intVal = Long.parseLong(val);
+
+ if (intVal < 0)
+ throw new IllegalArgumentException("The value must not be negative");
+
+ return intVal;
+ }
+
+ /**
+ * @param val String value.
+ * @return String set.
+ */
+ public static HashSet<String> parseStringSet(String val) {
+ HashSet<String> set = new HashSet<>();
+
+ if (val == null || val.trim().isEmpty())
+ return set;
+
+ String[] vals = val.split("\\W+");
+
+ set.addAll(Arrays.asList(vals));
+
+ return set;
+ }
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/tracing/configuration/DistributedTracingConfiguration.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/tracing/configuration/DistributedTracingConfiguration.java
index 8624778..690d145 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/tracing/configuration/DistributedTracingConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/tracing/configuration/DistributedTracingConfiguration.java
@@ -18,6 +18,7 @@
package org.apache.ignite.internal.processors.tracing.configuration;
import java.util.HashMap;
+import org.apache.ignite.IgniteException;
import org.apache.ignite.internal.processors.configuration.distributed.DistributedConfigurationProcessor;
import org.apache.ignite.internal.processors.configuration.distributed.SimpleDistributedProperty;
import org.apache.ignite.spi.tracing.TracingConfigurationCoordinates;
@@ -36,7 +37,7 @@ public class DistributedTracingConfiguration
* Constructor.
*/
public DistributedTracingConfiguration() {
- super(TRACING_CONFIGURATION_DISTRIBUTED_METASTORE_KEY);
+ super(TRACING_CONFIGURATION_DISTRIBUTED_METASTORE_KEY, null);
}
/**
@@ -46,4 +47,9 @@ public class DistributedTracingConfiguration
public static DistributedTracingConfiguration detachedProperty() {
return new DistributedTracingConfiguration();
}
+
+ /** {@inheritDoc} */
+ @Override public HashMap<TracingConfigurationCoordinates, TracingConfigurationParameters> parse(String str) {
+ throw new IgniteException("Please use the '--tracing-configuration' command to modify the tracing configuration");
+ }
}
diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityPermission.java b/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityPermission.java
index e062bc3..d6fe810 100644
--- a/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityPermission.java
+++ b/modules/core/src/main/java/org/apache/ignite/plugin/security/SecurityPermission.java
@@ -76,7 +76,13 @@ public enum SecurityPermission {
JOIN_AS_SERVER,
/** Administration operation with cluster metadata (REMOVE, UPDATE). */
- ADMIN_METADATA_OPS;
+ ADMIN_METADATA_OPS,
+
+ /** Administration operation: read distributed properties values. */
+ ADMIN_READ_DISTRIBUTED_PROPERTY,
+
+ /** Administration operation: write distributed properties values. */
+ ADMIN_WRITE_DISTRIBUTED_PROPERTY;
/** Enumerated values. */
private static final SecurityPermission[] VALS = values();
diff --git a/modules/core/src/main/resources/META-INF/classnames.properties b/modules/core/src/main/resources/META-INF/classnames.properties
index 9815054..a7fc780 100644
--- a/modules/core/src/main/resources/META-INF/classnames.properties
+++ b/modules/core/src/main/resources/META-INF/classnames.properties
@@ -383,6 +383,11 @@ org.apache.ignite.internal.commandline.meta.tasks.MetadataRemoveTask$DropAllThin
org.apache.ignite.internal.commandline.meta.tasks.MetadataTypeArgs
org.apache.ignite.internal.commandline.meta.tasks.MetadataUpdateTask
org.apache.ignite.internal.commandline.meta.tasks.MetadataUpdateTask.MetadataUpdateJob
+org.apache.ignite.internal.commandline.property.tasks.PropertiesListResult
+org.apache.ignite.internal.commandline.property.tasks.PropertiesListTask
+org.apache.ignite.internal.commandline.property.tasks.PropertyOperationResult
+org.apache.ignite.internal.commandline.property.tasks.PropertyTask
+org.apache.ignite.internal.commandline.property.PropertyArgs
org.apache.ignite.internal.commandline.ru.RollingUpgradeCommandArg
org.apache.ignite.internal.commandline.ru.RollingUpgradeSubCommands
org.apache.ignite.internal.compute.ComputeTaskCancelledCheckedException
diff --git a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
index e8727aa..ca726a5 100644
--- a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
+++ b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
@@ -168,6 +168,18 @@ If the file name isn't specified the output file name is: '<typeId>.bin'
Stop warm-up:
control.(sh|bat) --warm-up --stop
+ Print property command help:
+ control.(sh|bat) --property help
+
+ Print list of available properties:
+ control.(sh|bat) --property list
+
+ Get the property value
+ control.(sh|bat) --property get --name <property_name>
+
+ Set the property value
+ control.(sh|bat) --property set --name <property_name> --val <property_value>
+
By default commands affecting the cluster require interactive confirmation.
Use --yes option to disable it.
diff --git a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
index e8727aa..ca726a5 100644
--- a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
+++ b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
@@ -168,6 +168,18 @@ If the file name isn't specified the output file name is: '<typeId>.bin'
Stop warm-up:
control.(sh|bat) --warm-up --stop
+ Print property command help:
+ control.(sh|bat) --property help
+
+ Print list of available properties:
+ control.(sh|bat) --property list
+
+ Get the property value
+ control.(sh|bat) --property get --name <property_name>
+
+ Set the property value
+ control.(sh|bat) --property set --name <property_name> --val <property_value>
+
By default commands affecting the cluster require interactive confirmation.
Use --yes option to disable it.
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DistributedSqlConfiguration.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DistributedSqlConfiguration.java
index c7b47eb..9636ae4 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DistributedSqlConfiguration.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DistributedSqlConfiguration.java
@@ -61,12 +61,16 @@ public class DistributedSqlConfiguration {
public static final int DFLT_QRY_TIMEOUT = 0;
/** Disabled SQL functions. */
- private final SimpleDistributedProperty<HashSet<String>> disabledSqlFuncs
- = new SimpleDistributedProperty<>("sql.disabledFunctions");
+ private final SimpleDistributedProperty<HashSet<String>> disabledSqlFuncs = new SimpleDistributedProperty<>(
+ "sql.disabledFunctions",
+ SimpleDistributedProperty::parseStringSet
+ );
/** Query timeout. */
- private final SimpleDistributedProperty<Integer> dfltQueryTimeout
- = new SimpleDistributedProperty<>("sql.defaultQueryTimeout");
+ private final SimpleDistributedProperty<Integer> dfltQueryTimeout = new SimpleDistributedProperty<>(
+ "sql.defaultQueryTimeout",
+ SimpleDistributedProperty::parseNonNegativeInteger
+ );
/**
* @param ctx Kernal context