Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/_docs/events/listening-to-events.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Ignite can generate events for a variety of operations happening in the cluster
The list of events is available in the link:events/events[Events] section.

== Enabling Events
By default, events are disabled, and you have to enable each event type explicitly if you want to use it in your application.
By default, almost all events are disabled (except for a few that are implicitly enabled because they are required by the system), and you have to enable each event type explicitly if you want to use it in your application.
To enable specific event types, list them in the `includeEventTypes` property of `IgniteConfiguration` as shown below:

[tabs]
Expand All @@ -45,6 +45,8 @@ include::code-snippets/dotnet/WorkingWithEvents.cs[tag=enablingEvents,indent=0]
tab:C++[unsupported]
--

Events can also be enabled/disabled in runtime by the link:tools/control-script[control utility].

== Getting the Events Interface

The events functionality is available through the events interface, which provides methods for listening to cluster events. The events interface can be obtained from an instance of `Ignite` as follows:
Expand Down
52 changes: 52 additions & 0 deletions docs/_docs/tools/control-script.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1628,3 +1628,55 @@ Parameters:
|--node-id | A list of nodes to rebuild indexes on. If not specified, schedules rebuild on all nodes.
|--cache-names | Comma-separated list of cache names, optionally with indexes. If indexes are not specified, all indexes of the cache will be scheduled for the rebuild operation. Can be used simultaneously with cache group names.
|--group-names | Comma-separated list of cache group names. Can be used simultaneously with cache names.


== Event management

The control utility provides commands to enable, disable and check the status of events on all server nodes.

=== Enable/disable events

To enable or disable events on all server nodes, use the `--event enable/disable` command.

[source, shell]
----
control.sh|bat --event enable|disable event1[,...,eventN]
----

Parameters:

[cols="1,3",opts="header"]
|===
| Parameter | Description
| `event1[,...,eventN]`| Specifies a comma-separated list of events to enable/disable.
|===

Examples:
[source, shell]
----
control.sh|bat --event enable EVT_CACHE_STARTED,EVT_CACHE_STOPPED
control.sh|bat --event disable EVT_CACHE_STARTED,EVT_CACHE_STOPPED
----

=== Events list and status

To get the list and status of available events, use the `--event list` command.

[source, shell]
----
control.sh|bat --event list [--enabled]
----

Parameters:

[cols="1,3",opts="header"]
|===
| Parameter | Description
| `--enabled`| List only enabled evente.
|===

