[ https://issues.apache.org/jira/browse/IGNITE-23958?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Mikhail Petrov updated IGNITE-23958: ------------------------------------ Description: Reproducer: {code:java} /* * 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; import java.security.Permissions; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.apache.ignite.client.IgniteClient; import org.apache.ignite.client.IgniteClientFuture; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.configuration.ClientConfiguration; import org.apache.ignite.configuration.ClientConnectorConfiguration; import org.apache.ignite.configuration.DataRegionConfiguration; import org.apache.ignite.configuration.DataStorageConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.configuration.ThinClientConfiguration; import org.apache.ignite.internal.IgniteEx; import org.apache.ignite.internal.IgniteInternalFuture; import org.apache.ignite.internal.events.DiscoveryCustomEvent; import org.apache.ignite.internal.management.snapshot.SnapshotCreateCommandArg; import org.apache.ignite.internal.management.snapshot.SnapshotCreateTask; import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage; import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture; import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.PartitionsExchangeAware; import org.apache.ignite.internal.processors.cache.persistence.snapshot.SnapshotDiscoveryMessage; 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.internal.U; import org.apache.ignite.internal.visor.VisorTaskArgument; import org.apache.ignite.internal.visor.VisorTaskResult; import org.apache.ignite.plugin.security.SecurityPermissionSet; import org.apache.ignite.testframework.GridTestUtils; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; import org.junit.Test; import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL; import static org.apache.ignite.cluster.ClusterState.ACTIVE; import static org.apache.ignite.internal.events.DiscoveryCustomEvent.EVT_DISCOVERY_CUSTOM_EVT; import static org.apache.ignite.plugin.security.SecurityPermission.ADMIN_CLUSTER_STATE; import static org.apache.ignite.plugin.security.SecurityPermission.ADMIN_SNAPSHOT; import static org.apache.ignite.plugin.security.SecurityPermission.CACHE_CREATE; import static org.apache.ignite.plugin.security.SecurityPermission.CACHE_PUT; import static org.apache.ignite.plugin.security.SecurityPermission.CACHE_READ; import static org.apache.ignite.plugin.security.SecurityPermission.JOIN_AS_SERVER; import static org.apache.ignite.plugin.security.SecurityPermissionSetBuilder.create; import static org.apache.ignite.plugin.security.SecurityPermissionSetBuilder.systemPermissions; /** */ public class TransactionsHangingTest extends GridCommonAbstractTest { /** {@inheritDoc} */ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); cfg.setDataStorageConfiguration(new DataStorageConfiguration() .setDefaultDataRegionConfiguration(new DataRegionConfiguration() .setPersistenceEnabled(true))); cfg.setClientConnectorConfiguration(new ClientConnectorConfiguration() .setThreadPoolSize(2) // first thread is occupied by snapshot operation, the second is designated to perform cache operations. .setThinClientConfiguration(new ThinClientConfiguration() .setMaxActiveComputeTasksPerConnection(1))); cfg.setPluginProviders(new TestSecurityPluginProvider( igniteInstanceName, "", create() .defaultAllowAll(false) .appendSystemPermissions(JOIN_AS_SERVER, ADMIN_CLUSTER_STATE) .appendCachePermissions(DEFAULT_CACHE_NAME, CACHE_CREATE) .build(), null, false, userData("admin-snapshot", systemPermissions(ADMIN_SNAPSHOT)), userData("client", create() .defaultAllowAll(false) .appendCachePermissions(DEFAULT_CACHE_NAME, CACHE_READ, CACHE_PUT) .build()) )); return cfg; } /** {@inheritDoc} */ @Override protected void beforeTest() throws Exception { super.beforeTest(); cleanPersistenceDir(); } /** {@inheritDoc} */ @Override protected void afterTest() throws Exception { super.afterTest(); stopAllGrids(); cleanPersistenceDir(); } /** */ @Test public void test() throws Exception { IgniteEx ignite = startGrid(0); ignite.cluster().state(ACTIVE); ignite.createCache(new CacheConfiguration<>().setName(DEFAULT_CACHE_NAME).setAtomicityMode(TRANSACTIONAL)); CountDownLatch snapshotBlockedLatch = new CountDownLatch(1); CountDownLatch snapshotUnblockedLatch = new CountDownLatch(1); ignite.context().cache().context().exchange().registerExchangeAwareComponent(new PartitionsExchangeAware() { /** {@inheritDoc} */ @Override public void onInitAfterTopologyLock(GridDhtPartitionsExchangeFuture fut) { if (fut.firstEvent().type() != EVT_DISCOVERY_CUSTOM_EVT) return; DiscoveryCustomMessage msg = ((DiscoveryCustomEvent)fut.firstEvent()).customMessage(); assertNotNull(msg); if (msg instanceof SnapshotDiscoveryMessage) { snapshotBlockedLatch.countDown(); try { snapshotUnblockedLatch.await(getTestTimeout(), TimeUnit.MILLISECONDS); } catch (InterruptedException e) { throw new IgniteException(e); } } } }); try ( IgniteClient snpAdmin = Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:10800").setUserName("admin-snapshot").setUserPassword("")); IgniteClient cli = Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:10800").setUserName("client").setUserPassword("")) ) { SnapshotCreateCommandArg arg = new SnapshotCreateCommandArg(); arg.snapshotName("test_snapshot"); arg.sync(true); IgniteClientFuture<VisorTaskResult<String>> snpFut = snpAdmin.compute().<VisorTaskArgument<?>, VisorTaskResult<String>>executeAsync2( SnapshotCreateTask.class.getName(), new VisorTaskArgument<>( grid(0).localNode().id(), arg, false) ); assertTrue(snapshotBlockedLatch.await(getTestTimeout(), TimeUnit.MILLISECONDS)); IgniteInternalFuture<Object> putFut0 = GridTestUtils.runAsync(() -> cli.cache(DEFAULT_CACHE_NAME).put(0, 0)); IgniteInternalFuture<Object> putFut1 = GridTestUtils.runAsync(() -> cli.cache(DEFAULT_CACHE_NAME).put(1, 1)); U.sleep(1000); // Wait for tx requests chaining. snapshotUnblockedLatch.countDown(); snpFut.get(getTestTimeout(), TimeUnit.MILLISECONDS); putFut0.get(getTestTimeout()); putFut1.get(getTestTimeout()); // Will hang. } } /** */ private TestSecurityData userData(String login, SecurityPermissionSet perms) { return new TestSecurityData( login, "", perms, new Permissions() ); } } {code} Summary: Fix security context propagation for async transactional operations (was: Fix security context switch for Ignite Internal Future listeners) > Fix security context propagation for async transactional operations > ------------------------------------------------------------------- > > Key: IGNITE-23958 > URL: https://issues.apache.org/jira/browse/IGNITE-23958 > Project: Ignite > Issue Type: Bug > Reporter: Mikhail Petrov > Assignee: Mikhail Petrov > Priority: Blocker > Labels: ise > Fix For: 2.17 > > Time Spent: 40m > Remaining Estimate: 0h > > Reproducer: > {code:java} > /* > * 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; > import java.security.Permissions; > import java.util.concurrent.CountDownLatch; > import java.util.concurrent.TimeUnit; > import org.apache.ignite.client.IgniteClient; > import org.apache.ignite.client.IgniteClientFuture; > import org.apache.ignite.configuration.CacheConfiguration; > import org.apache.ignite.configuration.ClientConfiguration; > import org.apache.ignite.configuration.ClientConnectorConfiguration; > import org.apache.ignite.configuration.DataRegionConfiguration; > import org.apache.ignite.configuration.DataStorageConfiguration; > import org.apache.ignite.configuration.IgniteConfiguration; > import org.apache.ignite.configuration.ThinClientConfiguration; > import org.apache.ignite.internal.IgniteEx; > import org.apache.ignite.internal.IgniteInternalFuture; > import org.apache.ignite.internal.events.DiscoveryCustomEvent; > import > org.apache.ignite.internal.management.snapshot.SnapshotCreateCommandArg; > import org.apache.ignite.internal.management.snapshot.SnapshotCreateTask; > import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage; > import > org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture; > import > org.apache.ignite.internal.processors.cache.distributed.dht.preloader.PartitionsExchangeAware; > import > org.apache.ignite.internal.processors.cache.persistence.snapshot.SnapshotDiscoveryMessage; > 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.internal.U; > import org.apache.ignite.internal.visor.VisorTaskArgument; > import org.apache.ignite.internal.visor.VisorTaskResult; > import org.apache.ignite.plugin.security.SecurityPermissionSet; > import org.apache.ignite.testframework.GridTestUtils; > import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; > import org.junit.Test; > import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL; > import static org.apache.ignite.cluster.ClusterState.ACTIVE; > import static > org.apache.ignite.internal.events.DiscoveryCustomEvent.EVT_DISCOVERY_CUSTOM_EVT; > import static > org.apache.ignite.plugin.security.SecurityPermission.ADMIN_CLUSTER_STATE; > import static > org.apache.ignite.plugin.security.SecurityPermission.ADMIN_SNAPSHOT; > import static > org.apache.ignite.plugin.security.SecurityPermission.CACHE_CREATE; > import static org.apache.ignite.plugin.security.SecurityPermission.CACHE_PUT; > import static org.apache.ignite.plugin.security.SecurityPermission.CACHE_READ; > import static > org.apache.ignite.plugin.security.SecurityPermission.JOIN_AS_SERVER; > import static > org.apache.ignite.plugin.security.SecurityPermissionSetBuilder.create; > import static > org.apache.ignite.plugin.security.SecurityPermissionSetBuilder.systemPermissions; > /** */ > public class TransactionsHangingTest extends GridCommonAbstractTest { > /** {@inheritDoc} */ > @Override protected IgniteConfiguration getConfiguration(String > igniteInstanceName) throws Exception { > IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); > cfg.setDataStorageConfiguration(new DataStorageConfiguration() > .setDefaultDataRegionConfiguration(new DataRegionConfiguration() > .setPersistenceEnabled(true))); > cfg.setClientConnectorConfiguration(new ClientConnectorConfiguration() > .setThreadPoolSize(2) // first thread is occupied by snapshot > operation, the second is designated to perform cache operations. > .setThinClientConfiguration(new ThinClientConfiguration() > .setMaxActiveComputeTasksPerConnection(1))); > cfg.setPluginProviders(new TestSecurityPluginProvider( > igniteInstanceName, > "", > create() > .defaultAllowAll(false) > .appendSystemPermissions(JOIN_AS_SERVER, ADMIN_CLUSTER_STATE) > .appendCachePermissions(DEFAULT_CACHE_NAME, CACHE_CREATE) > .build(), > null, > false, > userData("admin-snapshot", systemPermissions(ADMIN_SNAPSHOT)), > userData("client", create() > .defaultAllowAll(false) > .appendCachePermissions(DEFAULT_CACHE_NAME, CACHE_READ, > CACHE_PUT) > .build()) > )); > return cfg; > } > /** {@inheritDoc} */ > @Override protected void beforeTest() throws Exception { > super.beforeTest(); > cleanPersistenceDir(); > } > /** {@inheritDoc} */ > @Override protected void afterTest() throws Exception { > super.afterTest(); > stopAllGrids(); > cleanPersistenceDir(); > } > /** */ > @Test > public void test() throws Exception { > IgniteEx ignite = startGrid(0); > ignite.cluster().state(ACTIVE); > ignite.createCache(new > CacheConfiguration<>().setName(DEFAULT_CACHE_NAME).setAtomicityMode(TRANSACTIONAL)); > CountDownLatch snapshotBlockedLatch = new CountDownLatch(1); > CountDownLatch snapshotUnblockedLatch = new CountDownLatch(1); > > ignite.context().cache().context().exchange().registerExchangeAwareComponent(new > PartitionsExchangeAware() { > /** {@inheritDoc} */ > @Override public void > onInitAfterTopologyLock(GridDhtPartitionsExchangeFuture fut) { > if (fut.firstEvent().type() != EVT_DISCOVERY_CUSTOM_EVT) > return; > DiscoveryCustomMessage msg = > ((DiscoveryCustomEvent)fut.firstEvent()).customMessage(); > assertNotNull(msg); > if (msg instanceof SnapshotDiscoveryMessage) { > snapshotBlockedLatch.countDown(); > try { > snapshotUnblockedLatch.await(getTestTimeout(), > TimeUnit.MILLISECONDS); > } > catch (InterruptedException e) { > throw new IgniteException(e); > } > } > } > }); > try ( > IgniteClient snpAdmin = Ignition.startClient(new > ClientConfiguration().setAddresses("127.0.0.1:10800").setUserName("admin-snapshot").setUserPassword("")); > IgniteClient cli = Ignition.startClient(new > ClientConfiguration().setAddresses("127.0.0.1:10800").setUserName("client").setUserPassword("")) > ) { > SnapshotCreateCommandArg arg = new SnapshotCreateCommandArg(); > arg.snapshotName("test_snapshot"); > arg.sync(true); > IgniteClientFuture<VisorTaskResult<String>> snpFut = > snpAdmin.compute().<VisorTaskArgument<?>, > VisorTaskResult<String>>executeAsync2( > SnapshotCreateTask.class.getName(), > new VisorTaskArgument<>( > grid(0).localNode().id(), > arg, > false) > ); > assertTrue(snapshotBlockedLatch.await(getTestTimeout(), > TimeUnit.MILLISECONDS)); > IgniteInternalFuture<Object> putFut0 = GridTestUtils.runAsync(() > -> cli.cache(DEFAULT_CACHE_NAME).put(0, 0)); > IgniteInternalFuture<Object> putFut1 = GridTestUtils.runAsync(() > -> cli.cache(DEFAULT_CACHE_NAME).put(1, 1)); > U.sleep(1000); // Wait for tx requests chaining. > snapshotUnblockedLatch.countDown(); > snpFut.get(getTestTimeout(), TimeUnit.MILLISECONDS); > putFut0.get(getTestTimeout()); > putFut1.get(getTestTimeout()); // Will hang. > } > } > /** */ > private TestSecurityData userData(String login, SecurityPermissionSet > perms) { > return new TestSecurityData( > login, > "", > perms, > new Permissions() > ); > } > } > {code} -- This message was sent by Atlassian Jira (v8.20.10#820010)