Examples:
[source, shell]
----
control.sh|bat --event list --enabled
----
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
import org.apache.ignite.internal.management.encryption.EncryptionChangeCacheKeyCommand;
import org.apache.ignite.internal.management.encryption.EncryptionChangeMasterKeyCommand;
import org.apache.ignite.internal.management.encryption.EncryptionCommand;
import org.apache.ignite.internal.management.event.EventCommand;
import org.apache.ignite.internal.management.kill.KillCommand;
import org.apache.ignite.internal.management.meta.MetaCommand;
import org.apache.ignite.internal.management.meta.MetaRemoveCommand;
Expand Down Expand Up @@ -1401,6 +1402,7 @@ private boolean requireArgs(Class<?> cmd) {
cmd == DefragmentationCommand.class ||
cmd == PerformanceStatisticsCommand.class ||
cmd == ConsistencyCommand.class ||
cmd == CdcCommand.class;
cmd == CdcCommand.class ||
cmd == EventCommand.class;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.apache.ignite.util.GridCommandHandlerConsistencySensitiveTest;
import org.apache.ignite.util.GridCommandHandlerConsistencyTest;
import org.apache.ignite.util.GridCommandHandlerDefragmentationTest;
import org.apache.ignite.util.GridCommandHandlerEventTest;
import org.apache.ignite.util.GridCommandHandlerIndexForceRebuildTest;
import org.apache.ignite.util.GridCommandHandlerIndexListTest;
import org.apache.ignite.util.GridCommandHandlerIndexRebuildStatusTest;
Expand Down Expand Up @@ -60,6 +61,8 @@
GridCommandHandlerConsistencyBinaryTest.class,
GridCommandHandlerConsistencySensitiveTest.class,

GridCommandHandlerEventTest.class,

RollingUpgradeCommandTest.class,
SystemViewCommandTest.class,
MetricCommandTest.class,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
/*
* 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.security.Permissions;
import org.apache.ignite.Ignite;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.events.EventType;
import org.apache.ignite.internal.processors.security.impl.TestSecurityData;
import org.apache.ignite.internal.processors.security.impl.TestSecurityPluginProvider;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.G;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.junit.Test;

import static org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_OK;
import static org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_UNEXPECTED_ERROR;
import static org.apache.ignite.internal.commandline.SecurityCommandHandlerPermissionsTest.DEFAULT_PWD;
import static org.apache.ignite.internal.commandline.SecurityCommandHandlerPermissionsTest.TEST_NO_PERMISSIONS_LOGIN;
import static org.apache.ignite.internal.commandline.SecurityCommandHandlerPermissionsTest.enrichWithConnectionArguments;
import static org.apache.ignite.plugin.security.SecurityPermission.ADMIN_OPS;
import static org.apache.ignite.plugin.security.SecurityPermission.EVENTS_DISABLE;
import static org.apache.ignite.plugin.security.SecurityPermission.EVENTS_ENABLE;
import static org.apache.ignite.plugin.security.SecurityPermissionSetBuilder.ALL_PERMISSIONS;
import static org.apache.ignite.plugin.security.SecurityPermissionSetBuilder.NO_PERMISSIONS;
import static org.apache.ignite.plugin.security.SecurityPermissionSetBuilder.systemPermissions;
import static org.junit.Assume.assumeTrue;

/** */
public class GridCommandHandlerEventTest extends GridCommandHandlerAbstractTest {
/** */
private static final String LOGIN_EVT_ENABLE = "test_login_evt_enable";

/** */
private static final String LOGIN_EVT_DISABLE = "test_login_evt_disable";

/** */
private static final String LOGIN_EVT_STATUS = "test_login_evt_status";

/** */
@Override protected void afterTest() throws Exception {
super.afterTest();

stopAllGrids();
}

/** */
@Test
public void testEventEnableDIsable() throws Exception {
startGrids(2);
startClientGrid("client");

assertEvents(false, EventType.EVT_CACHE_STARTED, EventType.EVT_CACHE_STOPPED);

assertEquals(EXIT_CODE_OK, execute("--event", "enable", "EVT_CACHE_STARTED,EVT_CACHE_STOPPED"));

assertEvents(true, EventType.EVT_CACHE_STARTED, EventType.EVT_CACHE_STOPPED);

injectTestSystemOut();

assertEquals(EXIT_CODE_OK, execute("--event", "list", "--enabled"));

String out = testOut.toString();

assertTrue(out.contains("EVT_CACHE_STARTED"));
assertTrue(out.contains("EVT_CACHE_STOPPED"));

assertEquals(EXIT_CODE_OK, execute("--event", "disable", "EVT_CACHE_STARTED,EVT_CACHE_STOPPED"));

assertEvents(false, EventType.EVT_CACHE_STARTED, EventType.EVT_CACHE_STOPPED);
}

/** */
@Test
public void testDifferentSetOfEventsOnNodes() throws Exception {
startGrid(getConfiguration(getTestIgniteInstanceName(0))
.setIncludeEventTypes(EventType.EVT_TX_STARTED, EventType.EVT_CACHE_STARTED));

startGrid(getConfiguration(getTestIgniteInstanceName(1))
.setIncludeEventTypes(EventType.EVT_TX_STARTED, EventType.EVT_CACHE_STOPPED));

assertEvents(true, EventType.EVT_TX_STARTED, EventType.EVT_CACHE_STARTED);
assertEvents(false, EventType.EVT_CACHE_STOPPED);

injectTestSystemOut();

assertEquals(EXIT_CODE_OK, execute("--event", "list", "--enabled"));

String out = testOut.toString();

assertTrue(out.contains("EVT_TX_STARTED"));
assertTrue(out.contains("EVT_CACHE_STARTED"));
assertFalse(out.contains("EVT_CACHE_STOPPED"));

assertEquals(EXIT_CODE_OK, execute("--event", "disable", "EVT_TX_STARTED"));

startGrid(getConfiguration(getTestIgniteInstanceName(2))
.setIncludeEventTypes(EventType.EVT_TX_STARTED, EventType.EVT_CACHE_STOPPED));

assertEvents(true, EventType.EVT_CACHE_STARTED);
assertEvents(false, EventType.EVT_TX_STARTED, EventType.EVT_CACHE_STOPPED);

assertEquals(EXIT_CODE_OK, execute("--event", "list", "--enabled"));

out = testOut.toString();

assertFalse(out.contains("EVT_TX_STARTED"));
assertTrue(out.contains("EVT_CACHE_STARTED"));
assertFalse(out.contains("EVT_CACHE_STOPPED"));
}

/** */
@Test
public void testUnknownEvent() throws Exception {
startGrids(2);

assertEquals(EXIT_CODE_UNEXPECTED_ERROR, execute("--event", "enable", "EVT_NO_SUCH_EVENT"));
}

/** */
@Test
public void testEventList() throws Exception {
startGrids(2);

injectTestSystemOut();

assertEquals(EXIT_CODE_OK, execute("--event", "list"));

String out = testOut.toString();

for (String evt : U.gridEventNames().values())
assertTrue(out.contains("EVT_" + evt));
}

/** */
@Test
public void testEventWithSecurity() throws Exception {
assumeTrue(cliCommandHandler());

startGrid(getConfigurationWithSecurity(getTestIgniteInstanceName(0)));
startGrid(getConfigurationWithSecurity(getTestIgniteInstanceName(1)));

assertExecuteWithSecurity(LOGIN_EVT_ENABLE, "--event", "enable", "EVT_CACHE_STARTED,EVT_CACHE_STOPPED");

assertEvents(true, EventType.EVT_CACHE_STARTED, EventType.EVT_CACHE_STOPPED);

assertExecuteWithSecurity(LOGIN_EVT_STATUS, "--event", "list");

assertExecuteWithSecurity(LOGIN_EVT_DISABLE, "--event", "disable", "EVT_CACHE_STARTED,EVT_CACHE_STOPPED");

assertEvents(false, EventType.EVT_CACHE_STARTED, EventType.EVT_CACHE_STOPPED);
}

/** */
private IgniteConfiguration getConfigurationWithSecurity(String igniteInstanceName) throws Exception {
IgniteConfiguration cfg = getConfiguration(igniteInstanceName);

cfg.setPluginProviders(
new TestSecurityPluginProvider(
igniteInstanceName,
DEFAULT_PWD,
ALL_PERMISSIONS,
false,
new TestSecurityData(TEST_NO_PERMISSIONS_LOGIN, DEFAULT_PWD, NO_PERMISSIONS, new Permissions()),
new TestSecurityData(LOGIN_EVT_ENABLE, DEFAULT_PWD, systemPermissions(EVENTS_ENABLE), new Permissions()),
new TestSecurityData(LOGIN_EVT_DISABLE, DEFAULT_PWD, systemPermissions(EVENTS_DISABLE), new Permissions()),
new TestSecurityData(LOGIN_EVT_STATUS, DEFAULT_PWD, systemPermissions(ADMIN_OPS), new Permissions()))
);

return cfg;
}

/** */
private void assertExecuteWithSecurity(String allowedLogin, String... cmdArgs) {
assertEquals(EXIT_CODE_UNEXPECTED_ERROR, execute(enrichWithConnectionArguments(F.asList(cmdArgs),
TEST_NO_PERMISSIONS_LOGIN)));

assertEquals(EXIT_CODE_OK, execute(enrichWithConnectionArguments(F.asList(cmdArgs), allowedLogin)));
}

/** */
private void assertEvents(boolean enabled, int... evts) {
for (Ignite ignite : G.allGrids()) {
if (ignite.configuration().isClientMode())
continue;

for (int i = 0; i < evts.length; i++)
assertEquals(enabled, ignite.events().isEnabled(evts[i]));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@ enum DiscoveryDataExchangeType {
META_STORAGE,

/** Performance statistics processor. */
PERFORMANCE_STAT_PROC;
PERFORMANCE_STAT_PROC,

/** Event storage manager. */
EVENT_MGR;

/** Cached values array. */
public static final DiscoveryDataExchangeType[] VALUES = values();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.apache.ignite.internal.management.defragmentation.DefragmentationCommand;
import org.apache.ignite.internal.management.diagnostic.DiagnosticCommand;
import org.apache.ignite.internal.management.encryption.EncryptionCommand;
import org.apache.ignite.internal.management.event.EventCommand;
import org.apache.ignite.internal.management.kill.KillCommand;
import org.apache.ignite.internal.management.meta.MetaCommand;
import org.apache.ignite.internal.management.metric.MetricCommand;
Expand Down Expand Up @@ -77,7 +78,8 @@ public IgniteCommandRegistry() {
new DefragmentationCommand(),
new PerformanceStatisticsCommand(),
new CdcCommand(),
new ConsistencyCommand()
new ConsistencyCommand(),
new EventCommand()
);

U.loadService(CommandsProvider.class).forEach(p -> p.commands().forEach(this::register));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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.management.event;

import org.apache.ignite.internal.management.api.CommandRegistryImpl;
import org.apache.ignite.internal.management.api.NoArg;

/** Command to enable/disable events. */
public class EventCommand extends CommandRegistryImpl<NoArg, Void> {
/** */
public EventCommand() {
super(
new EventEnableCommand(),
new EventDisableCommand(),
new EventListCommand()
);
}
}
Loading
Loading