From 1740273da20568067a1a524dab000c79f8068d3d Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 11 Jun 2026 12:23:26 +0300 Subject: [PATCH 01/47] impl --- .../internal/managers/communication/UnknownMessageException.java | 0 .../apache/ignite/plugin/extensions/communication/Message.java | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename modules/{core => commons}/src/main/java/org/apache/ignite/internal/managers/communication/UnknownMessageException.java (100%) rename modules/{core => commons}/src/main/java/org/apache/ignite/plugin/extensions/communication/Message.java (100%) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/UnknownMessageException.java b/modules/commons/src/main/java/org/apache/ignite/internal/managers/communication/UnknownMessageException.java similarity index 100% rename from modules/core/src/main/java/org/apache/ignite/internal/managers/communication/UnknownMessageException.java rename to modules/commons/src/main/java/org/apache/ignite/internal/managers/communication/UnknownMessageException.java diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/Message.java b/modules/commons/src/main/java/org/apache/ignite/plugin/extensions/communication/Message.java similarity index 100% rename from modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/Message.java rename to modules/commons/src/main/java/org/apache/ignite/plugin/extensions/communication/Message.java From baa147367a3876e08e30661b87fa6251cdd61290 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Fri, 12 Jun 2026 12:43:24 +0300 Subject: [PATCH 02/47] in-progress --- ...utedOperationContextAttributeRegistry.java | 83 +++++++++++++++++++ .../thread/context/OperationContext.java | 2 +- .../context/OperationContextAttribute.java | 1 + .../ignite/spi/discovery/tcp/ClientImpl.java | 14 +++- .../ignite/spi/discovery/tcp/ServerImpl.java | 26 ++++-- .../messages/InetSocketAddressMessage.java | 1 - .../messages/TcpDiscoveryAbstractMessage.java | 6 ++ .../OperationContextAttributesTest.java | 76 ++++++++++++++++- 8 files changed, 199 insertions(+), 10 deletions(-) create mode 100644 modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java new file mode 100644 index 0000000000000..93c4ddb621c34 --- /dev/null +++ b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java @@ -0,0 +1,83 @@ +/* + * 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.thread.context; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import org.apache.ignite.IgniteException; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.plugin.extensions.communication.Message; +import org.jetbrains.annotations.Nullable; + +/** */ +public class DistributedOperationContextAttributeRegistry { + /** */ + private static final DistributedOperationContextAttributeRegistry INSTANCE = new DistributedOperationContextAttributeRegistry(); + + /** Attributes by their id. */ + private final Map> attributes = new ConcurrentHashMap<>(); + + /** */ + public static DistributedOperationContextAttributeRegistry instance() { + return INSTANCE; + } + + /** */ + public void register(byte id, OperationContextAttribute attr) { + assert id >= 0; + + if(attributes.size() == OperationContextAttribute.MAX_ATTR_CNT) + throw new IgniteException("Maximum number of attributes is exceeded [" + OperationContextAttribute.MAX_ATTR_CNT + "]."); + + if (attributes.putIfAbsent(id, attr) != null) + throw new IgniteException("Duplicated attribute id: " + id); + } + + /** @return Values for all registered operation context attributes. */ + public @Nullable Map collectContext() { + Map res = null; + + for (Map.Entry> e : attributes.entrySet()) { + OperationContextAttribute attr = e.getValue(); + + Message curVal = OperationContext.get(attr); + + if (!Objects.equals(attr.initialValue(), curVal)) { + if (res == null) + res = new HashMap<>(attributes.size(), 1.0f); + + res.put(e.getKey(), curVal); + } + } + + return res; + } + + /** */ + public Scope restoreContext(Map res) { + if (F.isEmpty(res)) + return Scope.NOOP_SCOPE; + + OperationContext.ContextUpdater updater = OperationContext.ContextUpdater.create(); + + res.forEach((id, attr) -> updater.set((OperationContextAttribute)attributes.get(id), attr)); + + return updater.apply(); + } +} diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContext.java b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContext.java index 6953d8b853891..4a8f556781cf7 100644 --- a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContext.java +++ b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContext.java @@ -322,7 +322,7 @@ private static class AttributeValueHolder { } /** Allows to change multiple attribute values in a single update operation and skip updates that changes nothing. */ - private static class ContextUpdater { + static class ContextUpdater { /** */ private static final int INIT_UPDATES_CAPACITY = 3; diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java index 499d241d9ccba..f5f20066a3d2f 100644 --- a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java +++ b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java @@ -18,6 +18,7 @@ package org.apache.ignite.internal.thread.context; import java.util.concurrent.atomic.AtomicInteger; +import org.apache.ignite.plugin.extensions.communication.Message; import org.jetbrains.annotations.Nullable; /** diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index a0e1a20048786..3476ba8785843 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -70,6 +70,8 @@ import org.apache.ignite.internal.processors.tracing.messages.SpanContainer; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessage; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessagesTable; +import org.apache.ignite.internal.thread.context.DistributedOperationContextAttributeRegistry; +import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.internal.util.future.GridFutureAdapter; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.typedef.F; @@ -1310,6 +1312,8 @@ private class SocketWriter extends IgniteSpiThread { * @param msg Message. */ private void sendMessage(TcpDiscoveryAbstractMessage msg) { + msg.opCtxAttrs = DistributedOperationContextAttributeRegistry.instance().collectContext(); + synchronized (mux) { queue.add(msg); @@ -2001,7 +2005,15 @@ else if (discoMsg instanceof TcpDiscoveryCheckFailedMessage) } } - processDiscoveryMessage((TcpDiscoveryAbstractMessage)msg); + TcpDiscoveryAbstractMessage msg0 = (TcpDiscoveryAbstractMessage)msg; + + if (F.isEmpty(msg0.opCtxAttrs)) + processDiscoveryMessage(msg0); + else { + try (Scope ignored = DistributedOperationContextAttributeRegistry.instance().restoreContext(msg0.opCtxAttrs)) { + processDiscoveryMessage(msg0); + } + } } } } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index 82c012c2a1a94..a32bf95fd1bc5 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -95,6 +95,8 @@ import org.apache.ignite.internal.processors.tracing.messages.SpanContainer; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessage; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessagesTable; +import org.apache.ignite.internal.thread.context.DistributedOperationContextAttributeRegistry; +import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.internal.thread.pool.IgniteThreadPoolExecutor; import org.apache.ignite.internal.util.GridBoundedLinkedHashSet; import org.apache.ignite.internal.util.GridConcurrentHashSet; @@ -3046,6 +3048,9 @@ void addMessage(TcpDiscoveryAbstractMessage msg, boolean ignoreHighPriority, boo return; } + if (!fromSocket) + msg.opCtxAttrs = DistributedOperationContextAttributeRegistry.instance().collectContext(); + if (msg instanceof TraceableMessage) { TraceableMessage tMsg = (TraceableMessage)msg; @@ -3173,11 +3178,8 @@ protected void runTasks() { task.run(); } - /** {@inheritDoc} */ - @Override protected void processMessage(TcpDiscoveryAbstractMessage msg) { - if (msg == WAKEUP) - return; - + /** */ + private void processMessage0(TcpDiscoveryAbstractMessage msg) { notifiedDiscovery.set(false); if (msg instanceof TraceableMessage) { @@ -3315,6 +3317,20 @@ else if (msg instanceof TcpDiscoveryAuthFailedMessage) } } + /** {@inheritDoc} */ + @Override protected void processMessage(TcpDiscoveryAbstractMessage msg) { + if (msg == WAKEUP) + return; + + if (F.isEmpty(msg.opCtxAttrs)) + processMessage0(msg); + else { + try (Scope ignored = DistributedOperationContextAttributeRegistry.instance().restoreContext(msg.opCtxAttrs)) { + processMessage0(msg); + } + } + } + /** * Processes authentication failed message. * diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/InetSocketAddressMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/InetSocketAddressMessage.java index f23e36f200d27..d76279fb28082 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/InetSocketAddressMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/InetSocketAddressMessage.java @@ -52,7 +52,6 @@ public int port() { return port; } - /** {@inheritDoc} */ @Override public String toString() { return S.toString(InetSocketAddressMessage.class, this); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java index 7a97763c36b25..e04f1d856c0ec 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java @@ -19,6 +19,7 @@ import java.io.Externalizable; import java.util.HashSet; +import java.util.Map; import java.util.Set; import java.util.UUID; import org.apache.ignite.internal.Order; @@ -76,6 +77,11 @@ public abstract class TcpDiscoveryAbstractMessage implements Message { @Order(4) Set failedNodes; + /** Operation context attributes: id -> attribute value. */ + @GridToStringInclude + @Order(5) + public @Nullable Map opCtxAttrs; + /** * Default no-arg constructor for {@link Externalizable} interface. */ diff --git a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java index 9de906b27290c..e6454be489cc7 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java @@ -17,6 +17,7 @@ package org.apache.ignite.internal.thread.context; +import java.net.InetAddress; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; @@ -35,9 +36,17 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; +import org.apache.ignite.Ignite; import org.apache.ignite.IgniteException; +import org.apache.ignite.cluster.ClusterNode; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.events.Event; +import org.apache.ignite.internal.IgniteEx; import org.apache.ignite.internal.IgniteInternalFuture; import org.apache.ignite.internal.managers.communication.GridIoPolicy; +import org.apache.ignite.internal.managers.discovery.CustomEventListener; +import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.DynamicCacheChangeBatch; import org.apache.ignite.internal.processors.timeout.GridTimeoutObject; import org.apache.ignite.internal.processors.timeout.GridTimeoutProcessor; import org.apache.ignite.internal.thread.context.concurrent.IgniteCompletableFuture; @@ -48,20 +57,24 @@ import org.apache.ignite.internal.thread.pool.IgniteStripedThreadPoolExecutor; import org.apache.ignite.internal.thread.pool.IgniteThreadPoolExecutor; import org.apache.ignite.internal.util.future.GridFutureAdapter; +import org.apache.ignite.internal.util.typedef.G; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.internal.util.worker.queue.IgniteAsyncObjectHandler; import org.apache.ignite.internal.util.worker.queue.IgniteDelayedObjectHandler; import org.apache.ignite.lang.IgniteClosure; import org.apache.ignite.lang.IgniteInClosure; import org.apache.ignite.lang.IgniteOutClosure; +import org.apache.ignite.lang.IgnitePredicate; import org.apache.ignite.lang.IgniteRunnable; import org.apache.ignite.lang.IgniteUuid; +import org.apache.ignite.spi.discovery.tcp.messages.InetSocketAddressMessage; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; import org.apache.ignite.thread.IgniteThread; import org.junit.Test; import org.springframework.lang.NonNull; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.apache.ignite.internal.events.DiscoveryCustomEvent.EVT_DISCOVERY_CUSTOM_EVT; import static org.apache.ignite.testframework.GridTestUtils.assertThrowsAnyCause; import static org.apache.ignite.testframework.GridTestUtils.assertThrowsWithCause; @@ -85,6 +98,9 @@ public class OperationContextAttributesTest extends GridCommonAbstractTest { /** */ private int beforeTestReservedAttrIds; + /** */ + private IgnitePredicate evtLsnr; + /** {@inheritDoc} */ @Override protected void beforeTest() throws Exception { super.beforeTest(); @@ -98,6 +114,8 @@ public class OperationContextAttributesTest extends GridCommonAbstractTest { @Override protected void afterTest() throws Exception { super.afterTest(); + stopAllGrids(); + if (poolToShutdownAfterTest != null) poolToShutdownAfterTest.shutdownNow(); @@ -105,6 +123,16 @@ public class OperationContextAttributesTest extends GridCommonAbstractTest { OperationContextAttribute.ID_GEN.set(beforeTestReservedAttrIds); } + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); + + if (evtLsnr != null) + cfg.setLocalEventListeners(Collections.singletonMap(evtLsnr, new int[] {EVT_DISCOVERY_CUSTOM_EVT})); + + return cfg; + } + /** */ @Test public void testNotAttachedAttribute() { @@ -808,6 +836,51 @@ public void testContextAwareDelayQueue() throws Exception { } } + /** */ + @Test + public void testSendAttributesByDiscovery() throws Exception { + byte attrId = (byte)(OperationContextAttribute.MAX_ATTR_CNT + 1); + + InetSocketAddressMessage dfltAttrVal = new InetSocketAddressMessage(InetAddress.getLoopbackAddress(), 80); + + OperationContextAttribute attr = OperationContextAttribute.newInstance(); + + DistributedOperationContextAttributeRegistry.instance().register(attrId, attr); + + startGrids(2); + Ignite cli = startClientGrid(); + + CountDownLatch clientLatch = new CountDownLatch(1); + CountDownLatch srvrLatch = new CountDownLatch(1); + + for (int i = 1; i < G.allGrids().size(); ++i) { + int i0 = i; + + grid(i).context().discovery().setCustomEventListener( + DynamicCacheChangeBatch.class, new CustomEventListener<>() { + @Override public void onCustomEvent(AffinityTopologyVersion topVer, ClusterNode snd, + DynamicCacheChangeBatch msg) { + + if (grid(i0).localNode().isClient()) + clientLatch.countDown(); + else + srvrLatch.countDown(); + } + }); + } + + InetSocketAddressMessage newAttrVal = new InetSocketAddressMessage(dfltAttrVal.address(), 443); + + assertFalse(newAttrVal.equals(dfltAttrVal)); + + try (Scope ignored = OperationContext.set(attr, newAttrVal)) { + grid(0).createCache(defaultCacheConfiguration()); + } + + assertTrue(clientLatch.await(getTestTimeout(), TimeUnit.MILLISECONDS)); + assertTrue(srvrLatch.await(getTestTimeout(), TimeUnit.MILLISECONDS)); + } + /** */ private void doContextAwareExecutorServiceTest(ExecutorService pool) throws Exception { CountDownLatch poolUnblockedLatch = blockPool(pool); @@ -923,9 +996,8 @@ public AttributeValueChecker(String expStrAttrVal, Integer expIntAttrVal) { /** */ static void assertAllCreatedChecksPassed() throws Exception { - for (AttributeValueChecker check : CHECKS) { + for (AttributeValueChecker check : CHECKS) check.get(5_000, MILLISECONDS); - } } /** */ From 9f8e09d8a01167e5b8bb7a6b576353850cc792a4 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Sun, 14 Jun 2026 20:39:02 +0300 Subject: [PATCH 03/47] raw --- ...utedOperationContextAttributeRegistry.java | 2 +- .../context/OperationContextAttribute.java | 1 - .../OperationContextAttributesTest.java | 59 +++++++++++++++---- 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java index 93c4ddb621c34..4d9e9c0fd6698 100644 --- a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java +++ b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java @@ -42,7 +42,7 @@ public static DistributedOperationContextAttributeRegistry instance() { public void register(byte id, OperationContextAttribute attr) { assert id >= 0; - if(attributes.size() == OperationContextAttribute.MAX_ATTR_CNT) + if (attributes.size() == OperationContextAttribute.MAX_ATTR_CNT) throw new IgniteException("Maximum number of attributes is exceeded [" + OperationContextAttribute.MAX_ATTR_CNT + "]."); if (attributes.putIfAbsent(id, attr) != null) diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java index f5f20066a3d2f..499d241d9ccba 100644 --- a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java +++ b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java @@ -18,7 +18,6 @@ package org.apache.ignite.internal.thread.context; import java.util.concurrent.atomic.AtomicInteger; -import org.apache.ignite.plugin.extensions.communication.Message; import org.jetbrains.annotations.Nullable; /** diff --git a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java index e6454be489cc7..e82721c10b114 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java @@ -36,12 +36,10 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; -import org.apache.ignite.Ignite; import org.apache.ignite.IgniteException; import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.events.Event; -import org.apache.ignite.internal.IgniteEx; import org.apache.ignite.internal.IgniteInternalFuture; import org.apache.ignite.internal.managers.communication.GridIoPolicy; import org.apache.ignite.internal.managers.discovery.CustomEventListener; @@ -77,6 +75,7 @@ import static org.apache.ignite.internal.events.DiscoveryCustomEvent.EVT_DISCOVERY_CUSTOM_EVT; import static org.apache.ignite.testframework.GridTestUtils.assertThrowsAnyCause; import static org.apache.ignite.testframework.GridTestUtils.assertThrowsWithCause; +import static org.apache.ignite.testframework.GridTestUtils.waitForCondition; /** */ public class OperationContextAttributesTest extends GridCommonAbstractTest { @@ -848,12 +847,15 @@ public void testSendAttributesByDiscovery() throws Exception { DistributedOperationContextAttributeRegistry.instance().register(attrId, attr); startGrids(2); - Ignite cli = startClientGrid(); + startClientGrid(2); - CountDownLatch clientLatch = new CountDownLatch(1); - CountDownLatch srvrLatch = new CountDownLatch(1); + CountDownLatch coordLatch = new CountDownLatch(3); + CountDownLatch srvrLatch = new CountDownLatch(3); + CountDownLatch clientLatch = new CountDownLatch(3); - for (int i = 1; i < G.allGrids().size(); ++i) { + InetSocketAddressMessage valToSend = new InetSocketAddressMessage(dfltAttrVal.address(), 443); + + for (int i = 0; i < G.allGrids().size(); ++i) { int i0 = i; grid(i).context().discovery().setCustomEventListener( @@ -861,24 +863,61 @@ public void testSendAttributesByDiscovery() throws Exception { @Override public void onCustomEvent(AffinityTopologyVersion topVer, ClusterNode snd, DynamicCacheChangeBatch msg) { + InetSocketAddressMessage receivedVal = OperationContext.get(attr); + + assertNotNull(receivedVal); + + assertFalse(dfltAttrVal.port() == receivedVal.port()); + + assertEquals(receivedVal.port(), valToSend.port()); + assertEquals(receivedVal.address(), valToSend.address()); + if (grid(i0).localNode().isClient()) clientLatch.countDown(); + else if (grid(i0).localNode().order() == 1) + coordLatch.countDown(); else srvrLatch.countDown(); } }); } - InetSocketAddressMessage newAttrVal = new InetSocketAddressMessage(dfltAttrVal.address(), 443); + assertFalse(valToSend.equals(dfltAttrVal)); - assertFalse(newAttrVal.equals(dfltAttrVal)); + assertNull(OperationContext.get(attr)); - try (Scope ignored = OperationContext.set(attr, newAttrVal)) { + // Send from a coordinator. + try (Scope ignored = OperationContext.set(attr, valToSend)) { grid(0).createCache(defaultCacheConfiguration()); } - assertTrue(clientLatch.await(getTestTimeout(), TimeUnit.MILLISECONDS)); + assertTrue(waitForCondition(() -> coordLatch.getCount() == 2, getTestTimeout())); + assertTrue(waitForCondition(() -> srvrLatch.getCount() == 2, getTestTimeout())); + assertTrue(waitForCondition(() -> clientLatch.getCount() == 2, getTestTimeout())); + + assertNull(OperationContext.get(attr)); + + // Send from a server. + try (Scope ignored = OperationContext.set(attr, valToSend)) { + grid(1).destroyCache(DEFAULT_CACHE_NAME); + } + + assertTrue(waitForCondition(() -> coordLatch.getCount() == 1, getTestTimeout())); + assertTrue(waitForCondition(() -> srvrLatch.getCount() == 1, getTestTimeout())); + assertTrue(waitForCondition(() -> clientLatch.getCount() == 1, getTestTimeout())); + + assertNull(OperationContext.get(attr)); + + // Send from a client. + try (Scope ignored = OperationContext.set(attr, valToSend)) { + grid(2).createCache(defaultCacheConfiguration()); + } + + assertNull(OperationContext.get(attr)); + + assertTrue(coordLatch.await(getTestTimeout(), TimeUnit.MILLISECONDS)); assertTrue(srvrLatch.await(getTestTimeout(), TimeUnit.MILLISECONDS)); + assertTrue(clientLatch.await(getTestTimeout(), TimeUnit.MILLISECONDS)); } /** */ From 9f4ccecbea9382da2a1da57cd5d595d6c9966045 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Mon, 15 Jun 2026 20:42:00 +0300 Subject: [PATCH 04/47] impl --- ...utedOperationContextAttributeRegistry.java | 21 +++++++++---------- .../UnknownMessageException.java | 0 .../extensions/communication/Message.java | 0 3 files changed, 10 insertions(+), 11 deletions(-) rename modules/{commons => core}/src/main/java/org/apache/ignite/internal/managers/communication/UnknownMessageException.java (100%) rename modules/{commons => core}/src/main/java/org/apache/ignite/plugin/extensions/communication/Message.java (100%) diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java index 4d9e9c0fd6698..d81b0d1d321cb 100644 --- a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java +++ b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java @@ -22,7 +22,6 @@ import java.util.concurrent.ConcurrentHashMap; import org.apache.ignite.IgniteException; import org.apache.ignite.internal.util.typedef.F; -import org.apache.ignite.plugin.extensions.communication.Message; import org.jetbrains.annotations.Nullable; /** */ @@ -31,7 +30,7 @@ public class DistributedOperationContextAttributeRegistry { private static final DistributedOperationContextAttributeRegistry INSTANCE = new DistributedOperationContextAttributeRegistry(); /** Attributes by their id. */ - private final Map> attributes = new ConcurrentHashMap<>(); + private final Map> attributes = new ConcurrentHashMap<>(); /** */ public static DistributedOperationContextAttributeRegistry instance() { @@ -39,7 +38,7 @@ public static DistributedOperationContextAttributeRegistry instance() { } /** */ - public void register(byte id, OperationContextAttribute attr) { + public void register(byte id, OperationContextAttribute attr) { assert id >= 0; if (attributes.size() == OperationContextAttribute.MAX_ATTR_CNT) @@ -50,19 +49,19 @@ public void register(byte id, OperationContextAttribute a } /** @return Values for all registered operation context attributes. */ - public @Nullable Map collectContext() { - Map res = null; + public @Nullable Map collectContext() { + Map res = null; - for (Map.Entry> e : attributes.entrySet()) { - OperationContextAttribute attr = e.getValue(); + for (Map.Entry> e : attributes.entrySet()) { + OperationContextAttribute attr = e.getValue(); - Message curVal = OperationContext.get(attr); + Object curVal = OperationContext.get(attr); if (!Objects.equals(attr.initialValue(), curVal)) { if (res == null) res = new HashMap<>(attributes.size(), 1.0f); - res.put(e.getKey(), curVal); + res.put(e.getKey(), (T)curVal); } } @@ -70,13 +69,13 @@ public void register(byte id, OperationContextAttribute a } /** */ - public Scope restoreContext(Map res) { + public Scope restoreContext(Map res) { if (F.isEmpty(res)) return Scope.NOOP_SCOPE; OperationContext.ContextUpdater updater = OperationContext.ContextUpdater.create(); - res.forEach((id, attr) -> updater.set((OperationContextAttribute)attributes.get(id), attr)); + res.forEach((id, attr) -> updater.set((OperationContextAttribute)attributes.get(id), attr)); return updater.apply(); } diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/managers/communication/UnknownMessageException.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/UnknownMessageException.java similarity index 100% rename from modules/commons/src/main/java/org/apache/ignite/internal/managers/communication/UnknownMessageException.java rename to modules/core/src/main/java/org/apache/ignite/internal/managers/communication/UnknownMessageException.java diff --git a/modules/commons/src/main/java/org/apache/ignite/plugin/extensions/communication/Message.java b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/Message.java similarity index 100% rename from modules/commons/src/main/java/org/apache/ignite/plugin/extensions/communication/Message.java rename to modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/Message.java From 1987030a0b85fa0ce730b60afd2639c4c661be84 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Wed, 17 Jun 2026 13:50:35 +0300 Subject: [PATCH 05/47] review fixes --- ...utedOperationContextAttributeRegistry.java | 32 ++++++++++++---- .../context/OperationContextAttribute.java | 2 +- .../ignite/internal/CoreMessagesProvider.java | 4 ++ .../internal/OperationContexMessage.java | 37 +++++++++++++++++++ .../ignite/spi/discovery/tcp/ClientImpl.java | 7 ++-- .../ignite/spi/discovery/tcp/ServerImpl.java | 9 +++-- .../spi/discovery/tcp/TcpDiscoveryImpl.java | 24 ++++++++++++ .../messages/TcpDiscoveryAbstractMessage.java | 6 +-- .../OperationContextAttributesTest.java | 2 +- 9 files changed, 105 insertions(+), 18 deletions(-) create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/OperationContexMessage.java diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java index d81b0d1d321cb..9208fb5add00d 100644 --- a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java +++ b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java @@ -16,6 +16,7 @@ */ package org.apache.ignite.internal.thread.context; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -48,17 +49,25 @@ public void register(byte id, OperationContextAttribute attr) { throw new IgniteException("Duplicated attribute id: " + id); } - /** @return Values for all registered operation context attributes. */ - public @Nullable Map collectContext() { - Map res = null; + /** + * TODO : Declare distributed attributes as 'extends Message' after https://issues.apache.org/jira/browse/IGNITE-28766 + * @return Values for all registered operation context attributes. + * */ + public Map collectContext(@Nullable Class checkValuesType) { + Map res = Collections.emptyMap(); for (Map.Entry> e : attributes.entrySet()) { OperationContextAttribute attr = e.getValue(); Object curVal = OperationContext.get(attr); + if (curVal != null && checkValuesType != null && !checkValuesType.isAssignableFrom(curVal.getClass())) { + throw new IgniteException("To distribute operation context attributes they have to be a " + + checkValuesType.getSimpleName()); + } + if (!Objects.equals(attr.initialValue(), curVal)) { - if (res == null) + if (res == Collections.EMPTY_MAP) res = new HashMap<>(attributes.size(), 1.0f); res.put(e.getKey(), (T)curVal); @@ -69,13 +78,22 @@ public void register(byte id, OperationContextAttribute attr) { } /** */ - public Scope restoreContext(Map res) { - if (F.isEmpty(res)) + public Scope restoreContext(int idBitmask, Object[] values) { + if (F.isEmpty(values) || idBitmask == 0) return Scope.NOOP_SCOPE; OperationContext.ContextUpdater updater = OperationContext.ContextUpdater.create(); - res.forEach((id, attr) -> updater.set((OperationContextAttribute)attributes.get(id), attr)); + for (byte attrId = 0; attrId < OperationContextAttribute.MAX_ATTR_CNT; attrId++) { + assert attrId < Integer.SIZE; + + int mask = 1 << attrId; + + if ((mask & idBitmask) == 0) + continue; + + updater.set((OperationContextAttribute)attributes.get(attrId), values[attrId]); + } return updater.apply(); } diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java index 499d241d9ccba..373a72ee3b278 100644 --- a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java +++ b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java @@ -32,7 +32,7 @@ public class OperationContextAttribute { static final AtomicInteger ID_GEN = new AtomicInteger(); /** */ - static final int MAX_ATTR_CNT = Integer.SIZE; + public static final int MAX_ATTR_CNT = Integer.SIZE; /** */ private final int bitmask; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java index 9da592635d229..4d4caff06d126 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java @@ -666,6 +666,10 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C withNoSchema(PartitionHashRecord.class); withNoSchema(TransactionsHashRecord.class); + // [13400 - 13600]: Operation context messages. + msgIdx = 13400; + withNoSchema(OperationContexMessage.class); + assert msgIdx <= MAX_MESSAGE_ID; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/OperationContexMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/OperationContexMessage.java new file mode 100644 index 0000000000000..d45bf3a578602 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/OperationContexMessage.java @@ -0,0 +1,37 @@ +/* + * 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; + +import org.apache.ignite.internal.thread.context.OperationContext; +import org.apache.ignite.plugin.extensions.communication.Message; + +/** ransport for {@link OperationContext} attributes. */ +public class OperationContexMessage implements Message { + /** Values of operation context attributes. */ + @Order(0) + public Message[] vals; + + /** Bitmask of effective attributes ids. */ + @Order(1) + public int idBitmask; + + /** Empty constructor for serialization purposes. */ + public OperationContexMessage() { + // No-op. + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index 3476ba8785843..ce2911a83392e 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -1312,7 +1312,7 @@ private class SocketWriter extends IgniteSpiThread { * @param msg Message. */ private void sendMessage(TcpDiscoveryAbstractMessage msg) { - msg.opCtxAttrs = DistributedOperationContextAttributeRegistry.instance().collectContext(); + fillOperationContextAttributes(msg); synchronized (mux) { queue.add(msg); @@ -2007,10 +2007,11 @@ else if (discoMsg instanceof TcpDiscoveryCheckFailedMessage) TcpDiscoveryAbstractMessage msg0 = (TcpDiscoveryAbstractMessage)msg; - if (F.isEmpty(msg0.opCtxAttrs)) + if (msg0.opCtxMsg == null) processDiscoveryMessage(msg0); else { - try (Scope ignored = DistributedOperationContextAttributeRegistry.instance().restoreContext(msg0.opCtxAttrs)) { + try (Scope ignored = DistributedOperationContextAttributeRegistry.instance() + .restoreContext(msg0.opCtxMsg.idBitmask, msg0.opCtxMsg.vals)) { processDiscoveryMessage(msg0); } } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index a32bf95fd1bc5..e27de173ec6c2 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -81,6 +81,7 @@ import org.apache.ignite.internal.IgniteInterruptedCheckedException; import org.apache.ignite.internal.IgniteNodeAttributes; import org.apache.ignite.internal.IgnitionEx; +import org.apache.ignite.internal.OperationContexMessage; import org.apache.ignite.internal.events.DiscoveryCustomEvent; import org.apache.ignite.internal.managers.communication.UnknownMessageException; import org.apache.ignite.internal.managers.discovery.DiscoveryServerOnlyCustomMessage; @@ -3049,7 +3050,7 @@ void addMessage(TcpDiscoveryAbstractMessage msg, boolean ignoreHighPriority, boo } if (!fromSocket) - msg.opCtxAttrs = DistributedOperationContextAttributeRegistry.instance().collectContext(); + fillOperationContextAttributes(msg); if (msg instanceof TraceableMessage) { TraceableMessage tMsg = (TraceableMessage)msg; @@ -3322,10 +3323,12 @@ else if (msg instanceof TcpDiscoveryAuthFailedMessage) if (msg == WAKEUP) return; - if (F.isEmpty(msg.opCtxAttrs)) + if (msg.opCtxMsg == null) processMessage0(msg); else { - try (Scope ignored = DistributedOperationContextAttributeRegistry.instance().restoreContext(msg.opCtxAttrs)) { + OperationContexMessage cm = msg.opCtxMsg; + + try (Scope ignored = DistributedOperationContextAttributeRegistry.instance().restoreContext(cm.idBitmask, cm.vals)) { processMessage0(msg); } } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java index 789f3d0adb107..097a9a496c7eb 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java @@ -37,15 +37,19 @@ import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.internal.ClusterMetricsSnapshot; import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.OperationContexMessage; import org.apache.ignite.internal.processors.cache.CacheMetricsSnapshot; import org.apache.ignite.internal.processors.cluster.CacheMetricsMessage; import org.apache.ignite.internal.processors.cluster.NodeFullMetricsMessage; import org.apache.ignite.internal.processors.cluster.NodeMetricsMessage; import org.apache.ignite.internal.processors.tracing.NoopTracing; import org.apache.ignite.internal.processors.tracing.Tracing; +import org.apache.ignite.internal.thread.context.DistributedOperationContextAttributeRegistry; +import org.apache.ignite.internal.thread.context.OperationContextAttribute; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.LT; import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.spi.IgniteSpiContext; import org.apache.ignite.spi.IgniteSpiException; import org.apache.ignite.spi.IgniteSpiThread; @@ -450,6 +454,26 @@ public void processCacheMetricsMessage(TcpDiscoveryMetricsUpdateMessage msg, lon } } + /** */ + protected static void fillOperationContextAttributes(TcpDiscoveryAbstractMessage msg) { + DistributedOperationContextAttributeRegistry.instance().collectContext(Message.class).forEach((attrId, msgVal) -> { + assert attrId >= 0 && attrId < OperationContextAttribute.MAX_ATTR_CNT; + + if (msg.opCtxMsg == null) { + msg.opCtxMsg = new OperationContexMessage(); + + msg.opCtxMsg.vals = new Message[OperationContextAttribute.MAX_ATTR_CNT]; + } + + int mask = 1 << attrId; + + assert (msg.opCtxMsg.idBitmask & mask) == 0; + + msg.opCtxMsg.idBitmask |= mask; + msg.opCtxMsg.vals[attrId] = msgVal; + }); + } + /** * @param addrs Addresses. */ diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java index e04f1d856c0ec..1f624f7775af8 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java @@ -19,9 +19,9 @@ import java.io.Externalizable; import java.util.HashSet; -import java.util.Map; import java.util.Set; import java.util.UUID; +import org.apache.ignite.internal.OperationContexMessage; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.tostring.GridToStringInclude; @@ -77,10 +77,10 @@ public abstract class TcpDiscoveryAbstractMessage implements Message { @Order(4) Set failedNodes; - /** Operation context attributes: id -> attribute value. */ + /** Operation context attributes message. */ @GridToStringInclude @Order(5) - public @Nullable Map opCtxAttrs; + public @Nullable OperationContexMessage opCtxMsg; /** * Default no-arg constructor for {@link Externalizable} interface. diff --git a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java index e82721c10b114..e42fe31c83f07 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java @@ -838,7 +838,7 @@ public void testContextAwareDelayQueue() throws Exception { /** */ @Test public void testSendAttributesByDiscovery() throws Exception { - byte attrId = (byte)(OperationContextAttribute.MAX_ATTR_CNT + 1); + byte attrId = (byte)(OperationContextAttribute.MAX_ATTR_CNT - 1); InetSocketAddressMessage dfltAttrVal = new InetSocketAddressMessage(InetAddress.getLoopbackAddress(), 80); From d293eb032a9b0c0f0969bbf927c9cb98f61fc4d2 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Wed, 17 Jun 2026 16:03:40 +0300 Subject: [PATCH 06/47] fix --- ...ibutedOperationContextAttributeRegistry.java | 3 ++- .../context/OperationContextAttributesTest.java | 17 ----------------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java index 9208fb5add00d..a6fb4d41de982 100644 --- a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java +++ b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java @@ -51,8 +51,9 @@ public void register(byte id, OperationContextAttribute attr) { /** * TODO : Declare distributed attributes as 'extends Message' after https://issues.apache.org/jira/browse/IGNITE-28766 + * * @return Values for all registered operation context attributes. - * */ + */ public Map collectContext(@Nullable Class checkValuesType) { Map res = Collections.emptyMap(); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java index e42fe31c83f07..19b3a5d39a636 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java @@ -38,8 +38,6 @@ import java.util.function.Supplier; import org.apache.ignite.IgniteException; import org.apache.ignite.cluster.ClusterNode; -import org.apache.ignite.configuration.IgniteConfiguration; -import org.apache.ignite.events.Event; import org.apache.ignite.internal.IgniteInternalFuture; import org.apache.ignite.internal.managers.communication.GridIoPolicy; import org.apache.ignite.internal.managers.discovery.CustomEventListener; @@ -62,7 +60,6 @@ import org.apache.ignite.lang.IgniteClosure; import org.apache.ignite.lang.IgniteInClosure; import org.apache.ignite.lang.IgniteOutClosure; -import org.apache.ignite.lang.IgnitePredicate; import org.apache.ignite.lang.IgniteRunnable; import org.apache.ignite.lang.IgniteUuid; import org.apache.ignite.spi.discovery.tcp.messages.InetSocketAddressMessage; @@ -72,7 +69,6 @@ import org.springframework.lang.NonNull; import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static org.apache.ignite.internal.events.DiscoveryCustomEvent.EVT_DISCOVERY_CUSTOM_EVT; import static org.apache.ignite.testframework.GridTestUtils.assertThrowsAnyCause; import static org.apache.ignite.testframework.GridTestUtils.assertThrowsWithCause; import static org.apache.ignite.testframework.GridTestUtils.waitForCondition; @@ -97,9 +93,6 @@ public class OperationContextAttributesTest extends GridCommonAbstractTest { /** */ private int beforeTestReservedAttrIds; - /** */ - private IgnitePredicate evtLsnr; - /** {@inheritDoc} */ @Override protected void beforeTest() throws Exception { super.beforeTest(); @@ -122,16 +115,6 @@ public class OperationContextAttributesTest extends GridCommonAbstractTest { OperationContextAttribute.ID_GEN.set(beforeTestReservedAttrIds); } - /** {@inheritDoc} */ - @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { - IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); - - if (evtLsnr != null) - cfg.setLocalEventListeners(Collections.singletonMap(evtLsnr, new int[] {EVT_DISCOVERY_CUSTOM_EVT})); - - return cfg; - } - /** */ @Test public void testNotAttachedAttribute() { From 1395cafed69003dc49d235837e0d010c68d729a7 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Wed, 17 Jun 2026 16:40:08 +0300 Subject: [PATCH 07/47] review fixes --- ...utedOperationContextAttributeRegistry.java | 15 +++++++----- .../internal/OperationContexMessage.java | 2 +- .../spi/discovery/tcp/TcpDiscoveryImpl.java | 24 ++++++++++++------- .../OperationContextAttributesTest.java | 8 ++----- 4 files changed, 28 insertions(+), 21 deletions(-) diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java index a6fb4d41de982..c347d486f6603 100644 --- a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java +++ b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java @@ -27,6 +27,9 @@ /** */ public class DistributedOperationContextAttributeRegistry { + /** */ + public static final byte MAX_DISTRIBUTED_ATTR_ID = 7; + /** */ private static final DistributedOperationContextAttributeRegistry INSTANCE = new DistributedOperationContextAttributeRegistry(); @@ -79,21 +82,21 @@ public Map collectContext(@Nullable Class checkValuesType) { } /** */ - public Scope restoreContext(int idBitmask, Object[] values) { + public Scope restoreContext(byte idBitmask, Object[] values) { if (F.isEmpty(values) || idBitmask == 0) return Scope.NOOP_SCOPE; - OperationContext.ContextUpdater updater = OperationContext.ContextUpdater.create(); + assert values.length <= MAX_DISTRIBUTED_ATTR_ID; - for (byte attrId = 0; attrId < OperationContextAttribute.MAX_ATTR_CNT; attrId++) { - assert attrId < Integer.SIZE; + OperationContext.ContextUpdater updater = OperationContext.ContextUpdater.create(); - int mask = 1 << attrId; + for (byte attrId = 0, idx = 0; attrId < Byte.SIZE; ++attrId) { + byte mask = (byte)(1 << attrId); if ((mask & idBitmask) == 0) continue; - updater.set((OperationContextAttribute)attributes.get(attrId), values[attrId]); + updater.set((OperationContextAttribute)attributes.get(attrId), values[idx++]); } return updater.apply(); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/OperationContexMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/OperationContexMessage.java index d45bf3a578602..4435ed7ec38d5 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/OperationContexMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/OperationContexMessage.java @@ -28,7 +28,7 @@ public class OperationContexMessage implements Message { /** Bitmask of effective attributes ids. */ @Order(1) - public int idBitmask; + public byte idBitmask; /** Empty constructor for serialization purposes. */ public OperationContexMessage() { diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java index 097a9a496c7eb..849bc71c3b1ee 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java @@ -45,7 +45,6 @@ import org.apache.ignite.internal.processors.tracing.NoopTracing; import org.apache.ignite.internal.processors.tracing.Tracing; import org.apache.ignite.internal.thread.context.DistributedOperationContextAttributeRegistry; -import org.apache.ignite.internal.thread.context.OperationContextAttribute; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.LT; import org.apache.ignite.internal.util.typedef.internal.U; @@ -456,22 +455,31 @@ public void processCacheMetricsMessage(TcpDiscoveryMetricsUpdateMessage msg, lon /** */ protected static void fillOperationContextAttributes(TcpDiscoveryAbstractMessage msg) { - DistributedOperationContextAttributeRegistry.instance().collectContext(Message.class).forEach((attrId, msgVal) -> { - assert attrId >= 0 && attrId < OperationContextAttribute.MAX_ATTR_CNT; + Map attrs = DistributedOperationContextAttributeRegistry.instance().collectContext(Message.class); + + if(F.isEmpty(attrs)) + return; + + int idx = 0; + + for (Map.Entry e : attrs.entrySet()) { + byte attrId = e.getKey(); + Message msgVal = e.getValue(); + + assert attrId >= 0 && attrId <= DistributedOperationContextAttributeRegistry.MAX_DISTRIBUTED_ATTR_ID; if (msg.opCtxMsg == null) { msg.opCtxMsg = new OperationContexMessage(); - - msg.opCtxMsg.vals = new Message[OperationContextAttribute.MAX_ATTR_CNT]; + msg.opCtxMsg.vals = new Message[attrs.size()]; } - int mask = 1 << attrId; + byte mask = (byte)(1 << attrId); assert (msg.opCtxMsg.idBitmask & mask) == 0; msg.opCtxMsg.idBitmask |= mask; - msg.opCtxMsg.vals[attrId] = msgVal; - }); + msg.opCtxMsg.vals[idx++] = msgVal; + } } /** diff --git a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java index 19b3a5d39a636..20125f1773c23 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java @@ -821,7 +821,7 @@ public void testContextAwareDelayQueue() throws Exception { /** */ @Test public void testSendAttributesByDiscovery() throws Exception { - byte attrId = (byte)(OperationContextAttribute.MAX_ATTR_CNT - 1); + byte attrId = DistributedOperationContextAttributeRegistry.MAX_DISTRIBUTED_ATTR_ID; InetSocketAddressMessage dfltAttrVal = new InetSocketAddressMessage(InetAddress.getLoopbackAddress(), 80); @@ -866,10 +866,9 @@ else if (grid(i0).localNode().order() == 1) } assertFalse(valToSend.equals(dfltAttrVal)); - assertNull(OperationContext.get(attr)); - // Send from a coordinator. + // Send from the coordinator. try (Scope ignored = OperationContext.set(attr, valToSend)) { grid(0).createCache(defaultCacheConfiguration()); } @@ -877,7 +876,6 @@ else if (grid(i0).localNode().order() == 1) assertTrue(waitForCondition(() -> coordLatch.getCount() == 2, getTestTimeout())); assertTrue(waitForCondition(() -> srvrLatch.getCount() == 2, getTestTimeout())); assertTrue(waitForCondition(() -> clientLatch.getCount() == 2, getTestTimeout())); - assertNull(OperationContext.get(attr)); // Send from a server. @@ -888,7 +886,6 @@ else if (grid(i0).localNode().order() == 1) assertTrue(waitForCondition(() -> coordLatch.getCount() == 1, getTestTimeout())); assertTrue(waitForCondition(() -> srvrLatch.getCount() == 1, getTestTimeout())); assertTrue(waitForCondition(() -> clientLatch.getCount() == 1, getTestTimeout())); - assertNull(OperationContext.get(attr)); // Send from a client. @@ -897,7 +894,6 @@ else if (grid(i0).localNode().order() == 1) } assertNull(OperationContext.get(attr)); - assertTrue(coordLatch.await(getTestTimeout(), TimeUnit.MILLISECONDS)); assertTrue(srvrLatch.await(getTestTimeout(), TimeUnit.MILLISECONDS)); assertTrue(clientLatch.await(getTestTimeout(), TimeUnit.MILLISECONDS)); From 79dab0b2bafc06a4881157fcfcd15cf9f3597632 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 18 Jun 2026 17:21:26 +0300 Subject: [PATCH 08/47] reimpol --- ...utedOperationContextAttributeRegistry.java | 104 ---------------- .../ignite/internal/CoreMessagesProvider.java | 2 +- ...tedOperationContextAttributesMessage.java} | 9 +- .../DistributedOperationAttributeManager.java | 117 ++++++++++++++++++ .../ignite/spi/discovery/tcp/ClientImpl.java | 11 +- .../ignite/spi/discovery/tcp/ServerImpl.java | 16 +-- .../spi/discovery/tcp/TcpDiscoveryImpl.java | 32 ----- .../messages/TcpDiscoveryAbstractMessage.java | 4 +- .../OperationContextAttributesTest.java | 13 +- 9 files changed, 135 insertions(+), 173 deletions(-) delete mode 100644 modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java rename modules/core/src/main/java/org/apache/ignite/internal/{OperationContexMessage.java => DistributedOperationContextAttributesMessage.java} (82%) create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationAttributeManager.java diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java deleted file mode 100644 index c347d486f6603..0000000000000 --- a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeRegistry.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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.thread.context; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; -import org.apache.ignite.IgniteException; -import org.apache.ignite.internal.util.typedef.F; -import org.jetbrains.annotations.Nullable; - -/** */ -public class DistributedOperationContextAttributeRegistry { - /** */ - public static final byte MAX_DISTRIBUTED_ATTR_ID = 7; - - /** */ - private static final DistributedOperationContextAttributeRegistry INSTANCE = new DistributedOperationContextAttributeRegistry(); - - /** Attributes by their id. */ - private final Map> attributes = new ConcurrentHashMap<>(); - - /** */ - public static DistributedOperationContextAttributeRegistry instance() { - return INSTANCE; - } - - /** */ - public void register(byte id, OperationContextAttribute attr) { - assert id >= 0; - - if (attributes.size() == OperationContextAttribute.MAX_ATTR_CNT) - throw new IgniteException("Maximum number of attributes is exceeded [" + OperationContextAttribute.MAX_ATTR_CNT + "]."); - - if (attributes.putIfAbsent(id, attr) != null) - throw new IgniteException("Duplicated attribute id: " + id); - } - - /** - * TODO : Declare distributed attributes as 'extends Message' after https://issues.apache.org/jira/browse/IGNITE-28766 - * - * @return Values for all registered operation context attributes. - */ - public Map collectContext(@Nullable Class checkValuesType) { - Map res = Collections.emptyMap(); - - for (Map.Entry> e : attributes.entrySet()) { - OperationContextAttribute attr = e.getValue(); - - Object curVal = OperationContext.get(attr); - - if (curVal != null && checkValuesType != null && !checkValuesType.isAssignableFrom(curVal.getClass())) { - throw new IgniteException("To distribute operation context attributes they have to be a " - + checkValuesType.getSimpleName()); - } - - if (!Objects.equals(attr.initialValue(), curVal)) { - if (res == Collections.EMPTY_MAP) - res = new HashMap<>(attributes.size(), 1.0f); - - res.put(e.getKey(), (T)curVal); - } - } - - return res; - } - - /** */ - public Scope restoreContext(byte idBitmask, Object[] values) { - if (F.isEmpty(values) || idBitmask == 0) - return Scope.NOOP_SCOPE; - - assert values.length <= MAX_DISTRIBUTED_ATTR_ID; - - OperationContext.ContextUpdater updater = OperationContext.ContextUpdater.create(); - - for (byte attrId = 0, idx = 0; attrId < Byte.SIZE; ++attrId) { - byte mask = (byte)(1 << attrId); - - if ((mask & idBitmask) == 0) - continue; - - updater.set((OperationContextAttribute)attributes.get(attrId), values[idx++]); - } - - return updater.apply(); - } -} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java index 4d4caff06d126..0b655b98f48c5 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java @@ -668,7 +668,7 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C // [13400 - 13600]: Operation context messages. msgIdx = 13400; - withNoSchema(OperationContexMessage.class); + withNoSchema(DistributedOperationContextAttributesMessage.class); assert msgIdx <= MAX_MESSAGE_ID; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/OperationContexMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextAttributesMessage.java similarity index 82% rename from modules/core/src/main/java/org/apache/ignite/internal/OperationContexMessage.java rename to modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextAttributesMessage.java index 4435ed7ec38d5..a319ab9bb759b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/OperationContexMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextAttributesMessage.java @@ -17,21 +17,22 @@ package org.apache.ignite.internal; +import java.util.List; import org.apache.ignite.internal.thread.context.OperationContext; import org.apache.ignite.plugin.extensions.communication.Message; -/** ransport for {@link OperationContext} attributes. */ -public class OperationContexMessage implements Message { +/** Transport for {@link OperationContext} distibuted attributes. */ +public class DistributedOperationContextAttributesMessage implements Message { /** Values of operation context attributes. */ @Order(0) - public Message[] vals; + public List vals; /** Bitmask of effective attributes ids. */ @Order(1) public byte idBitmask; /** Empty constructor for serialization purposes. */ - public OperationContexMessage() { + public DistributedOperationContextAttributesMessage() { // No-op. } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationAttributeManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationAttributeManager.java new file mode 100644 index 0000000000000..cae1fa957be74 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationAttributeManager.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.thread.context; + +import java.util.ArrayList; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import org.apache.ignite.IgniteException; +import org.apache.ignite.internal.DistributedOperationContextAttributesMessage; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.plugin.extensions.communication.Message; +import org.jetbrains.annotations.Nullable; + +/** */ +public class DistributedOperationAttributeManager { + /** */ + public static final byte MAX_DISTRIBUTED_ATTR_ID = 7; + + /** */ + private static final DistributedOperationAttributeManager INSTANCE = new DistributedOperationAttributeManager(); + + /** Attributes by their id. */ + private final Map> attrs = new ConcurrentHashMap<>(); + + /** */ + public static DistributedOperationAttributeManager instance() { + return INSTANCE; + } + + /** */ + public OperationContextAttribute createDistributedAttriubte(byte id, @Nullable T initVal) { + assert id >= 0; + + if (attrs.size() == OperationContextAttribute.MAX_ATTR_CNT) + throw new IgniteException("Maximum number of ributed attributes is exceeded [" + OperationContextAttribute.MAX_ATTR_CNT + "]."); + + attrs.compute(id, (id0, attr0) -> { + if (attr0 != null) + throw new IgniteException("Duplicated distributed attribute id: " + id); + + return OperationContextAttribute.newInstance(initVal); + }); + + return (OperationContextAttribute)attrs.get(id); + } + + /** */ + public @Nullable DistributedOperationContextAttributesMessage collectDistributedAttributes() { + DistributedOperationContextAttributesMessage res = null; + + for (Map.Entry> e : attrs.entrySet()) { + OperationContextAttribute attr = e.getValue(); + + Message curVal = OperationContext.get(attr); + + assert attr.initialValue() == null || curVal == null || curVal.getClass().isAssignableFrom(attr.initialValue().getClass()); + + if (!Objects.equals(curVal, attr.initialValue())) { + if (res == null) { + res = new DistributedOperationContextAttributesMessage(); + + res.vals = new ArrayList<>(MAX_DISTRIBUTED_ATTR_ID / 2); + } + + byte mask = (byte)(1 << e.getKey()); + + assert (res.idBitmask & mask) == 0; + + res.vals.add(curVal); + res.idBitmask |= mask; + } + } + + return res; + } + + /** */ + public Scope restoreDistributedAttributes(@Nullable DistributedOperationContextAttributesMessage msg) { + if (msg == null) + return Scope.NOOP_SCOPE; + + assert msg.idBitmask != 0; + assert !F.isEmpty(msg.vals); + assert msg.vals.size() <= MAX_DISTRIBUTED_ATTR_ID; + + OperationContext.ContextUpdater updater = OperationContext.ContextUpdater.create(); + + for (byte valIdx = 0, maskIdx = -1; valIdx < msg.vals.size(); ++valIdx) { + Message curVal = msg.vals.get(valIdx); + + while (maskIdx < 0 || (msg.idBitmask & (1 << maskIdx)) == 0) { + assert maskIdx <= MAX_DISTRIBUTED_ATTR_ID; + + ++maskIdx; + } + + updater.set((OperationContextAttribute)attrs.get(maskIdx++), curVal); + } + + return updater.apply(); + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index ce2911a83392e..da38209518d63 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -70,7 +70,7 @@ import org.apache.ignite.internal.processors.tracing.messages.SpanContainer; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessage; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessagesTable; -import org.apache.ignite.internal.thread.context.DistributedOperationContextAttributeRegistry; +import org.apache.ignite.internal.thread.context.DistributedOperationAttributeManager; import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.internal.util.future.GridFutureAdapter; import org.apache.ignite.internal.util.tostring.GridToStringExclude; @@ -1312,7 +1312,7 @@ private class SocketWriter extends IgniteSpiThread { * @param msg Message. */ private void sendMessage(TcpDiscoveryAbstractMessage msg) { - fillOperationContextAttributes(msg); + msg.opCtxMsg = DistributedOperationAttributeManager.instance().collectDistributedAttributes(); synchronized (mux) { queue.add(msg); @@ -2007,13 +2007,8 @@ else if (discoMsg instanceof TcpDiscoveryCheckFailedMessage) TcpDiscoveryAbstractMessage msg0 = (TcpDiscoveryAbstractMessage)msg; - if (msg0.opCtxMsg == null) + try (Scope ignored = DistributedOperationAttributeManager.instance().restoreDistributedAttributes(msg0.opCtxMsg)) { processDiscoveryMessage(msg0); - else { - try (Scope ignored = DistributedOperationContextAttributeRegistry.instance() - .restoreContext(msg0.opCtxMsg.idBitmask, msg0.opCtxMsg.vals)) { - processDiscoveryMessage(msg0); - } } } } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index e27de173ec6c2..c8f45ecc8ccbf 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -81,7 +81,6 @@ import org.apache.ignite.internal.IgniteInterruptedCheckedException; import org.apache.ignite.internal.IgniteNodeAttributes; import org.apache.ignite.internal.IgnitionEx; -import org.apache.ignite.internal.OperationContexMessage; import org.apache.ignite.internal.events.DiscoveryCustomEvent; import org.apache.ignite.internal.managers.communication.UnknownMessageException; import org.apache.ignite.internal.managers.discovery.DiscoveryServerOnlyCustomMessage; @@ -96,7 +95,7 @@ import org.apache.ignite.internal.processors.tracing.messages.SpanContainer; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessage; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessagesTable; -import org.apache.ignite.internal.thread.context.DistributedOperationContextAttributeRegistry; +import org.apache.ignite.internal.thread.context.DistributedOperationAttributeManager; import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.internal.thread.pool.IgniteThreadPoolExecutor; import org.apache.ignite.internal.util.GridBoundedLinkedHashSet; @@ -3050,10 +3049,9 @@ void addMessage(TcpDiscoveryAbstractMessage msg, boolean ignoreHighPriority, boo } if (!fromSocket) - fillOperationContextAttributes(msg); + msg.opCtxMsg = DistributedOperationAttributeManager.instance().collectDistributedAttributes(); - if (msg instanceof TraceableMessage) { - TraceableMessage tMsg = (TraceableMessage)msg; + if (msg instanceof TraceableMessage tMsg) { // If we read this message from socket. if (fromSocket) @@ -3323,14 +3321,8 @@ else if (msg instanceof TcpDiscoveryAuthFailedMessage) if (msg == WAKEUP) return; - if (msg.opCtxMsg == null) + try (Scope ignored = DistributedOperationAttributeManager.instance().restoreDistributedAttributes(msg.opCtxMsg)) { processMessage0(msg); - else { - OperationContexMessage cm = msg.opCtxMsg; - - try (Scope ignored = DistributedOperationContextAttributeRegistry.instance().restoreContext(cm.idBitmask, cm.vals)) { - processMessage0(msg); - } } } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java index 849bc71c3b1ee..789f3d0adb107 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java @@ -37,18 +37,15 @@ import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.internal.ClusterMetricsSnapshot; import org.apache.ignite.internal.IgniteEx; -import org.apache.ignite.internal.OperationContexMessage; import org.apache.ignite.internal.processors.cache.CacheMetricsSnapshot; import org.apache.ignite.internal.processors.cluster.CacheMetricsMessage; import org.apache.ignite.internal.processors.cluster.NodeFullMetricsMessage; import org.apache.ignite.internal.processors.cluster.NodeMetricsMessage; import org.apache.ignite.internal.processors.tracing.NoopTracing; import org.apache.ignite.internal.processors.tracing.Tracing; -import org.apache.ignite.internal.thread.context.DistributedOperationContextAttributeRegistry; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.LT; import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.spi.IgniteSpiContext; import org.apache.ignite.spi.IgniteSpiException; import org.apache.ignite.spi.IgniteSpiThread; @@ -453,35 +450,6 @@ public void processCacheMetricsMessage(TcpDiscoveryMetricsUpdateMessage msg, lon } } - /** */ - protected static void fillOperationContextAttributes(TcpDiscoveryAbstractMessage msg) { - Map attrs = DistributedOperationContextAttributeRegistry.instance().collectContext(Message.class); - - if(F.isEmpty(attrs)) - return; - - int idx = 0; - - for (Map.Entry e : attrs.entrySet()) { - byte attrId = e.getKey(); - Message msgVal = e.getValue(); - - assert attrId >= 0 && attrId <= DistributedOperationContextAttributeRegistry.MAX_DISTRIBUTED_ATTR_ID; - - if (msg.opCtxMsg == null) { - msg.opCtxMsg = new OperationContexMessage(); - msg.opCtxMsg.vals = new Message[attrs.size()]; - } - - byte mask = (byte)(1 << attrId); - - assert (msg.opCtxMsg.idBitmask & mask) == 0; - - msg.opCtxMsg.idBitmask |= mask; - msg.opCtxMsg.vals[idx++] = msgVal; - } - } - /** * @param addrs Addresses. */ diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java index 1f624f7775af8..bbee4c33e8cd9 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java @@ -21,7 +21,7 @@ import java.util.HashSet; import java.util.Set; import java.util.UUID; -import org.apache.ignite.internal.OperationContexMessage; +import org.apache.ignite.internal.DistributedOperationContextAttributesMessage; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.tostring.GridToStringInclude; @@ -80,7 +80,7 @@ public abstract class TcpDiscoveryAbstractMessage implements Message { /** Operation context attributes message. */ @GridToStringInclude @Order(5) - public @Nullable OperationContexMessage opCtxMsg; + public @Nullable DistributedOperationContextAttributesMessage opCtxMsg; /** * Default no-arg constructor for {@link Externalizable} interface. diff --git a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java index 20125f1773c23..6f571a984204e 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java @@ -821,13 +821,12 @@ public void testContextAwareDelayQueue() throws Exception { /** */ @Test public void testSendAttributesByDiscovery() throws Exception { - byte attrId = DistributedOperationContextAttributeRegistry.MAX_DISTRIBUTED_ATTR_ID; + byte attrId = DistributedOperationAttributeManager.MAX_DISTRIBUTED_ATTR_ID; InetSocketAddressMessage dfltAttrVal = new InetSocketAddressMessage(InetAddress.getLoopbackAddress(), 80); - OperationContextAttribute attr = OperationContextAttribute.newInstance(); - - DistributedOperationContextAttributeRegistry.instance().register(attrId, attr); + OperationContextAttribute attr = DistributedOperationAttributeManager.instance() + .createDistributedAttriubte(attrId, dfltAttrVal); startGrids(2); startClientGrid(2); @@ -865,9 +864,6 @@ else if (grid(i0).localNode().order() == 1) }); } - assertFalse(valToSend.equals(dfltAttrVal)); - assertNull(OperationContext.get(attr)); - // Send from the coordinator. try (Scope ignored = OperationContext.set(attr, valToSend)) { grid(0).createCache(defaultCacheConfiguration()); @@ -876,7 +872,6 @@ else if (grid(i0).localNode().order() == 1) assertTrue(waitForCondition(() -> coordLatch.getCount() == 2, getTestTimeout())); assertTrue(waitForCondition(() -> srvrLatch.getCount() == 2, getTestTimeout())); assertTrue(waitForCondition(() -> clientLatch.getCount() == 2, getTestTimeout())); - assertNull(OperationContext.get(attr)); // Send from a server. try (Scope ignored = OperationContext.set(attr, valToSend)) { @@ -886,14 +881,12 @@ else if (grid(i0).localNode().order() == 1) assertTrue(waitForCondition(() -> coordLatch.getCount() == 1, getTestTimeout())); assertTrue(waitForCondition(() -> srvrLatch.getCount() == 1, getTestTimeout())); assertTrue(waitForCondition(() -> clientLatch.getCount() == 1, getTestTimeout())); - assertNull(OperationContext.get(attr)); // Send from a client. try (Scope ignored = OperationContext.set(attr, valToSend)) { grid(2).createCache(defaultCacheConfiguration()); } - assertNull(OperationContext.get(attr)); assertTrue(coordLatch.await(getTestTimeout(), TimeUnit.MILLISECONDS)); assertTrue(srvrLatch.await(getTestTimeout(), TimeUnit.MILLISECONDS)); assertTrue(clientLatch.await(getTestTimeout(), TimeUnit.MILLISECONDS)); From 695f18d30cde1ea0cf3b5fb85879c0f0811c45bb Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Fri, 19 Jun 2026 12:54:56 +0300 Subject: [PATCH 09/47] review fixes --- .../context/OperationContextAttribute.java | 2 +- ...utedOperationContextAttributesMessage.java | 4 +- ...utedOperationContextAttributeManager.java} | 53 ++++++++++--------- .../ignite/spi/discovery/tcp/ClientImpl.java | 7 +-- .../ignite/spi/discovery/tcp/ServerImpl.java | 6 +-- .../OperationContextAttributesTest.java | 4 +- 6 files changed, 41 insertions(+), 35 deletions(-) rename modules/core/src/main/java/org/apache/ignite/internal/thread/context/{DistributedOperationAttributeManager.java => DistributedOperationContextAttributeManager.java} (70%) diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java index 373a72ee3b278..499d241d9ccba 100644 --- a/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java +++ b/modules/commons/src/main/java/org/apache/ignite/internal/thread/context/OperationContextAttribute.java @@ -32,7 +32,7 @@ public class OperationContextAttribute { static final AtomicInteger ID_GEN = new AtomicInteger(); /** */ - public static final int MAX_ATTR_CNT = Integer.SIZE; + static final int MAX_ATTR_CNT = Integer.SIZE; /** */ private final int bitmask; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextAttributesMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextAttributesMessage.java index a319ab9bb759b..937536d1b24ad 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextAttributesMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextAttributesMessage.java @@ -21,7 +21,7 @@ import org.apache.ignite.internal.thread.context.OperationContext; import org.apache.ignite.plugin.extensions.communication.Message; -/** Transport for {@link OperationContext} distibuted attributes. */ +/** Transport for {@link OperationContext} distributed attributes. */ public class DistributedOperationContextAttributesMessage implements Message { /** Values of operation context attributes. */ @Order(0) @@ -29,7 +29,7 @@ public class DistributedOperationContextAttributesMessage implements Message { /** Bitmask of effective attributes ids. */ @Order(1) - public byte idBitmask; + public byte idBitmap; /** Empty constructor for serialization purposes. */ public DistributedOperationContextAttributesMessage() { diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationAttributeManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeManager.java similarity index 70% rename from modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationAttributeManager.java rename to modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeManager.java index cae1fa957be74..ff76eb99ea4e6 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationAttributeManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeManager.java @@ -18,8 +18,7 @@ import java.util.ArrayList; import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentSkipListMap; import org.apache.ignite.IgniteException; import org.apache.ignite.internal.DistributedOperationContextAttributesMessage; import org.apache.ignite.internal.util.typedef.F; @@ -27,18 +26,18 @@ import org.jetbrains.annotations.Nullable; /** */ -public class DistributedOperationAttributeManager { +public class DistributedOperationContextAttributeManager { /** */ - public static final byte MAX_DISTRIBUTED_ATTR_ID = 7; + static final byte MAX_DISTRIBUTED_ATTR_CNT = 7; /** */ - private static final DistributedOperationAttributeManager INSTANCE = new DistributedOperationAttributeManager(); + private static final DistributedOperationContextAttributeManager INSTANCE = new DistributedOperationContextAttributeManager(); /** Attributes by their id. */ - private final Map> attrs = new ConcurrentHashMap<>(); + private final Map> attrs = new ConcurrentSkipListMap<>(); /** */ - public static DistributedOperationAttributeManager instance() { + public static DistributedOperationContextAttributeManager instance() { return INSTANCE; } @@ -46,17 +45,23 @@ public static DistributedOperationAttributeManager instance() { public OperationContextAttribute createDistributedAttriubte(byte id, @Nullable T initVal) { assert id >= 0; - if (attrs.size() == OperationContextAttribute.MAX_ATTR_CNT) - throw new IgniteException("Maximum number of ributed attributes is exceeded [" + OperationContextAttribute.MAX_ATTR_CNT + "]."); + if (attrs.size() == OperationContextAttribute.MAX_ATTR_CNT) { + throw new IgniteException("Maximum number of distributed attributes is exceeded [max=" + + OperationContextAttribute.MAX_ATTR_CNT + "]."); + } + + OperationContextAttribute res; - attrs.compute(id, (id0, attr0) -> { - if (attr0 != null) - throw new IgniteException("Duplicated distributed attribute id: " + id); + synchronized (attrs) { + if (attrs.containsKey(id)) + throw new IgniteException("Duplicated distributed attribute id [id=" + id + "]."); - return OperationContextAttribute.newInstance(initVal); - }); + res = OperationContextAttribute.newInstance(initVal); - return (OperationContextAttribute)attrs.get(id); + attrs.put(id, res); + } + + return res; } /** */ @@ -70,19 +75,19 @@ public OperationContextAttribute createDistributedAttriub assert attr.initialValue() == null || curVal == null || curVal.getClass().isAssignableFrom(attr.initialValue().getClass()); - if (!Objects.equals(curVal, attr.initialValue())) { + if (curVal != attr.initialValue()) { if (res == null) { res = new DistributedOperationContextAttributesMessage(); - res.vals = new ArrayList<>(MAX_DISTRIBUTED_ATTR_ID / 2); + res.vals = new ArrayList<>(MAX_DISTRIBUTED_ATTR_CNT / 2); } byte mask = (byte)(1 << e.getKey()); - assert (res.idBitmask & mask) == 0; + assert (res.idBitmap & mask) == 0; res.vals.add(curVal); - res.idBitmask |= mask; + res.idBitmap |= mask; } } @@ -94,17 +99,17 @@ public Scope restoreDistributedAttributes(@Nullable DistributedOperationContextA if (msg == null) return Scope.NOOP_SCOPE; - assert msg.idBitmask != 0; + assert msg.idBitmap != 0; assert !F.isEmpty(msg.vals); - assert msg.vals.size() <= MAX_DISTRIBUTED_ATTR_ID; + assert msg.vals.size() <= MAX_DISTRIBUTED_ATTR_CNT; OperationContext.ContextUpdater updater = OperationContext.ContextUpdater.create(); - for (byte valIdx = 0, maskIdx = -1; valIdx < msg.vals.size(); ++valIdx) { + for (byte valIdx = 0, maskIdx = 0; valIdx < msg.vals.size(); ++valIdx) { Message curVal = msg.vals.get(valIdx); - while (maskIdx < 0 || (msg.idBitmask & (1 << maskIdx)) == 0) { - assert maskIdx <= MAX_DISTRIBUTED_ATTR_ID; + while ((msg.idBitmap & (1 << maskIdx)) == 0) { + assert maskIdx <= MAX_DISTRIBUTED_ATTR_CNT; ++maskIdx; } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index da38209518d63..2ebeeedf762f6 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -70,7 +70,7 @@ import org.apache.ignite.internal.processors.tracing.messages.SpanContainer; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessage; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessagesTable; -import org.apache.ignite.internal.thread.context.DistributedOperationAttributeManager; +import org.apache.ignite.internal.thread.context.DistributedOperationContextAttributeManager; import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.internal.util.future.GridFutureAdapter; import org.apache.ignite.internal.util.tostring.GridToStringExclude; @@ -1312,7 +1312,7 @@ private class SocketWriter extends IgniteSpiThread { * @param msg Message. */ private void sendMessage(TcpDiscoveryAbstractMessage msg) { - msg.opCtxMsg = DistributedOperationAttributeManager.instance().collectDistributedAttributes(); + msg.opCtxMsg = DistributedOperationContextAttributeManager.instance().collectDistributedAttributes(); synchronized (mux) { queue.add(msg); @@ -2007,7 +2007,8 @@ else if (discoMsg instanceof TcpDiscoveryCheckFailedMessage) TcpDiscoveryAbstractMessage msg0 = (TcpDiscoveryAbstractMessage)msg; - try (Scope ignored = DistributedOperationAttributeManager.instance().restoreDistributedAttributes(msg0.opCtxMsg)) { + try (Scope ignored = DistributedOperationContextAttributeManager.instance() + .restoreDistributedAttributes(msg0.opCtxMsg)) { processDiscoveryMessage(msg0); } } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index c8f45ecc8ccbf..684ef8d7b2048 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -95,7 +95,7 @@ import org.apache.ignite.internal.processors.tracing.messages.SpanContainer; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessage; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessagesTable; -import org.apache.ignite.internal.thread.context.DistributedOperationAttributeManager; +import org.apache.ignite.internal.thread.context.DistributedOperationContextAttributeManager; import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.internal.thread.pool.IgniteThreadPoolExecutor; import org.apache.ignite.internal.util.GridBoundedLinkedHashSet; @@ -3049,7 +3049,7 @@ void addMessage(TcpDiscoveryAbstractMessage msg, boolean ignoreHighPriority, boo } if (!fromSocket) - msg.opCtxMsg = DistributedOperationAttributeManager.instance().collectDistributedAttributes(); + msg.opCtxMsg = DistributedOperationContextAttributeManager.instance().collectDistributedAttributes(); if (msg instanceof TraceableMessage tMsg) { @@ -3321,7 +3321,7 @@ else if (msg instanceof TcpDiscoveryAuthFailedMessage) if (msg == WAKEUP) return; - try (Scope ignored = DistributedOperationAttributeManager.instance().restoreDistributedAttributes(msg.opCtxMsg)) { + try (Scope ignored = DistributedOperationContextAttributeManager.instance().restoreDistributedAttributes(msg.opCtxMsg)) { processMessage0(msg); } } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java index 6f571a984204e..446f47d2a5058 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java @@ -821,11 +821,11 @@ public void testContextAwareDelayQueue() throws Exception { /** */ @Test public void testSendAttributesByDiscovery() throws Exception { - byte attrId = DistributedOperationAttributeManager.MAX_DISTRIBUTED_ATTR_ID; + byte attrId = DistributedOperationContextAttributeManager.MAX_DISTRIBUTED_ATTR_CNT; InetSocketAddressMessage dfltAttrVal = new InetSocketAddressMessage(InetAddress.getLoopbackAddress(), 80); - OperationContextAttribute attr = DistributedOperationAttributeManager.instance() + OperationContextAttribute attr = DistributedOperationContextAttributeManager.instance() .createDistributedAttriubte(attrId, dfltAttrVal); startGrids(2); From f0d579fc2d24de981922b36e2dc4fd8e37fc758f Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Fri, 19 Jun 2026 15:43:31 +0300 Subject: [PATCH 10/47] review fixes --- ...> DistributedOperationContextManager.java} | 20 +++------ .../ignite/spi/discovery/tcp/ClientImpl.java | 7 ++- .../ignite/spi/discovery/tcp/ServerImpl.java | 6 +-- .../OperationContextAttributesTest.java | 45 +++++++++++++------ 4 files changed, 45 insertions(+), 33 deletions(-) rename modules/core/src/main/java/org/apache/ignite/internal/thread/context/{DistributedOperationContextAttributeManager.java => DistributedOperationContextManager.java} (88%) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java similarity index 88% rename from modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeManager.java rename to modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java index ff76eb99ea4e6..0738398560df2 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextAttributeManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java @@ -26,18 +26,18 @@ import org.jetbrains.annotations.Nullable; /** */ -public class DistributedOperationContextAttributeManager { +public class DistributedOperationContextManager { /** */ static final byte MAX_DISTRIBUTED_ATTR_CNT = 7; /** */ - private static final DistributedOperationContextAttributeManager INSTANCE = new DistributedOperationContextAttributeManager(); + private static final DistributedOperationContextManager INSTANCE = new DistributedOperationContextManager(); /** Attributes by their id. */ private final Map> attrs = new ConcurrentSkipListMap<>(); /** */ - public static DistributedOperationContextAttributeManager instance() { + public static DistributedOperationContextManager instance() { return INSTANCE; } @@ -50,18 +50,12 @@ public OperationContextAttribute createDistributedAttriub + OperationContextAttribute.MAX_ATTR_CNT + "]."); } - OperationContextAttribute res; - - synchronized (attrs) { - if (attrs.containsKey(id)) + return (OperationContextAttribute)attrs.compute(id, (id0, attr0) -> { + if (attr0 != null) throw new IgniteException("Duplicated distributed attribute id [id=" + id + "]."); - res = OperationContextAttribute.newInstance(initVal); - - attrs.put(id, res); - } - - return res; + return OperationContextAttribute.newInstance(initVal); + }); } /** */ diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index 2ebeeedf762f6..ec153176d64b6 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -70,7 +70,7 @@ import org.apache.ignite.internal.processors.tracing.messages.SpanContainer; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessage; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessagesTable; -import org.apache.ignite.internal.thread.context.DistributedOperationContextAttributeManager; +import org.apache.ignite.internal.thread.context.DistributedOperationContextManager; import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.internal.util.future.GridFutureAdapter; import org.apache.ignite.internal.util.tostring.GridToStringExclude; @@ -1312,7 +1312,7 @@ private class SocketWriter extends IgniteSpiThread { * @param msg Message. */ private void sendMessage(TcpDiscoveryAbstractMessage msg) { - msg.opCtxMsg = DistributedOperationContextAttributeManager.instance().collectDistributedAttributes(); + msg.opCtxMsg = DistributedOperationContextManager.instance().collectDistributedAttributes(); synchronized (mux) { queue.add(msg); @@ -2007,8 +2007,7 @@ else if (discoMsg instanceof TcpDiscoveryCheckFailedMessage) TcpDiscoveryAbstractMessage msg0 = (TcpDiscoveryAbstractMessage)msg; - try (Scope ignored = DistributedOperationContextAttributeManager.instance() - .restoreDistributedAttributes(msg0.opCtxMsg)) { + try (Scope ignored = DistributedOperationContextManager.instance().restoreDistributedAttributes(msg0.opCtxMsg)) { processDiscoveryMessage(msg0); } } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index 684ef8d7b2048..a8a4f2f0a473e 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -95,7 +95,7 @@ import org.apache.ignite.internal.processors.tracing.messages.SpanContainer; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessage; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessagesTable; -import org.apache.ignite.internal.thread.context.DistributedOperationContextAttributeManager; +import org.apache.ignite.internal.thread.context.DistributedOperationContextManager; import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.internal.thread.pool.IgniteThreadPoolExecutor; import org.apache.ignite.internal.util.GridBoundedLinkedHashSet; @@ -3049,7 +3049,7 @@ void addMessage(TcpDiscoveryAbstractMessage msg, boolean ignoreHighPriority, boo } if (!fromSocket) - msg.opCtxMsg = DistributedOperationContextAttributeManager.instance().collectDistributedAttributes(); + msg.opCtxMsg = DistributedOperationContextManager.instance().collectDistributedAttributes(); if (msg instanceof TraceableMessage tMsg) { @@ -3321,7 +3321,7 @@ else if (msg instanceof TcpDiscoveryAuthFailedMessage) if (msg == WAKEUP) return; - try (Scope ignored = DistributedOperationContextAttributeManager.instance().restoreDistributedAttributes(msg.opCtxMsg)) { + try (Scope ignored = DistributedOperationContextManager.instance().restoreDistributedAttributes(msg.opCtxMsg)) { processMessage0(msg); } } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java index 446f47d2a5058..d60071c6dd3e8 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java @@ -43,6 +43,7 @@ import org.apache.ignite.internal.managers.discovery.CustomEventListener; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; import org.apache.ignite.internal.processors.cache.DynamicCacheChangeBatch; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; import org.apache.ignite.internal.processors.timeout.GridTimeoutObject; import org.apache.ignite.internal.processors.timeout.GridTimeoutProcessor; import org.apache.ignite.internal.thread.context.concurrent.IgniteCompletableFuture; @@ -821,12 +822,25 @@ public void testContextAwareDelayQueue() throws Exception { /** */ @Test public void testSendAttributesByDiscovery() throws Exception { - byte attrId = DistributedOperationContextAttributeManager.MAX_DISTRIBUTED_ATTR_CNT; + byte attrId1 = 0; + byte attrId2 = DistributedOperationContextManager.MAX_DISTRIBUTED_ATTR_CNT; - InetSocketAddressMessage dfltAttrVal = new InetSocketAddressMessage(InetAddress.getLoopbackAddress(), 80); + InetSocketAddressMessage dfltDistAttr1Val = new InetSocketAddressMessage(InetAddress.getLoopbackAddress(), 80); + GridCacheVersion dfltDistrAttr2Val = new GridCacheVersion(1, 1, 1); - OperationContextAttribute attr = DistributedOperationContextAttributeManager.instance() - .createDistributedAttriubte(attrId, dfltAttrVal); + // Local attribute 1. + OperationContextAttribute.newInstance(1000); + + // Distributed attribute 1. + OperationContextAttribute dAttr1 = DistributedOperationContextManager.instance() + .createDistributedAttriubte(attrId1, dfltDistAttr1Val); + + // Local attribute 2. + OperationContextAttribute.newInstance("locaAttr2"); + + // Distributed attribute 2. + OperationContextAttribute dAttr2 = DistributedOperationContextManager.instance() + .createDistributedAttriubte(attrId2, dfltDistrAttr2Val); startGrids(2); startClientGrid(2); @@ -835,7 +849,8 @@ public void testSendAttributesByDiscovery() throws Exception { CountDownLatch srvrLatch = new CountDownLatch(3); CountDownLatch clientLatch = new CountDownLatch(3); - InetSocketAddressMessage valToSend = new InetSocketAddressMessage(dfltAttrVal.address(), 443); + InetSocketAddressMessage valToSend1 = new InetSocketAddressMessage(dfltDistAttr1Val.address(), 443); + GridCacheVersion valToSend2 = new GridCacheVersion(2, 2, 2); for (int i = 0; i < G.allGrids().size(); ++i) { int i0 = i; @@ -845,14 +860,18 @@ public void testSendAttributesByDiscovery() throws Exception { @Override public void onCustomEvent(AffinityTopologyVersion topVer, ClusterNode snd, DynamicCacheChangeBatch msg) { - InetSocketAddressMessage receivedVal = OperationContext.get(attr); + InetSocketAddressMessage receivedVal1 = OperationContext.get(dAttr1); + GridCacheVersion receivedVal2 = OperationContext.get(dAttr2); - assertNotNull(receivedVal); + assertNotNull(receivedVal1); + assertNotNull(receivedVal2); - assertFalse(dfltAttrVal.port() == receivedVal.port()); + assertFalse(dfltDistAttr1Val.port() == receivedVal1.port()); + assertEquals(receivedVal1.port(), valToSend1.port()); + assertEquals(receivedVal1.address(), valToSend1.address()); - assertEquals(receivedVal.port(), valToSend.port()); - assertEquals(receivedVal.address(), valToSend.address()); + assertFalse(dfltDistrAttr2Val.equals(receivedVal2)); + assertTrue(valToSend2.equals(receivedVal2)); if (grid(i0).localNode().isClient()) clientLatch.countDown(); @@ -865,7 +884,7 @@ else if (grid(i0).localNode().order() == 1) } // Send from the coordinator. - try (Scope ignored = OperationContext.set(attr, valToSend)) { + try (Scope ignored = OperationContext.set(dAttr1, valToSend1, dAttr2, valToSend2)) { grid(0).createCache(defaultCacheConfiguration()); } @@ -874,7 +893,7 @@ else if (grid(i0).localNode().order() == 1) assertTrue(waitForCondition(() -> clientLatch.getCount() == 2, getTestTimeout())); // Send from a server. - try (Scope ignored = OperationContext.set(attr, valToSend)) { + try (Scope ignored = OperationContext.set(dAttr1, valToSend1, dAttr2, valToSend2)) { grid(1).destroyCache(DEFAULT_CACHE_NAME); } @@ -883,7 +902,7 @@ else if (grid(i0).localNode().order() == 1) assertTrue(waitForCondition(() -> clientLatch.getCount() == 1, getTestTimeout())); // Send from a client. - try (Scope ignored = OperationContext.set(attr, valToSend)) { + try (Scope ignored = OperationContext.set(dAttr1, valToSend1, dAttr2, valToSend2)) { grid(2).createCache(defaultCacheConfiguration()); } From 13d5f1146e19ef054b449526dfea730618a4ab7d Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Fri, 19 Jun 2026 16:38:10 +0300 Subject: [PATCH 11/47] renaming --- .../apache/ignite/internal/CoreMessagesProvider.java | 2 +- ...ge.java => DistributedOperationContextMessage.java} | 4 ++-- .../context/DistributedOperationContextManager.java | 10 +++++----- .../tcp/messages/TcpDiscoveryAbstractMessage.java | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) rename modules/core/src/main/java/org/apache/ignite/internal/{DistributedOperationContextAttributesMessage.java => DistributedOperationContextMessage.java} (90%) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java index 0b655b98f48c5..cc0ab3e112b7d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java @@ -668,7 +668,7 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C // [13400 - 13600]: Operation context messages. msgIdx = 13400; - withNoSchema(DistributedOperationContextAttributesMessage.class); + withNoSchema(DistributedOperationContextMessage.class); assert msgIdx <= MAX_MESSAGE_ID; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextAttributesMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextMessage.java similarity index 90% rename from modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextAttributesMessage.java rename to modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextMessage.java index 937536d1b24ad..0277784044272 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextAttributesMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextMessage.java @@ -22,7 +22,7 @@ import org.apache.ignite.plugin.extensions.communication.Message; /** Transport for {@link OperationContext} distributed attributes. */ -public class DistributedOperationContextAttributesMessage implements Message { +public class DistributedOperationContextMessage implements Message { /** Values of operation context attributes. */ @Order(0) public List vals; @@ -32,7 +32,7 @@ public class DistributedOperationContextAttributesMessage implements Message { public byte idBitmap; /** Empty constructor for serialization purposes. */ - public DistributedOperationContextAttributesMessage() { + public DistributedOperationContextMessage() { // No-op. } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java index 0738398560df2..a95e48880353f 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java @@ -20,7 +20,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentSkipListMap; import org.apache.ignite.IgniteException; -import org.apache.ignite.internal.DistributedOperationContextAttributesMessage; +import org.apache.ignite.internal.DistributedOperationContextMessage; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.plugin.extensions.communication.Message; import org.jetbrains.annotations.Nullable; @@ -59,8 +59,8 @@ public OperationContextAttribute createDistributedAttriub } /** */ - public @Nullable DistributedOperationContextAttributesMessage collectDistributedAttributes() { - DistributedOperationContextAttributesMessage res = null; + public @Nullable DistributedOperationContextMessage collectDistributedAttributes() { + DistributedOperationContextMessage res = null; for (Map.Entry> e : attrs.entrySet()) { OperationContextAttribute attr = e.getValue(); @@ -71,7 +71,7 @@ public OperationContextAttribute createDistributedAttriub if (curVal != attr.initialValue()) { if (res == null) { - res = new DistributedOperationContextAttributesMessage(); + res = new DistributedOperationContextMessage(); res.vals = new ArrayList<>(MAX_DISTRIBUTED_ATTR_CNT / 2); } @@ -89,7 +89,7 @@ public OperationContextAttribute createDistributedAttriub } /** */ - public Scope restoreDistributedAttributes(@Nullable DistributedOperationContextAttributesMessage msg) { + public Scope restoreDistributedAttributes(@Nullable DistributedOperationContextMessage msg) { if (msg == null) return Scope.NOOP_SCOPE; diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java index bbee4c33e8cd9..9dda990c7d020 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java @@ -21,7 +21,7 @@ import java.util.HashSet; import java.util.Set; import java.util.UUID; -import org.apache.ignite.internal.DistributedOperationContextAttributesMessage; +import org.apache.ignite.internal.DistributedOperationContextMessage; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.tostring.GridToStringInclude; @@ -80,7 +80,7 @@ public abstract class TcpDiscoveryAbstractMessage implements Message { /** Operation context attributes message. */ @GridToStringInclude @Order(5) - public @Nullable DistributedOperationContextAttributesMessage opCtxMsg; + public @Nullable DistributedOperationContextMessage opCtxMsg; /** * Default no-arg constructor for {@link Externalizable} interface. From 1bc5fa895521b1f0128eddd9465a2139c73501f7 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Mon, 22 Jun 2026 16:36:40 +0300 Subject: [PATCH 12/47] review fixes --- .../DistributedOperationContextMessage.java | 5 +- .../DistributedOperationContextManager.java | 32 +- .../ignite/spi/discovery/tcp/ClientImpl.java | 428 +++++++++--------- .../OperationContextAttributesTest.java | 4 +- 4 files changed, 238 insertions(+), 231 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextMessage.java index 0277784044272..2cfed19ad250a 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextMessage.java @@ -17,7 +17,6 @@ package org.apache.ignite.internal; -import java.util.List; import org.apache.ignite.internal.thread.context.OperationContext; import org.apache.ignite.plugin.extensions.communication.Message; @@ -25,9 +24,9 @@ public class DistributedOperationContextMessage implements Message { /** Values of operation context attributes. */ @Order(0) - public List vals; + public Message[] vals; - /** Bitmask of effective attributes ids. */ + /** Bitmap of effective attributes ids. */ @Order(1) public byte idBitmap; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java index a95e48880353f..d02b708b975db 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java @@ -17,6 +17,7 @@ package org.apache.ignite.internal.thread.context; import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentSkipListMap; import org.apache.ignite.IgniteException; @@ -28,7 +29,7 @@ /** */ public class DistributedOperationContextManager { /** */ - static final byte MAX_DISTRIBUTED_ATTR_CNT = 7; + static final byte MAX_DISTRIBUTED_ATTR_CNT = Byte.SIZE; /** */ private static final DistributedOperationContextManager INSTANCE = new DistributedOperationContextManager(); @@ -42,13 +43,11 @@ public static DistributedOperationContextManager instance() { } /** */ - public OperationContextAttribute createDistributedAttriubte(byte id, @Nullable T initVal) { + public OperationContextAttribute createDistributedAttribute(byte id, @Nullable T initVal) { assert id >= 0; - if (attrs.size() == OperationContextAttribute.MAX_ATTR_CNT) { - throw new IgniteException("Maximum number of distributed attributes is exceeded [max=" - + OperationContextAttribute.MAX_ATTR_CNT + "]."); - } + if (attrs.size() == MAX_DISTRIBUTED_ATTR_CNT) + throw new IgniteException("Maximum number of distributed attributes is exceeded [max=" + MAX_DISTRIBUTED_ATTR_CNT + "]."); return (OperationContextAttribute)attrs.compute(id, (id0, attr0) -> { if (attr0 != null) @@ -61,30 +60,32 @@ public OperationContextAttribute createDistributedAttriub /** */ public @Nullable DistributedOperationContextMessage collectDistributedAttributes() { DistributedOperationContextMessage res = null; + List vals = null; for (Map.Entry> e : attrs.entrySet()) { OperationContextAttribute attr = e.getValue(); Message curVal = OperationContext.get(attr); - assert attr.initialValue() == null || curVal == null || curVal.getClass().isAssignableFrom(attr.initialValue().getClass()); - if (curVal != attr.initialValue()) { if (res == null) { res = new DistributedOperationContextMessage(); - res.vals = new ArrayList<>(MAX_DISTRIBUTED_ATTR_CNT / 2); + vals = new ArrayList<>(MAX_DISTRIBUTED_ATTR_CNT / 2); } byte mask = (byte)(1 << e.getKey()); assert (res.idBitmap & mask) == 0; - res.vals.add(curVal); + vals.add(curVal); res.idBitmap |= mask; } } + if (res != null) + res.vals = vals.toArray(vals.toArray(new Message[vals.size()])); + return res; } @@ -95,18 +96,15 @@ public Scope restoreDistributedAttributes(@Nullable DistributedOperationContextM assert msg.idBitmap != 0; assert !F.isEmpty(msg.vals); - assert msg.vals.size() <= MAX_DISTRIBUTED_ATTR_CNT; + assert msg.vals.length <= MAX_DISTRIBUTED_ATTR_CNT; OperationContext.ContextUpdater updater = OperationContext.ContextUpdater.create(); - for (byte valIdx = 0, maskIdx = 0; valIdx < msg.vals.size(); ++valIdx) { - Message curVal = msg.vals.get(valIdx); - - while ((msg.idBitmap & (1 << maskIdx)) == 0) { - assert maskIdx <= MAX_DISTRIBUTED_ATTR_CNT; + for (byte valIdx = 0, maskIdx = 0; valIdx < msg.vals.length; ++valIdx) { + Message curVal = msg.vals[valIdx]; + while ((msg.idBitmap & (1 << maskIdx)) == 0) ++maskIdx; - } updater.set((OperationContextAttribute)attrs.get(maskIdx++), curVal); } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index ec153176d64b6..4b4eb3fccacd2 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -1761,280 +1761,290 @@ private MessageWorker(IgniteLogger log) { blockingSectionEnd(); } - if (msg instanceof JoinTimeout) { - int joinCnt0 = ((JoinTimeout)msg).joinCnt; - - if (joinCnt == joinCnt0) { - if (state == STARTING) { - joinError(new IgniteSpiException("Join process timed out, did not receive response for " + - "join request (consider increasing 'joinTimeout' configuration property) " + - "[joinTimeout=" + spi.joinTimeout + ", sock=" + currSock + ']')); - + if (msg instanceof TcpDiscoveryClientReconnectMessage msg0 && msg0.opCtxMsg != null) { + try (Scope ignored = DistributedOperationContextManager.instance().restoreDistributedAttributes(msg0.opCtxMsg)) { + if (processRawMessage(msg)) break; - } - else if (state == DISCONNECTED) { - if (log.isDebugEnabled()) - log.debug("Failed to reconnect, local node segmented " + - "[joinTimeout=" + spi.joinTimeout + ']'); - - state = SEGMENTED; - - notifyDiscovery( - EVT_NODE_SEGMENTED, topVer, locNode, allVisibleNodes(), null); - } } } - else if (msg == SPI_STOP) { - boolean connected = state == CONNECTED; - - state = STOPPED; + else if (processRawMessage(msg)) + break; + } + } + catch (InterruptedException ignored) { + Thread.currentThread().interrupt(); + } + catch (Throwable t) { + if (spi.ignite() instanceof IgniteEx) + ((IgniteEx)spi.ignite()).context().failure().process(new FailureContext(CRITICAL_ERROR, t)); + } + finally { + SocketStream currSock = this.currSock; - assert spi.getSpiContext().isStopping(); + if (currSock != null) + U.closeQuiet(currSock.socket()); - if (connected && currSock != null) { - TcpDiscoveryNodeLeftMessage leftMsg = new TcpDiscoveryNodeLeftMessage(getLocalNodeId()); + if (joinLatch.getCount() > 0) + joinError(new IgniteSpiException("Some error in join process.")); // This should not occur. - leftMsg.client(true); + if (reconnector != null) { + reconnector.cancel(); - Span rootSpan = tracing.create(TraceableMessagesTable.traceName(leftMsg.getClass())) - .addTag(SpanTags.tag(SpanTags.EVENT_NODE, SpanTags.ID), () -> locNode.id().toString()) - .addTag(SpanTags.tag(SpanTags.EVENT_NODE, SpanTags.CONSISTENT_ID), - () -> locNode.consistentId().toString()) - .addLog(() -> "Created"); + reconnector.join(); + } + } + } - leftMsg.spanContainer().serializedSpanBytes(tracing.serialize(rootSpan)); + /** @return {@code True} if the cycle stop is required. */ + private boolean processRawMessage(Object msg) throws InterruptedException { + if (msg instanceof JoinTimeout) { + int joinCnt0 = ((JoinTimeout)msg).joinCnt; - sockWriter.sendMessage(leftMsg); + if (joinCnt == joinCnt0) { + if (state == STARTING) { + joinError(new IgniteSpiException("Join process timed out, did not receive response for " + + "join request (consider increasing 'joinTimeout' configuration property) " + + "[joinTimeout=" + spi.joinTimeout + ", sock=" + currSock + ']')); - rootSpan.addLog(() -> "Sent").end(); - } - else - leaveLatch.countDown(); + return true; } - else if (msg == SPI_RECONNECT) { - if (state == CONNECTED) { - if (reconnector != null) { - reconnector.cancel(); - reconnector.join(); + else if (state == DISCONNECTED) { + if (log.isDebugEnabled()) + log.debug("Failed to reconnect, local node segmented " + + "[joinTimeout=" + spi.joinTimeout + ']'); - reconnector = null; - } + state = SEGMENTED; - sockWriter.forceLeave(); - sockReader.forceStopRead(); + notifyDiscovery( + EVT_NODE_SEGMENTED, topVer, locNode, allVisibleNodes(), null); + } + } + } + else if (msg == SPI_STOP) { + boolean connected = state == CONNECTED; - currSock = null; + state = STOPPED; - queue.clear(); + assert spi.getSpiContext().isStopping(); - onDisconnected(); + if (connected && currSock != null) { + TcpDiscoveryNodeLeftMessage leftMsg = new TcpDiscoveryNodeLeftMessage(getLocalNodeId()); - UUID newId = UUID.randomUUID(); + leftMsg.client(true); - U.quietAndWarn(log, "Local node will try to reconnect to cluster with new id due " + - "to network problems [newId=" + newId + - ", prevId=" + locNode.id() + - ", locNode=" + locNode + ']'); + Span rootSpan = tracing.create(TraceableMessagesTable.traceName(leftMsg.getClass())) + .addTag(SpanTags.tag(SpanTags.EVENT_NODE, SpanTags.ID), () -> locNode.id().toString()) + .addTag(SpanTags.tag(SpanTags.EVENT_NODE, SpanTags.CONSISTENT_ID), + () -> locNode.consistentId().toString()) + .addLog(() -> "Created"); - locNode.onClientDisconnected(newId); + leftMsg.spanContainer().serializedSpanBytes(tracing.serialize(rootSpan)); - throttleClientReconnect(); + sockWriter.sendMessage(leftMsg); - tryJoin(); - } + rootSpan.addLog(() -> "Sent").end(); + } + else + leaveLatch.countDown(); + } + else if (msg == SPI_RECONNECT) { + if (state == CONNECTED) { + if (reconnector != null) { + reconnector.cancel(); + reconnector.join(); + + reconnector = null; } - else if (msg instanceof TcpDiscoveryNodeFailedMessage && - ((TcpDiscoveryNodeFailedMessage)msg).failedNodeId().equals(locNode.id())) { - TcpDiscoveryNodeFailedMessage msg0 = (TcpDiscoveryNodeFailedMessage)msg; - assert msg0.force() : msg0; + sockWriter.forceLeave(); + sockReader.forceStopRead(); - forceFailMsg = msg0; - } - else if (msg instanceof SocketClosedMessage) { - if (((SocketClosedMessage)msg).sock == currSock) { - Socket sock = currSock.sock; + currSock = null; - InetSocketAddress prevAddr = new InetSocketAddress(sock.getInetAddress(), sock.getPort()); + queue.clear(); - currSock = null; + onDisconnected(); - boolean join = joinLatch.getCount() > 0; + UUID newId = UUID.randomUUID(); - if (spi.getSpiContext().isStopping() || state == SEGMENTED) { - leaveLatch.countDown(); + U.quietAndWarn(log, "Local node will try to reconnect to cluster with new id due " + + "to network problems [newId=" + newId + + ", prevId=" + locNode.id() + + ", locNode=" + locNode + ']'); - if (join) { - joinError(new IgniteSpiException("Failed to connect to cluster: socket closed.")); + locNode.onClientDisconnected(newId); - break; - } - } - else { - if (forceFailMsg != null) { - if (log.isDebugEnabled()) { - log.debug("Connection closed, local node received force fail message, " + - "will not try to restore connection"); - } + throttleClientReconnect(); - queue.addFirst(SPI_RECONNECT_FAILED); - } - else { - if (log.isDebugEnabled()) - log.debug("Connection closed, will try to restore connection."); + tryJoin(); + } + } + else if (msg instanceof TcpDiscoveryNodeFailedMessage && + ((TcpDiscoveryNodeFailedMessage)msg).failedNodeId().equals(locNode.id())) { + TcpDiscoveryNodeFailedMessage msg0 = (TcpDiscoveryNodeFailedMessage)msg; - assert reconnector == null; + assert msg0.force() : msg0; - reconnector = new Reconnector(join, prevAddr); - reconnector.start(); - } - } + forceFailMsg = msg0; + } + else if (msg instanceof SocketClosedMessage) { + if (((SocketClosedMessage)msg).sock == currSock) { + Socket sock = currSock.sock; + + InetSocketAddress prevAddr = new InetSocketAddress(sock.getInetAddress(), sock.getPort()); + + currSock = null; + + boolean join = joinLatch.getCount() > 0; + + if (spi.getSpiContext().isStopping() || state == SEGMENTED) { + leaveLatch.countDown(); + + if (join) { + joinError(new IgniteSpiException("Failed to connect to cluster: socket closed.")); + + return true; } } - else if (msg == SPI_RECONNECT_FAILED) { - if (reconnector != null) { - reconnector.cancel(); - reconnector.join(); + else { + if (forceFailMsg != null) { + if (log.isDebugEnabled()) { + log.debug("Connection closed, local node received force fail message, " + + "will not try to restore connection"); + } - reconnector = null; + queue.addFirst(SPI_RECONNECT_FAILED); } - else - assert forceFailMsg != null; - - if (spi.isClientReconnectDisabled()) { - if (state != SEGMENTED && state != STOPPED) { - if (forceFailMsg != null) { - U.quietAndWarn(log, "Local node was dropped from cluster due to network problems " + - "[nodeInitiatedFail=" + forceFailMsg.creatorNodeId() + - ", msg=" + forceFailMsg.warning() + ']'); - } + else { + if (log.isDebugEnabled()) + log.debug("Connection closed, will try to restore connection."); - if (log.isDebugEnabled()) { - log.debug("Failed to restore closed connection, reconnect disabled, " + - "local node segmented [networkTimeout=" + spi.netTimeout + ']'); - } + assert reconnector == null; - state = SEGMENTED; + reconnector = new Reconnector(join, prevAddr); + reconnector.start(); + } + } + } + } + else if (msg == SPI_RECONNECT_FAILED) { + if (reconnector != null) { + reconnector.cancel(); + reconnector.join(); - notifyDiscovery( - EVT_NODE_SEGMENTED, topVer, locNode, allVisibleNodes(), null); - } + reconnector = null; + } + else + assert forceFailMsg != null; + + if (spi.isClientReconnectDisabled()) { + if (state != SEGMENTED && state != STOPPED) { + if (forceFailMsg != null) { + U.quietAndWarn(log, "Local node was dropped from cluster due to network problems " + + "[nodeInitiatedFail=" + forceFailMsg.creatorNodeId() + + ", msg=" + forceFailMsg.warning() + ']'); } - else { - if (state == STARTING || state == CONNECTED) { - if (log.isDebugEnabled()) { - log.debug("Failed to restore closed connection, will try to reconnect " + - "[networkTimeout=" + spi.netTimeout + - ", joinTimeout=" + spi.joinTimeout + - ", failMsg=" + forceFailMsg + ']'); - } - onDisconnected(); - } + if (log.isDebugEnabled()) { + log.debug("Failed to restore closed connection, reconnect disabled, " + + "local node segmented [networkTimeout=" + spi.netTimeout + ']'); + } - UUID newId = UUID.randomUUID(); + state = SEGMENTED; - if (forceFailMsg != null) { - long delay = IgniteSystemProperties.getLong(IGNITE_DISCO_FAILED_CLIENT_RECONNECT_DELAY, - DFLT_DISCO_FAILED_CLIENT_RECONNECT_DELAY); + notifyDiscovery( + EVT_NODE_SEGMENTED, topVer, locNode, allVisibleNodes(), null); + } + } + else { + if (state == STARTING || state == CONNECTED) { + if (log.isDebugEnabled()) { + log.debug("Failed to restore closed connection, will try to reconnect " + + "[networkTimeout=" + spi.netTimeout + + ", joinTimeout=" + spi.joinTimeout + + ", failMsg=" + forceFailMsg + ']'); + } - if (delay > 0) { - U.quietAndWarn(log, "Local node was dropped from cluster due to network problems, " + - "will try to reconnect with new id after " + delay + "ms (reconnect delay " + - "can be changed using IGNITE_DISCO_FAILED_CLIENT_RECONNECT_DELAY system " + - "property) [" + - "newId=" + newId + - ", prevId=" + locNode.id() + - ", locNode=" + locNode + - ", nodeInitiatedFail=" + forceFailMsg.creatorNodeId() + - ", msg=" + forceFailMsg.warning() + ']'); + onDisconnected(); + } - Thread.sleep(delay); - } - else { - U.quietAndWarn(log, "Local node was dropped from cluster due to network problems, " + - "will try to reconnect with new id [" + - "newId=" + newId + - ", prevId=" + locNode.id() + - ", locNode=" + locNode + - ", nodeInitiatedFail=" + forceFailMsg.creatorNodeId() + - ", msg=" + forceFailMsg.warning() + ']'); - } + UUID newId = UUID.randomUUID(); - forceFailMsg = null; - } - else if (log.isInfoEnabled()) { - log.info("Client node disconnected from cluster, will try to reconnect with new id " + - "[newId=" + newId + ", prevId=" + locNode.id() + ", locNode=" + locNode + ']'); - } + if (forceFailMsg != null) { + long delay = IgniteSystemProperties.getLong(IGNITE_DISCO_FAILED_CLIENT_RECONNECT_DELAY, + DFLT_DISCO_FAILED_CLIENT_RECONNECT_DELAY); - locNode.onClientDisconnected(newId); + if (delay > 0) { + U.quietAndWarn(log, "Local node was dropped from cluster due to network problems, " + + "will try to reconnect with new id after " + delay + "ms (reconnect delay " + + "can be changed using IGNITE_DISCO_FAILED_CLIENT_RECONNECT_DELAY system " + + "property) [" + + "newId=" + newId + + ", prevId=" + locNode.id() + + ", locNode=" + locNode + + ", nodeInitiatedFail=" + forceFailMsg.creatorNodeId() + + ", msg=" + forceFailMsg.warning() + ']'); - tryJoin(); + Thread.sleep(delay); + } + else { + U.quietAndWarn(log, "Local node was dropped from cluster due to network problems, " + + "will try to reconnect with new id [" + + "newId=" + newId + + ", prevId=" + locNode.id() + + ", locNode=" + locNode + + ", nodeInitiatedFail=" + forceFailMsg.creatorNodeId() + + ", msg=" + forceFailMsg.warning() + ']'); } + + forceFailMsg = null; + } + else if (log.isInfoEnabled()) { + log.info("Client node disconnected from cluster, will try to reconnect with new id " + + "[newId=" + newId + ", prevId=" + locNode.id() + ", locNode=" + locNode + ']'); } - else { - TcpDiscoveryAbstractMessage discoMsg = (TcpDiscoveryAbstractMessage)msg; - if (joining()) { - IgniteSpiException err = null; + locNode.onClientDisconnected(newId); - if (discoMsg instanceof TcpDiscoveryDuplicateIdMessage) - err = spi.duplicateIdError((TcpDiscoveryDuplicateIdMessage)msg); - else if (discoMsg instanceof TcpDiscoveryAuthFailedMessage) - err = spi.authenticationFailedError((TcpDiscoveryAuthFailedMessage)msg); - //TODO: https://issues.apache.org/jira/browse/IGNITE-9829 - else if (discoMsg instanceof TcpDiscoveryCheckFailedMessage) - err = spi.checkFailedError((TcpDiscoveryCheckFailedMessage)msg); + tryJoin(); + } + } + else { + TcpDiscoveryAbstractMessage discoMsg = (TcpDiscoveryAbstractMessage)msg; - if (err != null) { - if (state == DISCONNECTED) { - U.error(log, "Failed to reconnect, segment local node.", err); + if (joining()) { + IgniteSpiException err = null; - state = SEGMENTED; + if (discoMsg instanceof TcpDiscoveryDuplicateIdMessage) + err = spi.duplicateIdError((TcpDiscoveryDuplicateIdMessage)msg); + else if (discoMsg instanceof TcpDiscoveryAuthFailedMessage) + err = spi.authenticationFailedError((TcpDiscoveryAuthFailedMessage)msg); + //TODO: https://issues.apache.org/jira/browse/IGNITE-9829 + else if (discoMsg instanceof TcpDiscoveryCheckFailedMessage) + err = spi.checkFailedError((TcpDiscoveryCheckFailedMessage)msg); - notifyDiscovery( - EVT_NODE_SEGMENTED, topVer, locNode, allVisibleNodes(), null); - } - else - joinError(err); + if (err != null) { + if (state == DISCONNECTED) { + U.error(log, "Failed to reconnect, segment local node.", err); - cancel(); + state = SEGMENTED; - break; - } + notifyDiscovery( + EVT_NODE_SEGMENTED, topVer, locNode, allVisibleNodes(), null); } + else + joinError(err); - TcpDiscoveryAbstractMessage msg0 = (TcpDiscoveryAbstractMessage)msg; + cancel(); - try (Scope ignored = DistributedOperationContextManager.instance().restoreDistributedAttributes(msg0.opCtxMsg)) { - processDiscoveryMessage(msg0); - } + return true; } } - } - catch (InterruptedException ignored) { - Thread.currentThread().interrupt(); - } - catch (Throwable t) { - if (spi.ignite() instanceof IgniteEx) - ((IgniteEx)spi.ignite()).context().failure().process(new FailureContext(CRITICAL_ERROR, t)); - } - finally { - SocketStream currSock = this.currSock; - if (currSock != null) - U.closeQuiet(currSock.socket()); - - if (joinLatch.getCount() > 0) - joinError(new IgniteSpiException("Some error in join process.")); // This should not occur. - - if (reconnector != null) { - reconnector.cancel(); - - reconnector.join(); - } + processDiscoveryMessage((TcpDiscoveryAbstractMessage)msg); } + + return false; } /** diff --git a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java index d60071c6dd3e8..20ca6845072bf 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java @@ -833,14 +833,14 @@ public void testSendAttributesByDiscovery() throws Exception { // Distributed attribute 1. OperationContextAttribute dAttr1 = DistributedOperationContextManager.instance() - .createDistributedAttriubte(attrId1, dfltDistAttr1Val); + .createDistributedAttribute(attrId1, dfltDistAttr1Val); // Local attribute 2. OperationContextAttribute.newInstance("locaAttr2"); // Distributed attribute 2. OperationContextAttribute dAttr2 = DistributedOperationContextManager.instance() - .createDistributedAttriubte(attrId2, dfltDistrAttr2Val); + .createDistributedAttribute(attrId2, dfltDistrAttr2Val); startGrids(2); startClientGrid(2); From cb024d1897db0564f7c16b8958176ad56da93420 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Mon, 22 Jun 2026 16:45:49 +0300 Subject: [PATCH 13/47] fix --- .../thread/context/DistributedOperationContextManager.java | 2 +- .../internal/thread/context/OperationContextAttributesTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java index d02b708b975db..a0eba66e7052f 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java @@ -44,7 +44,7 @@ public static DistributedOperationContextManager instance() { /** */ public OperationContextAttribute createDistributedAttribute(byte id, @Nullable T initVal) { - assert id >= 0; + assert id >= 0 && id < MAX_DISTRIBUTED_ATTR_CNT : "Invalid distributed attributed id [id=" + id + "]."; if (attrs.size() == MAX_DISTRIBUTED_ATTR_CNT) throw new IgniteException("Maximum number of distributed attributes is exceeded [max=" + MAX_DISTRIBUTED_ATTR_CNT + "]."); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java index 20ca6845072bf..bdf84b743ad2d 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java @@ -823,7 +823,7 @@ public void testContextAwareDelayQueue() throws Exception { @Test public void testSendAttributesByDiscovery() throws Exception { byte attrId1 = 0; - byte attrId2 = DistributedOperationContextManager.MAX_DISTRIBUTED_ATTR_CNT; + byte attrId2 = DistributedOperationContextManager.MAX_DISTRIBUTED_ATTR_CNT - 1; InetSocketAddressMessage dfltDistAttr1Val = new InetSocketAddressMessage(InetAddress.getLoopbackAddress(), 80); GridCacheVersion dfltDistrAttr2Val = new GridCacheVersion(1, 1, 1); From 4f5d18034ab7e20ec543fe85f9e42cdd6b1523ee Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Mon, 22 Jun 2026 17:00:17 +0300 Subject: [PATCH 14/47] fix --- .../java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index 4b4eb3fccacd2..81c0bf9c26f5d 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -1761,7 +1761,7 @@ private MessageWorker(IgniteLogger log) { blockingSectionEnd(); } - if (msg instanceof TcpDiscoveryClientReconnectMessage msg0 && msg0.opCtxMsg != null) { + if (msg instanceof TcpDiscoveryAbstractMessage msg0 && msg0.opCtxMsg != null) { try (Scope ignored = DistributedOperationContextManager.instance().restoreDistributedAttributes(msg0.opCtxMsg)) { if (processRawMessage(msg)) break; From a25c2f2e36a305f73823302df0a9aab86440ce11 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Mon, 22 Jun 2026 17:19:36 +0300 Subject: [PATCH 15/47] review fixes --- .../DistributedOperationContextMessage.java | 7 +++- .../DistributedOperationContextManager.java | 40 +++++++++++++------ 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextMessage.java index 2cfed19ad250a..42d5c7eda859a 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextMessage.java @@ -17,10 +17,15 @@ package org.apache.ignite.internal; +import org.apache.ignite.internal.thread.context.DistributedOperationContextManager; import org.apache.ignite.internal.thread.context.OperationContext; import org.apache.ignite.plugin.extensions.communication.Message; -/** Transport for {@link OperationContext} distributed attributes. */ +/** + * Transport for {@link OperationContext} distributed attributes. + * + * @see DistributedOperationContextManager + */ public class DistributedOperationContextMessage implements Message { /** Values of operation context attributes. */ @Order(0) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java index a0eba66e7052f..25824f64eaaf9 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java @@ -26,15 +26,21 @@ import org.apache.ignite.plugin.extensions.communication.Message; import org.jetbrains.annotations.Nullable; -/** */ +/** + * A manager of {@link OperationContextAttribute} which are required to be propagated through a cluster. + * Has own attributes ids compared to a local node's {@link OperationContext}. + * + * @see OperationContext + * @see DistributedOperationContextMessage + */ public class DistributedOperationContextManager { - /** */ - static final byte MAX_DISTRIBUTED_ATTR_CNT = Byte.SIZE; - /** */ private static final DistributedOperationContextManager INSTANCE = new DistributedOperationContextManager(); - /** Attributes by their id. */ + /** Maximal number of supported distributed attributes. */ + static final byte MAX_DISTRIBUTED_ATTR_CNT = Byte.SIZE; + + /** Registered distributed attributes by their cluster-wide id. */ private final Map> attrs = new ConcurrentSkipListMap<>(); /** */ @@ -42,22 +48,30 @@ public static DistributedOperationContextManager instance() { return INSTANCE; } - /** */ + /** + * Creates and registers a distributable {@link OperationContextAttribute} identified by {@code id}. + * + * @param id Cluster-wide id of an operation context attribute. + * @param initVal The attrbute's unitial value. + */ public OperationContextAttribute createDistributedAttribute(byte id, @Nullable T initVal) { - assert id >= 0 && id < MAX_DISTRIBUTED_ATTR_CNT : "Invalid distributed attributed id [id=" + id + "]."; - - if (attrs.size() == MAX_DISTRIBUTED_ATTR_CNT) - throw new IgniteException("Maximum number of distributed attributes is exceeded [max=" + MAX_DISTRIBUTED_ATTR_CNT + "]."); + assert id >= 0 && id < MAX_DISTRIBUTED_ATTR_CNT : "Invalid distributed attributed id [id=" + id + ']'; return (OperationContextAttribute)attrs.compute(id, (id0, attr0) -> { if (attr0 != null) - throw new IgniteException("Duplicated distributed attribute id [id=" + id + "]."); + throw new IgniteException("Duplicated distributed attribute id [id=" + id + ']'); return OperationContextAttribute.newInstance(initVal); }); } - /** */ + /** + * Requests current {@link OperationContext} for its effective attributes and collects ones which are also registered + * as the distbibued attributes. + * + * @return The dedicated message to send current effective distributed attributes. {@code null}, if there are no + * effective attributes in {@link OperationContext} or none of them is registered as the distribute attribute. + */ public @Nullable DistributedOperationContextMessage collectDistributedAttributes() { DistributedOperationContextMessage res = null; List vals = null; @@ -89,7 +103,7 @@ public OperationContextAttribute createDistributedAttribu return res; } - /** */ + /** Sets the received distributed operation context attributes (if any) into current {@link OperationContext}. */ public Scope restoreDistributedAttributes(@Nullable DistributedOperationContextMessage msg) { if (msg == null) return Scope.NOOP_SCOPE; From 4af4ccdd084645694d808ebed71fdee22c679ba2 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Mon, 22 Jun 2026 17:25:30 +0300 Subject: [PATCH 16/47] typo --- .../thread/context/DistributedOperationContextManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java index 25824f64eaaf9..4a47c84a206c8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java @@ -51,8 +51,8 @@ public static DistributedOperationContextManager instance() { /** * Creates and registers a distributable {@link OperationContextAttribute} identified by {@code id}. * - * @param id Cluster-wide id of an operation context attribute. - * @param initVal The attrbute's unitial value. + * @param id Cluster-wide id of a distributed operation context attribute. + * @param initVal The attribute's unitial value. */ public OperationContextAttribute createDistributedAttribute(byte id, @Nullable T initVal) { assert id >= 0 && id < MAX_DISTRIBUTED_ATTR_CNT : "Invalid distributed attributed id [id=" + id + ']'; From f863cc482d3f5b002180ae825582851bcf8a4532 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Mon, 22 Jun 2026 17:28:17 +0300 Subject: [PATCH 17/47] typo --- .../context/DistributedOperationContextManager.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java index 4a47c84a206c8..cc39aff8e05d9 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java @@ -49,7 +49,7 @@ public static DistributedOperationContextManager instance() { } /** - * Creates and registers a distributable {@link OperationContextAttribute} identified by {@code id}. + * Creates and registers a distributable {@link OperationContextAttribute}. * * @param id Cluster-wide id of a distributed operation context attribute. * @param initVal The attribute's unitial value. @@ -67,10 +67,10 @@ public OperationContextAttribute createDistributedAttribu /** * Requests current {@link OperationContext} for its effective attributes and collects ones which are also registered - * as the distbibued attributes. + * as distbibued attributes. * - * @return The dedicated message to send current effective distributed attributes. {@code null}, if there are no - * effective attributes in {@link OperationContext} or none of them is registered as the distribute attribute. + * @return A message to send current effective distributed attributes. {@code null}, if there are no + * effective attributes in {@link OperationContext} or none of them is a distributed attribute. */ public @Nullable DistributedOperationContextMessage collectDistributedAttributes() { DistributedOperationContextMessage res = null; From 0e2fcd7aa6b6cbee4d652cec60102a3ae769dac9 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Mon, 22 Jun 2026 23:06:02 +0300 Subject: [PATCH 18/47] trivial --- .../thread/context/DistributedOperationContextManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java index cc39aff8e05d9..814af74a68c1e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java @@ -37,7 +37,7 @@ public class DistributedOperationContextManager { /** */ private static final DistributedOperationContextManager INSTANCE = new DistributedOperationContextManager(); - /** Maximal number of supported distributed attributes. */ + /** Maximal number of currently supported distributed attributes. */ static final byte MAX_DISTRIBUTED_ATTR_CNT = Byte.SIZE; /** Registered distributed attributes by their cluster-wide id. */ From 3d7a8bd13fea2ad957bbf4a252d88b19b8134aa2 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Tue, 23 Jun 2026 07:02:28 +0300 Subject: [PATCH 19/47] raw --- .../thread/context/DistributedOperationContextManager.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java index 814af74a68c1e..da9cb5a5bbc52 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java @@ -57,6 +57,9 @@ public static DistributedOperationContextManager instance() { public OperationContextAttribute createDistributedAttribute(byte id, @Nullable T initVal) { assert id >= 0 && id < MAX_DISTRIBUTED_ATTR_CNT : "Invalid distributed attributed id [id=" + id + ']'; + if (started) + throw new IgniteException("Distributed operation context attributes is registered only at the starting."); + return (OperationContextAttribute)attrs.compute(id, (id0, attr0) -> { if (attr0 != null) throw new IgniteException("Duplicated distributed attribute id [id=" + id + ']'); From c545034841649699f011dde30824a7a397bc6ae6 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Tue, 23 Jun 2026 11:06:59 +0300 Subject: [PATCH 20/47] txt --- .../DistributedOperationContextManager.java | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java index cc39aff8e05d9..57a4d39040948 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java @@ -27,8 +27,20 @@ import org.jetbrains.annotations.Nullable; /** - * A manager of {@link OperationContextAttribute} which are required to be propagated through a cluster. - * Has own attributes ids compared to a local node's {@link OperationContext}. + * Provides the ability to manage {@link OperationContext} attributes in a distributed manner. + * + *

This mechanism is primarily used to propagate {@link OperationContext} state across the cluster by + * capturing it before a message is sent, transferring it together with the message, and restoring it on + * the receiving node before message processing begins.

+ * + *

The implementation relies on a mapping between a distributed identifier and an + * {@link OperationContextAttribute} instance that is consistent across all cluster nodes.

+ * + *

To enable propagation of an {@link OperationContextAttribute} value across cluster nodes, the + * attribute must be created using the {@link #createDistributedAttribute(byte, Message)} method. + * + *

Note, that the maximum number of distributed attribute instances that can be created is currently limited to + * {@link #MAX_DISTRIBUTED_ATTR_CNT} for implementation reasons.

* * @see OperationContext * @see DistributedOperationContextMessage @@ -49,10 +61,15 @@ public static DistributedOperationContextManager instance() { } /** - * Creates and registers a distributable {@link OperationContextAttribute}. + * Creates a new {@link OperationContext} attribute with the specified distributed ID and initial value. + * + *

The distributed ID is used to consistently identify the attribute across all nodes in the cluster. + * It must be unique, and its value must be in the range from {@code 0} (inclusive) to {@code Byte.SIZE} (exclusive).

+ * + *

The value of the created attribute is automatically captured and propagated between cluster nodes + * during message transmission.

* - * @param id Cluster-wide id of a distributed operation context attribute. - * @param initVal The attribute's unitial value. + * @see OperationContextAttribute#newInstance(Object) */ public OperationContextAttribute createDistributedAttribute(byte id, @Nullable T initVal) { assert id >= 0 && id < MAX_DISTRIBUTED_ATTR_CNT : "Invalid distributed attributed id [id=" + id + ']'; @@ -66,11 +83,10 @@ public OperationContextAttribute createDistributedAttribu } /** - * Requests current {@link OperationContext} for its effective attributes and collects ones which are also registered - * as distbibued attributes. + * Collects the values of all distributed {@link OperationContextAttribute}s registered by this manager in a format + * suitable for transmission between cluster nodes. * - * @return A message to send current effective distributed attributes. {@code null}, if there are no - * effective attributes in {@link OperationContext} or none of them is a distributed attribute. + * @see OperationContext#get(OperationContextAttribute) */ public @Nullable DistributedOperationContextMessage collectDistributedAttributes() { DistributedOperationContextMessage res = null; @@ -103,7 +119,7 @@ public OperationContextAttribute createDistributedAttribu return res; } - /** Sets the received distributed operation context attributes (if any) into current {@link OperationContext}. */ + /** Restores distributed {@link OperationContextAttribute} values received from a remote node. */ public Scope restoreDistributedAttributes(@Nullable DistributedOperationContextMessage msg) { if (msg == null) return Scope.NOOP_SCOPE; From 887535151993d99e47ba2797821e8c73f518f0b0 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Tue, 23 Jun 2026 11:30:51 +0300 Subject: [PATCH 21/47] fix --- .../ignite/spi/discovery/tcp/ClientImpl.java | 434 +++++++++--------- 1 file changed, 212 insertions(+), 222 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index 81c0bf9c26f5d..a53dd59bb96c7 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -1761,290 +1761,280 @@ private MessageWorker(IgniteLogger log) { blockingSectionEnd(); } - if (msg instanceof TcpDiscoveryAbstractMessage msg0 && msg0.opCtxMsg != null) { - try (Scope ignored = DistributedOperationContextManager.instance().restoreDistributedAttributes(msg0.opCtxMsg)) { - if (processRawMessage(msg)) - break; - } - } - else if (processRawMessage(msg)) - break; - } - } - catch (InterruptedException ignored) { - Thread.currentThread().interrupt(); - } - catch (Throwable t) { - if (spi.ignite() instanceof IgniteEx) - ((IgniteEx)spi.ignite()).context().failure().process(new FailureContext(CRITICAL_ERROR, t)); - } - finally { - SocketStream currSock = this.currSock; + TcpDiscoveryAbstractMessage dm = msg instanceof TcpDiscoveryAbstractMessage ? (TcpDiscoveryAbstractMessage)msg : null; - if (currSock != null) - U.closeQuiet(currSock.socket()); + try (Scope ignored = DistributedOperationContextManager.instance().restoreDistributedAttributes(dm == null ? null : dm.opCtxMsg)) { + if (msg instanceof JoinTimeout) { + int joinCnt0 = ((JoinTimeout)msg).joinCnt; - if (joinLatch.getCount() > 0) - joinError(new IgniteSpiException("Some error in join process.")); // This should not occur. + if (joinCnt == joinCnt0) { + if (state == STARTING) { + joinError(new IgniteSpiException("Join process timed out, did not receive response for " + + "join request (consider increasing 'joinTimeout' configuration property) " + + "[joinTimeout=" + spi.joinTimeout + ", sock=" + currSock + ']')); - if (reconnector != null) { - reconnector.cancel(); + break; + } + else if (state == DISCONNECTED) { + if (log.isDebugEnabled()) + log.debug("Failed to reconnect, local node segmented " + + "[joinTimeout=" + spi.joinTimeout + ']'); - reconnector.join(); - } - } - } + state = SEGMENTED; - /** @return {@code True} if the cycle stop is required. */ - private boolean processRawMessage(Object msg) throws InterruptedException { - if (msg instanceof JoinTimeout) { - int joinCnt0 = ((JoinTimeout)msg).joinCnt; + notifyDiscovery( + EVT_NODE_SEGMENTED, topVer, locNode, allVisibleNodes(), null); + } + } + } + else if (msg == SPI_STOP) { + boolean connected = state == CONNECTED; - if (joinCnt == joinCnt0) { - if (state == STARTING) { - joinError(new IgniteSpiException("Join process timed out, did not receive response for " + - "join request (consider increasing 'joinTimeout' configuration property) " + - "[joinTimeout=" + spi.joinTimeout + ", sock=" + currSock + ']')); + state = STOPPED; - return true; - } - else if (state == DISCONNECTED) { - if (log.isDebugEnabled()) - log.debug("Failed to reconnect, local node segmented " + - "[joinTimeout=" + spi.joinTimeout + ']'); + assert spi.getSpiContext().isStopping(); - state = SEGMENTED; + if (connected && currSock != null) { + TcpDiscoveryNodeLeftMessage leftMsg = new TcpDiscoveryNodeLeftMessage(getLocalNodeId()); - notifyDiscovery( - EVT_NODE_SEGMENTED, topVer, locNode, allVisibleNodes(), null); - } - } - } - else if (msg == SPI_STOP) { - boolean connected = state == CONNECTED; + leftMsg.client(true); - state = STOPPED; + Span rootSpan = tracing.create(TraceableMessagesTable.traceName(leftMsg.getClass())) + .addTag(SpanTags.tag(SpanTags.EVENT_NODE, SpanTags.ID), () -> locNode.id().toString()) + .addTag(SpanTags.tag(SpanTags.EVENT_NODE, SpanTags.CONSISTENT_ID), + () -> locNode.consistentId().toString()) + .addLog(() -> "Created"); - assert spi.getSpiContext().isStopping(); + leftMsg.spanContainer().serializedSpanBytes(tracing.serialize(rootSpan)); - if (connected && currSock != null) { - TcpDiscoveryNodeLeftMessage leftMsg = new TcpDiscoveryNodeLeftMessage(getLocalNodeId()); + sockWriter.sendMessage(leftMsg); - leftMsg.client(true); + rootSpan.addLog(() -> "Sent").end(); + } + else + leaveLatch.countDown(); + } + else if (msg == SPI_RECONNECT) { + if (state == CONNECTED) { + if (reconnector != null) { + reconnector.cancel(); + reconnector.join(); - Span rootSpan = tracing.create(TraceableMessagesTable.traceName(leftMsg.getClass())) - .addTag(SpanTags.tag(SpanTags.EVENT_NODE, SpanTags.ID), () -> locNode.id().toString()) - .addTag(SpanTags.tag(SpanTags.EVENT_NODE, SpanTags.CONSISTENT_ID), - () -> locNode.consistentId().toString()) - .addLog(() -> "Created"); + reconnector = null; + } - leftMsg.spanContainer().serializedSpanBytes(tracing.serialize(rootSpan)); + sockWriter.forceLeave(); + sockReader.forceStopRead(); - sockWriter.sendMessage(leftMsg); + currSock = null; - rootSpan.addLog(() -> "Sent").end(); - } - else - leaveLatch.countDown(); - } - else if (msg == SPI_RECONNECT) { - if (state == CONNECTED) { - if (reconnector != null) { - reconnector.cancel(); - reconnector.join(); + queue.clear(); - reconnector = null; - } + onDisconnected(); - sockWriter.forceLeave(); - sockReader.forceStopRead(); + UUID newId = UUID.randomUUID(); - currSock = null; + U.quietAndWarn(log, "Local node will try to reconnect to cluster with new id due " + + "to network problems [newId=" + newId + + ", prevId=" + locNode.id() + + ", locNode=" + locNode + ']'); - queue.clear(); + locNode.onClientDisconnected(newId); - onDisconnected(); + throttleClientReconnect(); - UUID newId = UUID.randomUUID(); - - U.quietAndWarn(log, "Local node will try to reconnect to cluster with new id due " + - "to network problems [newId=" + newId + - ", prevId=" + locNode.id() + - ", locNode=" + locNode + ']'); + tryJoin(); + } + } + else if (msg instanceof TcpDiscoveryNodeFailedMessage && + ((TcpDiscoveryNodeFailedMessage)msg).failedNodeId().equals(locNode.id())) { + TcpDiscoveryNodeFailedMessage msg0 = (TcpDiscoveryNodeFailedMessage)msg; - locNode.onClientDisconnected(newId); + assert msg0.force() : msg0; - throttleClientReconnect(); + forceFailMsg = msg0; + } + else if (msg instanceof SocketClosedMessage) { + if (((SocketClosedMessage)msg).sock == currSock) { + Socket sock = currSock.sock; - tryJoin(); - } - } - else if (msg instanceof TcpDiscoveryNodeFailedMessage && - ((TcpDiscoveryNodeFailedMessage)msg).failedNodeId().equals(locNode.id())) { - TcpDiscoveryNodeFailedMessage msg0 = (TcpDiscoveryNodeFailedMessage)msg; + InetSocketAddress prevAddr = new InetSocketAddress(sock.getInetAddress(), sock.getPort()); - assert msg0.force() : msg0; + currSock = null; - forceFailMsg = msg0; - } - else if (msg instanceof SocketClosedMessage) { - if (((SocketClosedMessage)msg).sock == currSock) { - Socket sock = currSock.sock; + boolean join = joinLatch.getCount() > 0; - InetSocketAddress prevAddr = new InetSocketAddress(sock.getInetAddress(), sock.getPort()); + if (spi.getSpiContext().isStopping() || state == SEGMENTED) { + leaveLatch.countDown(); - currSock = null; + if (join) { + joinError(new IgniteSpiException("Failed to connect to cluster: socket closed.")); - boolean join = joinLatch.getCount() > 0; + break; + } + } + else { + if (forceFailMsg != null) { + if (log.isDebugEnabled()) { + log.debug("Connection closed, local node received force fail message, " + + "will not try to restore connection"); + } - if (spi.getSpiContext().isStopping() || state == SEGMENTED) { - leaveLatch.countDown(); + queue.addFirst(SPI_RECONNECT_FAILED); + } + else { + if (log.isDebugEnabled()) + log.debug("Connection closed, will try to restore connection."); - if (join) { - joinError(new IgniteSpiException("Failed to connect to cluster: socket closed.")); + assert reconnector == null; - return true; - } - } - else { - if (forceFailMsg != null) { - if (log.isDebugEnabled()) { - log.debug("Connection closed, local node received force fail message, " + - "will not try to restore connection"); + reconnector = new Reconnector(join, prevAddr); + reconnector.start(); + } + } } - - queue.addFirst(SPI_RECONNECT_FAILED); } - else { - if (log.isDebugEnabled()) - log.debug("Connection closed, will try to restore connection."); + else if (msg == SPI_RECONNECT_FAILED) { + if (reconnector != null) { + reconnector.cancel(); + reconnector.join(); + + reconnector = null; + } + else + assert forceFailMsg != null; + + if (spi.isClientReconnectDisabled()) { + if (state != SEGMENTED && state != STOPPED) { + if (forceFailMsg != null) { + U.quietAndWarn(log, "Local node was dropped from cluster due to network problems " + + "[nodeInitiatedFail=" + forceFailMsg.creatorNodeId() + + ", msg=" + forceFailMsg.warning() + ']'); + } - assert reconnector == null; + if (log.isDebugEnabled()) { + log.debug("Failed to restore closed connection, reconnect disabled, " + + "local node segmented [networkTimeout=" + spi.netTimeout + ']'); + } - reconnector = new Reconnector(join, prevAddr); - reconnector.start(); - } - } - } - } - else if (msg == SPI_RECONNECT_FAILED) { - if (reconnector != null) { - reconnector.cancel(); - reconnector.join(); + state = SEGMENTED; - reconnector = null; - } - else - assert forceFailMsg != null; - - if (spi.isClientReconnectDisabled()) { - if (state != SEGMENTED && state != STOPPED) { - if (forceFailMsg != null) { - U.quietAndWarn(log, "Local node was dropped from cluster due to network problems " + - "[nodeInitiatedFail=" + forceFailMsg.creatorNodeId() + - ", msg=" + forceFailMsg.warning() + ']'); - } + notifyDiscovery( + EVT_NODE_SEGMENTED, topVer, locNode, allVisibleNodes(), null); + } + } + else { + if (state == STARTING || state == CONNECTED) { + if (log.isDebugEnabled()) { + log.debug("Failed to restore closed connection, will try to reconnect " + + "[networkTimeout=" + spi.netTimeout + + ", joinTimeout=" + spi.joinTimeout + + ", failMsg=" + forceFailMsg + ']'); + } - if (log.isDebugEnabled()) { - log.debug("Failed to restore closed connection, reconnect disabled, " + - "local node segmented [networkTimeout=" + spi.netTimeout + ']'); - } + onDisconnected(); + } - state = SEGMENTED; + UUID newId = UUID.randomUUID(); - notifyDiscovery( - EVT_NODE_SEGMENTED, topVer, locNode, allVisibleNodes(), null); - } - } - else { - if (state == STARTING || state == CONNECTED) { - if (log.isDebugEnabled()) { - log.debug("Failed to restore closed connection, will try to reconnect " + - "[networkTimeout=" + spi.netTimeout + - ", joinTimeout=" + spi.joinTimeout + - ", failMsg=" + forceFailMsg + ']'); - } + if (forceFailMsg != null) { + long delay = IgniteSystemProperties.getLong(IGNITE_DISCO_FAILED_CLIENT_RECONNECT_DELAY, + DFLT_DISCO_FAILED_CLIENT_RECONNECT_DELAY); - onDisconnected(); - } + if (delay > 0) { + U.quietAndWarn(log, "Local node was dropped from cluster due to network problems, " + + "will try to reconnect with new id after " + delay + "ms (reconnect delay " + + "can be changed using IGNITE_DISCO_FAILED_CLIENT_RECONNECT_DELAY system " + + "property) [" + + "newId=" + newId + + ", prevId=" + locNode.id() + + ", locNode=" + locNode + + ", nodeInitiatedFail=" + forceFailMsg.creatorNodeId() + + ", msg=" + forceFailMsg.warning() + ']'); - UUID newId = UUID.randomUUID(); + Thread.sleep(delay); + } + else { + U.quietAndWarn(log, "Local node was dropped from cluster due to network problems, " + + "will try to reconnect with new id [" + + "newId=" + newId + + ", prevId=" + locNode.id() + + ", locNode=" + locNode + + ", nodeInitiatedFail=" + forceFailMsg.creatorNodeId() + + ", msg=" + forceFailMsg.warning() + ']'); + } - if (forceFailMsg != null) { - long delay = IgniteSystemProperties.getLong(IGNITE_DISCO_FAILED_CLIENT_RECONNECT_DELAY, - DFLT_DISCO_FAILED_CLIENT_RECONNECT_DELAY); + forceFailMsg = null; + } + else if (log.isInfoEnabled()) { + log.info("Client node disconnected from cluster, will try to reconnect with new id " + + "[newId=" + newId + ", prevId=" + locNode.id() + ", locNode=" + locNode + ']'); + } - if (delay > 0) { - U.quietAndWarn(log, "Local node was dropped from cluster due to network problems, " + - "will try to reconnect with new id after " + delay + "ms (reconnect delay " + - "can be changed using IGNITE_DISCO_FAILED_CLIENT_RECONNECT_DELAY system " + - "property) [" + - "newId=" + newId + - ", prevId=" + locNode.id() + - ", locNode=" + locNode + - ", nodeInitiatedFail=" + forceFailMsg.creatorNodeId() + - ", msg=" + forceFailMsg.warning() + ']'); + locNode.onClientDisconnected(newId); - Thread.sleep(delay); + tryJoin(); + } } else { - U.quietAndWarn(log, "Local node was dropped from cluster due to network problems, " + - "will try to reconnect with new id [" + - "newId=" + newId + - ", prevId=" + locNode.id() + - ", locNode=" + locNode + - ", nodeInitiatedFail=" + forceFailMsg.creatorNodeId() + - ", msg=" + forceFailMsg.warning() + ']'); - } + TcpDiscoveryAbstractMessage discoMsg = (TcpDiscoveryAbstractMessage)msg; - forceFailMsg = null; - } - else if (log.isInfoEnabled()) { - log.info("Client node disconnected from cluster, will try to reconnect with new id " + - "[newId=" + newId + ", prevId=" + locNode.id() + ", locNode=" + locNode + ']'); - } + if (joining()) { + IgniteSpiException err = null; - locNode.onClientDisconnected(newId); + if (discoMsg instanceof TcpDiscoveryDuplicateIdMessage) + err = spi.duplicateIdError((TcpDiscoveryDuplicateIdMessage)msg); + else if (discoMsg instanceof TcpDiscoveryAuthFailedMessage) + err = spi.authenticationFailedError((TcpDiscoveryAuthFailedMessage)msg); + //TODO: https://issues.apache.org/jira/browse/IGNITE-9829 + else if (discoMsg instanceof TcpDiscoveryCheckFailedMessage) + err = spi.checkFailedError((TcpDiscoveryCheckFailedMessage)msg); - tryJoin(); - } - } - else { - TcpDiscoveryAbstractMessage discoMsg = (TcpDiscoveryAbstractMessage)msg; + if (err != null) { + if (state == DISCONNECTED) { + U.error(log, "Failed to reconnect, segment local node.", err); - if (joining()) { - IgniteSpiException err = null; + state = SEGMENTED; - if (discoMsg instanceof TcpDiscoveryDuplicateIdMessage) - err = spi.duplicateIdError((TcpDiscoveryDuplicateIdMessage)msg); - else if (discoMsg instanceof TcpDiscoveryAuthFailedMessage) - err = spi.authenticationFailedError((TcpDiscoveryAuthFailedMessage)msg); - //TODO: https://issues.apache.org/jira/browse/IGNITE-9829 - else if (discoMsg instanceof TcpDiscoveryCheckFailedMessage) - err = spi.checkFailedError((TcpDiscoveryCheckFailedMessage)msg); + notifyDiscovery( + EVT_NODE_SEGMENTED, topVer, locNode, allVisibleNodes(), null); + } + else + joinError(err); - if (err != null) { - if (state == DISCONNECTED) { - U.error(log, "Failed to reconnect, segment local node.", err); + cancel(); - state = SEGMENTED; + break; + } + } - notifyDiscovery( - EVT_NODE_SEGMENTED, topVer, locNode, allVisibleNodes(), null); + processDiscoveryMessage((TcpDiscoveryAbstractMessage)msg); } - else - joinError(err); - - cancel(); - - return true; } } - - processDiscoveryMessage((TcpDiscoveryAbstractMessage)msg); } + catch (InterruptedException ignored) { + Thread.currentThread().interrupt(); + } + catch (Throwable t) { + if (spi.ignite() instanceof IgniteEx) + ((IgniteEx)spi.ignite()).context().failure().process(new FailureContext(CRITICAL_ERROR, t)); + } + finally { + SocketStream currSock = this.currSock; - return false; + if (currSock != null) + U.closeQuiet(currSock.socket()); + + if (joinLatch.getCount() > 0) + joinError(new IgniteSpiException("Some error in join process.")); // This should not occur. + + if (reconnector != null) { + reconnector.cancel(); + + reconnector.join(); + } + } } /** From 41d5e1fa1dd09cf92b443017e6e3556dee04eec0 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Tue, 23 Jun 2026 11:32:08 +0300 Subject: [PATCH 22/47] fix --- .../apache/ignite/spi/discovery/tcp/ClientImpl.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index a53dd59bb96c7..d869d5d39e91b 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -1977,17 +1977,15 @@ else if (log.isInfoEnabled()) { } } else { - TcpDiscoveryAbstractMessage discoMsg = (TcpDiscoveryAbstractMessage)msg; - if (joining()) { IgniteSpiException err = null; - if (discoMsg instanceof TcpDiscoveryDuplicateIdMessage) + if (dm instanceof TcpDiscoveryDuplicateIdMessage) err = spi.duplicateIdError((TcpDiscoveryDuplicateIdMessage)msg); - else if (discoMsg instanceof TcpDiscoveryAuthFailedMessage) + else if (dm instanceof TcpDiscoveryAuthFailedMessage) err = spi.authenticationFailedError((TcpDiscoveryAuthFailedMessage)msg); //TODO: https://issues.apache.org/jira/browse/IGNITE-9829 - else if (discoMsg instanceof TcpDiscoveryCheckFailedMessage) + else if (dm instanceof TcpDiscoveryCheckFailedMessage) err = spi.checkFailedError((TcpDiscoveryCheckFailedMessage)msg); if (err != null) { @@ -2008,7 +2006,7 @@ else if (discoMsg instanceof TcpDiscoveryCheckFailedMessage) } } - processDiscoveryMessage((TcpDiscoveryAbstractMessage)msg); + processDiscoveryMessage(dm); } } } From ec3b24195b1b0f453f0b53726137c983c2b544c4 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Tue, 23 Jun 2026 11:33:31 +0300 Subject: [PATCH 23/47] fix --- .../java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index d869d5d39e91b..03d63decf7478 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -1761,7 +1761,9 @@ private MessageWorker(IgniteLogger log) { blockingSectionEnd(); } - TcpDiscoveryAbstractMessage dm = msg instanceof TcpDiscoveryAbstractMessage ? (TcpDiscoveryAbstractMessage)msg : null; + TcpDiscoveryAbstractMessage dm = msg instanceof TcpDiscoveryAbstractMessage + ? (TcpDiscoveryAbstractMessage)msg + : null; try (Scope ignored = DistributedOperationContextManager.instance().restoreDistributedAttributes(dm == null ? null : dm.opCtxMsg)) { if (msg instanceof JoinTimeout) { From 69b5916279553d5350df9de340121b6c8e92fb1b Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Tue, 23 Jun 2026 12:07:21 +0300 Subject: [PATCH 24/47] fix --- .../java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java | 3 ++- .../tcp/messages/TcpDiscoveryAbstractTraceableMessage.java | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index 03d63decf7478..ccf622be6ea3f 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -1765,7 +1765,8 @@ private MessageWorker(IgniteLogger log) { ? (TcpDiscoveryAbstractMessage)msg : null; - try (Scope ignored = DistributedOperationContextManager.instance().restoreDistributedAttributes(dm == null ? null : dm.opCtxMsg)) { + try (Scope ignored = DistributedOperationContextManager.instance() + .restoreDistributedAttributes(dm == null ? null : dm.opCtxMsg)) { if (msg instanceof JoinTimeout) { int joinCnt0 = ((JoinTimeout)msg).joinCnt; diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractTraceableMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractTraceableMessage.java index c36601a399567..f2689f93b3745 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractTraceableMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractTraceableMessage.java @@ -62,6 +62,7 @@ protected TcpDiscoveryAbstractTraceableMessage(TcpDiscoveryAbstractTraceableMess super(msg); this.spanContainer = msg.spanContainer; + this.opCtxMsg = msg.opCtxMsg; } /** From 2f1cf8d18bd169a5a58158b8928ce47acef7038e Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Tue, 23 Jun 2026 12:11:59 +0300 Subject: [PATCH 25/47] fix --- .../thread/context/DistributedOperationContextManager.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java index 57a4d39040948..61bfc48589104 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java @@ -136,6 +136,8 @@ public Scope restoreDistributedAttributes(@Nullable DistributedOperationContextM while ((msg.idBitmap & (1 << maskIdx)) == 0) ++maskIdx; + assert attrs.get(maskIdx) != null; + updater.set((OperationContextAttribute)attrs.get(maskIdx++), curVal); } From 33bb3a8a81973ad7976078694bc47f2aba834628 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Tue, 23 Jun 2026 13:59:53 +0300 Subject: [PATCH 26/47] fix --- .../spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java | 1 + .../tcp/messages/TcpDiscoveryAbstractTraceableMessage.java | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java index 9dda990c7d020..60c38866034e6 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java @@ -106,6 +106,7 @@ protected TcpDiscoveryAbstractMessage(TcpDiscoveryAbstractMessage msg) { verifierNodeId = msg.verifierNodeId; topVer = msg.topVer; flags = msg.flags; + opCtxMsg = msg.opCtxMsg; } /** diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractTraceableMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractTraceableMessage.java index f2689f93b3745..c36601a399567 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractTraceableMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractTraceableMessage.java @@ -62,7 +62,6 @@ protected TcpDiscoveryAbstractTraceableMessage(TcpDiscoveryAbstractTraceableMess super(msg); this.spanContainer = msg.spanContainer; - this.opCtxMsg = msg.opCtxMsg; } /** From 47aac3e1a09dfb39d66a2f231a125b124343e305 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Tue, 23 Jun 2026 14:04:36 +0300 Subject: [PATCH 27/47] fix --- .../spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java index 60c38866034e6..9dda990c7d020 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java @@ -106,7 +106,6 @@ protected TcpDiscoveryAbstractMessage(TcpDiscoveryAbstractMessage msg) { verifierNodeId = msg.verifierNodeId; topVer = msg.topVer; flags = msg.flags; - opCtxMsg = msg.opCtxMsg; } /** From 7d2778bd8a56036742fa75584f81e507e1730957 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Tue, 23 Jun 2026 14:09:13 +0300 Subject: [PATCH 28/47] revert --- .../spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java index 9dda990c7d020..60c38866034e6 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java @@ -106,6 +106,7 @@ protected TcpDiscoveryAbstractMessage(TcpDiscoveryAbstractMessage msg) { verifierNodeId = msg.verifierNodeId; topVer = msg.topVer; flags = msg.flags; + opCtxMsg = msg.opCtxMsg; } /** From 1858db5a0bcdcc766ae598d285704c6f076bdb47 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Tue, 23 Jun 2026 14:12:15 +0300 Subject: [PATCH 29/47] review comment fix --- .../thread/context/DistributedOperationContextManager.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java index 61bfc48589104..20fcb99f0cb5e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java @@ -136,9 +136,11 @@ public Scope restoreDistributedAttributes(@Nullable DistributedOperationContextM while ((msg.idBitmap & (1 << maskIdx)) == 0) ++maskIdx; - assert attrs.get(maskIdx) != null; + OperationContextAttribute attr = (OperationContextAttribute)attrs.get(maskIdx++); - updater.set((OperationContextAttribute)attrs.get(maskIdx++), curVal); + assert attr != null; + + updater.set(attr, curVal); } return updater.apply(); From a0ed08a640995ad000ef7b997e7010f10e0948c7 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Tue, 23 Jun 2026 14:13:57 +0300 Subject: [PATCH 30/47] minor style fix --- .../thread/context/DistributedOperationContextManager.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java index 20fcb99f0cb5e..e87f8cd4d0159 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java @@ -53,7 +53,7 @@ public class DistributedOperationContextManager { static final byte MAX_DISTRIBUTED_ATTR_CNT = Byte.SIZE; /** Registered distributed attributes by their cluster-wide id. */ - private final Map> attrs = new ConcurrentSkipListMap<>(); + private final Map> attrs = new ConcurrentSkipListMap<>(); /** */ public static DistributedOperationContextManager instance() { @@ -92,7 +92,7 @@ public OperationContextAttribute createDistributedAttribu DistributedOperationContextMessage res = null; List vals = null; - for (Map.Entry> e : attrs.entrySet()) { + for (Map.Entry> e : attrs.entrySet()) { OperationContextAttribute attr = e.getValue(); Message curVal = OperationContext.get(attr); @@ -136,7 +136,7 @@ public Scope restoreDistributedAttributes(@Nullable DistributedOperationContextM while ((msg.idBitmap & (1 << maskIdx)) == 0) ++maskIdx; - OperationContextAttribute attr = (OperationContextAttribute)attrs.get(maskIdx++); + OperationContextAttribute attr = attrs.get(maskIdx++); assert attr != null; From b1473805a70456f01413c778974e9e530b1d2aa7 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Tue, 23 Jun 2026 18:44:39 +0300 Subject: [PATCH 31/47] raw --- .../ignite/internal/GridKernalContext.java | 10 +++- .../internal/GridKernalContextImpl.java | 6 ++ .../apache/ignite/internal/IgniteKernal.java | 21 +++++++ .../reader/StandaloneGridKernalContext.java | 6 ++ .../DistributedOperationContextManager.java | 11 ---- .../ignite/spi/discovery/tcp/ClientImpl.java | 6 +- .../ignite/spi/discovery/tcp/ServerImpl.java | 5 +- .../spi/discovery/tcp/TcpDiscoveryImpl.java | 6 ++ .../OperationContextAttributesTest.java | 59 +++++++++++++++---- 9 files changed, 101 insertions(+), 29 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java index 744a844f88e2f..42c800d27bd7f 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java @@ -78,6 +78,7 @@ import org.apache.ignite.internal.processors.timeout.GridTimeoutProcessor; import org.apache.ignite.internal.processors.tracing.Tracing; import org.apache.ignite.internal.suggestions.GridPerformanceSuggestions; +import org.apache.ignite.internal.thread.context.DistributedOperationContextManager; import org.apache.ignite.internal.util.IgniteExceptionRegistry; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.worker.WorkersRegistry; @@ -211,12 +212,19 @@ public interface GridKernalContext extends Iterable { public MaintenanceRegistry maintenanceRegistry(); /** - * Gets core message factoy. + * Gets core message factory. * * @return Core message factory. */ public MessageFactory messageFactory(); + /** + * Gets the distributed operation context manager. + * + * @return The distributed operation context manager. + */ + public DistributedOperationContextManager distributedOperationContextManager(); + /** * Gets transformation processor. * diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java index 5d779302d1f7b..741b99632fe99 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java @@ -101,6 +101,7 @@ import org.apache.ignite.internal.processors.timeout.GridTimeoutProcessor; import org.apache.ignite.internal.processors.tracing.Tracing; import org.apache.ignite.internal.suggestions.GridPerformanceSuggestions; +import org.apache.ignite.internal.thread.context.DistributedOperationContextManager; import org.apache.ignite.internal.thread.pool.IgniteForkJoinPool; import org.apache.ignite.internal.util.IgniteExceptionRegistry; import org.apache.ignite.internal.util.spring.IgniteSpringHelper; @@ -697,6 +698,11 @@ else if (!(comp instanceof DiscoveryNodeValidationProcessor return grid.messageFactory(); } + /** {@inheritDoc} */ + @Override public DistributedOperationContextManager distributedOperationContextManager() { + return grid.distributedOperationContextManager(); + } + /** {@inheritDoc} */ @Override public CacheObjectTransformerProcessor transformer() { return transProc; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java index 303b0355960ab..2d1935ff45c5d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java @@ -174,6 +174,8 @@ import org.apache.ignite.internal.suggestions.JvmConfigurationSuggestions; import org.apache.ignite.internal.suggestions.OsConfigurationSuggestions; import org.apache.ignite.internal.systemview.ConfigurationViewWalker; +import org.apache.ignite.internal.thread.context.DistributedOperationContextManager; +import org.apache.ignite.internal.thread.context.OperationContextAttribute; import org.apache.ignite.internal.util.TimeBag; import org.apache.ignite.internal.util.future.GridCompoundFuture; import org.apache.ignite.internal.util.future.GridFinishedFuture; @@ -210,6 +212,7 @@ import org.apache.ignite.plugin.IgnitePlugin; import org.apache.ignite.plugin.PluginNotFoundException; import org.apache.ignite.plugin.PluginProvider; +import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.extensions.communication.MessageFactory; import org.apache.ignite.plugin.extensions.communication.MessageFactoryProvider; import org.apache.ignite.spi.IgniteSpi; @@ -444,6 +447,9 @@ public class IgniteKernal implements IgniteEx, Externalizable { /** Core message factory. */ private MessageFactory msgFactory; + /** */ + private DistributedOperationContextManager distrOperationContextMgr; + /** * No-arg constructor is required by externalization. */ @@ -930,6 +936,16 @@ public void start( longJVMPauseDetector ); + distrOperationContextMgr = new DistributedOperationContextManager() { + @Override public OperationContextAttribute createDistributedAttribute(byte id, + @Nullable T initVal) { + if (gw.getState() != STARTING) + throw new IgniteException("Distributed operation context attributes is registered only at the starting."); + + return super.createDistributedAttribute(id, initVal); + } + }; + startProcessor(new DiagnosticProcessor(ctx)); mBeansMgr = new IgniteMBeansManager(this); @@ -3057,6 +3073,11 @@ MessageFactory messageFactory() { return msgFactory; } + /** @return {@link DistributedOperationContextManager}. */ + DistributedOperationContextManager distributedOperationContextManager() { + return distrOperationContextMgr; + } + /** * Method is responsible for handling the {@link EventType#EVT_CLIENT_NODE_DISCONNECTED} event. Notify all the * GridComponents that the such even has been occurred (e.g. if the local client node disconnected from the cluster diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java index 48525f5d697d4..29a6bb32ce0e2 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java @@ -103,6 +103,7 @@ import org.apache.ignite.internal.processors.tracing.NoopTracing; import org.apache.ignite.internal.processors.tracing.Tracing; import org.apache.ignite.internal.suggestions.GridPerformanceSuggestions; +import org.apache.ignite.internal.thread.context.DistributedOperationContextManager; import org.apache.ignite.internal.util.IgniteExceptionRegistry; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.typedef.internal.U; @@ -454,6 +455,11 @@ private void setField(IgniteEx kernal, String name, Object val) throws NoSuchFie return null; } + /** {@inheritDoc} */ + @Override public DistributedOperationContextManager distributedOperationContextManager() { + return null; + } + /** {@inheritDoc} */ @Override public CacheObjectTransformerProcessor transformer() { return transProc; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java index 01efcd7fa7ede..8d3d42c33583f 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java @@ -46,20 +46,12 @@ * @see DistributedOperationContextMessage */ public class DistributedOperationContextManager { - /** */ - private static final DistributedOperationContextManager INSTANCE = new DistributedOperationContextManager(); - /** Maximal number of currently supported distributed attributes. */ static final byte MAX_DISTRIBUTED_ATTR_CNT = Byte.SIZE; /** Registered distributed attributes by their cluster-wide id. */ private final Map> attrs = new ConcurrentSkipListMap<>(); - /** */ - public static DistributedOperationContextManager instance() { - return INSTANCE; - } - /** * Creates a new {@link OperationContext} attribute with the specified distributed ID and initial value. * @@ -74,9 +66,6 @@ public static DistributedOperationContextManager instance() { public OperationContextAttribute createDistributedAttribute(byte id, @Nullable T initVal) { assert id >= 0 && id < MAX_DISTRIBUTED_ATTR_CNT : "Invalid distributed attributed id [id=" + id + ']'; - if (started) - throw new IgniteException("Distributed operation context attributes is registered only at the starting."); - return (OperationContextAttribute)attrs.compute(id, (id0, attr0) -> { if (attr0 != null) throw new IgniteException("Duplicated distributed attribute id [id=" + id + ']'); diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index ccf622be6ea3f..10f62ab350030 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -70,7 +70,6 @@ import org.apache.ignite.internal.processors.tracing.messages.SpanContainer; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessage; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessagesTable; -import org.apache.ignite.internal.thread.context.DistributedOperationContextManager; import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.internal.util.future.GridFutureAdapter; import org.apache.ignite.internal.util.tostring.GridToStringExclude; @@ -1312,7 +1311,7 @@ private class SocketWriter extends IgniteSpiThread { * @param msg Message. */ private void sendMessage(TcpDiscoveryAbstractMessage msg) { - msg.opCtxMsg = DistributedOperationContextManager.instance().collectDistributedAttributes(); + msg.opCtxMsg = distrOperationContextMgr.collectDistributedAttributes(); synchronized (mux) { queue.add(msg); @@ -1765,8 +1764,7 @@ private MessageWorker(IgniteLogger log) { ? (TcpDiscoveryAbstractMessage)msg : null; - try (Scope ignored = DistributedOperationContextManager.instance() - .restoreDistributedAttributes(dm == null ? null : dm.opCtxMsg)) { + try (Scope ignored = distrOperationContextMgr.restoreDistributedAttributes(dm == null ? null : dm.opCtxMsg)) { if (msg instanceof JoinTimeout) { int joinCnt0 = ((JoinTimeout)msg).joinCnt; diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index a8a4f2f0a473e..30d289355717b 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -95,7 +95,6 @@ import org.apache.ignite.internal.processors.tracing.messages.SpanContainer; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessage; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessagesTable; -import org.apache.ignite.internal.thread.context.DistributedOperationContextManager; import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.internal.thread.pool.IgniteThreadPoolExecutor; import org.apache.ignite.internal.util.GridBoundedLinkedHashSet; @@ -3049,7 +3048,7 @@ void addMessage(TcpDiscoveryAbstractMessage msg, boolean ignoreHighPriority, boo } if (!fromSocket) - msg.opCtxMsg = DistributedOperationContextManager.instance().collectDistributedAttributes(); + msg.opCtxMsg = distrOperationContextMgr.collectDistributedAttributes(); if (msg instanceof TraceableMessage tMsg) { @@ -3321,7 +3320,7 @@ else if (msg instanceof TcpDiscoveryAuthFailedMessage) if (msg == WAKEUP) return; - try (Scope ignored = DistributedOperationContextManager.instance().restoreDistributedAttributes(msg.opCtxMsg)) { + try (Scope ignored = distrOperationContextMgr.restoreDistributedAttributes(msg.opCtxMsg)) { processMessage0(msg); } } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java index 789f3d0adb107..abab4e3de3944 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java @@ -43,6 +43,7 @@ import org.apache.ignite.internal.processors.cluster.NodeMetricsMessage; import org.apache.ignite.internal.processors.tracing.NoopTracing; import org.apache.ignite.internal.processors.tracing.Tracing; +import org.apache.ignite.internal.thread.context.DistributedOperationContextManager; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.LT; import org.apache.ignite.internal.util.typedef.internal.U; @@ -139,6 +140,9 @@ abstract class TcpDiscoveryImpl { /** Tracing. */ protected Tracing tracing; + /** */ + protected final DistributedOperationContextManager distrOperationContextMgr; + /** * @param spi Adapter. */ @@ -151,6 +155,8 @@ abstract class TcpDiscoveryImpl { tracing = ((IgniteEx)spi.ignite()).context().tracing(); else tracing = new NoopTracing(); + + distrOperationContextMgr = ((IgniteEx)spi.ignite()).context().distributedOperationContextManager(); } /** diff --git a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java index bdf84b743ad2d..590ec3a7bbe0c 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java @@ -31,13 +31,16 @@ import java.util.concurrent.ForkJoinPool; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; +import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteException; import org.apache.ignite.cluster.ClusterNode; +import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.internal.IgniteInternalFuture; import org.apache.ignite.internal.managers.communication.GridIoPolicy; import org.apache.ignite.internal.managers.discovery.CustomEventListener; @@ -63,13 +66,18 @@ import org.apache.ignite.lang.IgniteOutClosure; import org.apache.ignite.lang.IgniteRunnable; import org.apache.ignite.lang.IgniteUuid; +import org.apache.ignite.plugin.AbstractTestPluginProvider; +import org.apache.ignite.plugin.PluginContext; +import org.apache.ignite.plugin.PluginProvider; import org.apache.ignite.spi.discovery.tcp.messages.InetSocketAddressMessage; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; import org.apache.ignite.thread.IgniteThread; import org.junit.Test; import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.apache.ignite.testframework.GridTestUtils.assertThrows; import static org.apache.ignite.testframework.GridTestUtils.assertThrowsAnyCause; import static org.apache.ignite.testframework.GridTestUtils.assertThrowsWithCause; import static org.apache.ignite.testframework.GridTestUtils.waitForCondition; @@ -94,6 +102,9 @@ public class OperationContextAttributesTest extends GridCommonAbstractTest { /** */ private int beforeTestReservedAttrIds; + /** */ + private @Nullable PluginProvider pluginProvider; + /** {@inheritDoc} */ @Override protected void beforeTest() throws Exception { super.beforeTest(); @@ -116,6 +127,16 @@ public class OperationContextAttributesTest extends GridCommonAbstractTest { OperationContextAttribute.ID_GEN.set(beforeTestReservedAttrIds); } + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); + + if (pluginProvider != null) + cfg.setPluginProviders(pluginProvider); + + return cfg; + } + /** */ @Test public void testNotAttachedAttribute() { @@ -828,23 +849,41 @@ public void testSendAttributesByDiscovery() throws Exception { InetSocketAddressMessage dfltDistAttr1Val = new InetSocketAddressMessage(InetAddress.getLoopbackAddress(), 80); GridCacheVersion dfltDistrAttr2Val = new GridCacheVersion(1, 1, 1); - // Local attribute 1. - OperationContextAttribute.newInstance(1000); + AtomicReference> attr1 = new AtomicReference<>(); + AtomicReference> attr2 = new AtomicReference<>(); - // Distributed attribute 1. - OperationContextAttribute dAttr1 = DistributedOperationContextManager.instance() - .createDistributedAttribute(attrId1, dfltDistAttr1Val); + pluginProvider = new AbstractTestPluginProvider() { + @Override public String name() { + return "DistributedOperationContextAttributesRegistrator"; + } - // Local attribute 2. - OperationContextAttribute.newInstance("locaAttr2"); + @Override public void start(PluginContext ctx) { + // Distributed attribute 1. + OperationContextAttribute dAttr1 = grid(0).context().distributedOperationContextManager() + .createDistributedAttribute(attrId1, dfltDistAttr1Val); - // Distributed attribute 2. - OperationContextAttribute dAttr2 = DistributedOperationContextManager.instance() - .createDistributedAttribute(attrId2, dfltDistrAttr2Val); + // Distributed attribute 2. + OperationContextAttribute dAttr2 = grid(0).context().distributedOperationContextManager() + .createDistributedAttribute(attrId2, dfltDistrAttr2Val); + } + }; + + // Local attribute 1. + OperationContextAttribute.newInstance(1000); startGrids(2); startClientGrid(2); + assertThrows( + null, + () -> grid(0).context().distributedOperationContextManager().createDistributedAttribute((byte)1, null), + IgniteException.class, + "Distributed operation context attributes is registered only at the starting" + ); + + // Local attribute 2. + OperationContextAttribute.newInstance("locaAttr2"); + CountDownLatch coordLatch = new CountDownLatch(3); CountDownLatch srvrLatch = new CountDownLatch(3); CountDownLatch clientLatch = new CountDownLatch(3); From 68615dc22135be00302dd39e052319f4cf7686b6 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Tue, 23 Jun 2026 19:12:56 +0300 Subject: [PATCH 32/47] raw --- .../OperationContextAttributesTest.java | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java index 590ec3a7bbe0c..8b59975e6fdf5 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java @@ -41,6 +41,7 @@ import org.apache.ignite.IgniteException; import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.IgniteEx; import org.apache.ignite.internal.IgniteInternalFuture; import org.apache.ignite.internal.managers.communication.GridIoPolicy; import org.apache.ignite.internal.managers.discovery.CustomEventListener; @@ -849,8 +850,8 @@ public void testSendAttributesByDiscovery() throws Exception { InetSocketAddressMessage dfltDistAttr1Val = new InetSocketAddressMessage(InetAddress.getLoopbackAddress(), 80); GridCacheVersion dfltDistrAttr2Val = new GridCacheVersion(1, 1, 1); - AtomicReference> attr1 = new AtomicReference<>(); - AtomicReference> attr2 = new AtomicReference<>(); + AtomicReference> dAttr1 = new AtomicReference<>(); + AtomicReference> dAttr2 = new AtomicReference<>(); pluginProvider = new AbstractTestPluginProvider() { @Override public String name() { @@ -859,12 +860,16 @@ public void testSendAttributesByDiscovery() throws Exception { @Override public void start(PluginContext ctx) { // Distributed attribute 1. - OperationContextAttribute dAttr1 = grid(0).context().distributedOperationContextManager() - .createDistributedAttribute(attrId1, dfltDistAttr1Val); + OperationContextAttribute a1 = ((IgniteEx)ctx.grid()).context() + .distributedOperationContextManager().createDistributedAttribute(attrId1, dfltDistAttr1Val); + + dAttr1.set(a1); // Distributed attribute 2. - OperationContextAttribute dAttr2 = grid(0).context().distributedOperationContextManager() - .createDistributedAttribute(attrId2, dfltDistrAttr2Val); + OperationContextAttribute a2 = ((IgniteEx)ctx.grid()).context() + .distributedOperationContextManager().createDistributedAttribute(attrId2, dfltDistrAttr2Val); + + dAttr2.set(a2); } }; @@ -899,8 +904,8 @@ public void testSendAttributesByDiscovery() throws Exception { @Override public void onCustomEvent(AffinityTopologyVersion topVer, ClusterNode snd, DynamicCacheChangeBatch msg) { - InetSocketAddressMessage receivedVal1 = OperationContext.get(dAttr1); - GridCacheVersion receivedVal2 = OperationContext.get(dAttr2); + InetSocketAddressMessage receivedVal1 = OperationContext.get(dAttr1.get()); + GridCacheVersion receivedVal2 = OperationContext.get(dAttr2.get()); assertNotNull(receivedVal1); assertNotNull(receivedVal2); @@ -923,7 +928,7 @@ else if (grid(i0).localNode().order() == 1) } // Send from the coordinator. - try (Scope ignored = OperationContext.set(dAttr1, valToSend1, dAttr2, valToSend2)) { + try (Scope ignored = OperationContext.set(dAttr1.get(), valToSend1, dAttr2.get(), valToSend2)) { grid(0).createCache(defaultCacheConfiguration()); } @@ -932,7 +937,7 @@ else if (grid(i0).localNode().order() == 1) assertTrue(waitForCondition(() -> clientLatch.getCount() == 2, getTestTimeout())); // Send from a server. - try (Scope ignored = OperationContext.set(dAttr1, valToSend1, dAttr2, valToSend2)) { + try (Scope ignored = OperationContext.set(dAttr1.get(), valToSend1, dAttr2.get(), valToSend2)) { grid(1).destroyCache(DEFAULT_CACHE_NAME); } @@ -941,7 +946,7 @@ else if (grid(i0).localNode().order() == 1) assertTrue(waitForCondition(() -> clientLatch.getCount() == 1, getTestTimeout())); // Send from a client. - try (Scope ignored = OperationContext.set(dAttr1, valToSend1, dAttr2, valToSend2)) { + try (Scope ignored = OperationContext.set(dAttr1.get(), valToSend1, dAttr2.get(), valToSend2)) { grid(2).createCache(defaultCacheConfiguration()); } From 6b038601ee408e04af37af3839fffa5c5145799a Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Wed, 24 Jun 2026 13:08:12 +0300 Subject: [PATCH 33/47] raw --- .../main/java/org/apache/ignite/internal/IgniteKernal.java | 2 +- .../thread/context/DistributedOperationContextManager.java | 5 ----- .../java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java | 1 - .../thread/context/OperationContextAttributesTest.java | 1 - 4 files changed, 1 insertion(+), 8 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java index 9e386ad675ce1..3fc9dfe53a976 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java @@ -3075,7 +3075,7 @@ MessageFactory messageFactory() { return msgFactory; } - /** @return {@link DistributedOperationContextManager}. */ + /** @return Instance of {@link DistributedOperationContextManager}. */ DistributedOperationContextManager distributedOperationContextManager() { return distrOperationContextMgr; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java index f72801c5cb257..925c56ae1d9e3 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java @@ -52,11 +52,6 @@ public class DistributedOperationContextManager { /** Registered distributed attributes by their cluster-wide id. */ private final Map> attrs = new ConcurrentSkipListMap<>(); - /** */ - public static DistributedOperationContextManager instance() { - return INSTANCE; - } - /** * Creates a new {@link OperationContext} attribute with the specified distributed ID and initial value. * diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index 782835981dea9..10f62ab350030 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -70,7 +70,6 @@ import org.apache.ignite.internal.processors.tracing.messages.SpanContainer; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessage; import org.apache.ignite.internal.processors.tracing.messages.TraceableMessagesTable; -import org.apache.ignite.internal.thread.context.DistributedOperationContextManager; import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.internal.util.future.GridFutureAdapter; import org.apache.ignite.internal.util.tostring.GridToStringExclude; diff --git a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java index 8b59975e6fdf5..8caa21403c59e 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java @@ -37,7 +37,6 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteException; import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.configuration.IgniteConfiguration; From 65348cac974e2f5662961878975f1168a1ed801b Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Wed, 24 Jun 2026 17:02:17 +0300 Subject: [PATCH 34/47] raw --- .../org/apache/ignite/internal/IgniteKernal.java | 4 ++-- .../context/DistributedOperationContextManager.java | 12 ++++++------ .../context/OperationContextAttributesTest.java | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java index 3fc9dfe53a976..41832237f4ab2 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java @@ -937,12 +937,12 @@ public void start( ); distrOperationContextMgr = new DistributedOperationContextManager() { - @Override public OperationContextAttribute createDistributedAttribute(byte id, + @Override public OperationContextAttribute registerDistributedAttribute(byte id, @Nullable T initVal) { if (gw.getState() != STARTING) throw new IgniteException("Distributed operation context attributes is registered only at the starting."); - return super.createDistributedAttribute(id, initVal); + return super.registerDistributedAttribute(id, initVal); } }; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java index 925c56ae1d9e3..463b08e2f52e8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java @@ -37,7 +37,7 @@ * {@link OperationContextAttribute} instance that is consistent across all cluster nodes.

* *

To enable propagation of an {@link OperationContextAttribute} value across cluster nodes, the - * attribute must be created using the {@link #createDistributedAttribute(byte, Message)} method. + * attribute must be created using the {@link #registerDistributedAttribute(byte, Message)} method. * *

Note, that the maximum number of distributed attribute instances that can be created is currently limited to * {@link #MAX_DISTRIBUTED_ATTR_CNT} for implementation reasons.

@@ -50,7 +50,7 @@ public class DistributedOperationContextManager { static final byte MAX_DISTRIBUTED_ATTR_CNT = Byte.SIZE; /** Registered distributed attributes by their cluster-wide id. */ - private final Map> attrs = new ConcurrentSkipListMap<>(); + private final Map> attrs = new ConcurrentSkipListMap<>(); /** * Creates a new {@link OperationContext} attribute with the specified distributed ID and initial value. @@ -63,14 +63,14 @@ public class DistributedOperationContextManager { * * @see OperationContextAttribute#newInstance(Object) */ - public OperationContextAttribute createDistributedAttribute(byte id, @Nullable T initVal) { + public OperationContextAttribute registerDistributedAttribute(byte id, OperationContextAttribute attr) { assert id >= 0 && id < MAX_DISTRIBUTED_ATTR_CNT : "Invalid distributed attributed id [id=" + id + ']'; return (OperationContextAttribute)attrs.compute(id, (id0, attr0) -> { if (attr0 != null) throw new IgniteException("Duplicated distributed attribute id [id=" + id + ']'); - return OperationContextAttribute.newInstance(initVal); + return attr; }); } @@ -84,7 +84,7 @@ public OperationContextAttribute createDistributedAttribu DistributedOperationContextMessage res = null; List vals = null; - for (Map.Entry> e : attrs.entrySet()) { + for (Map.Entry> e : attrs.entrySet()) { OperationContextAttribute attr = e.getValue(); Message curVal = OperationContext.get(attr); @@ -128,7 +128,7 @@ public Scope restoreDistributedAttributes(@Nullable DistributedOperationContextM while ((msg.idBitmap & (1 << maskIdx)) == 0) ++maskIdx; - OperationContextAttribute attr = attrs.get(maskIdx++); + OperationContextAttribute attr = (OperationContextAttribute)attrs.get(maskIdx++); assert attr != null; diff --git a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java index 8caa21403c59e..8b443c5887091 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java @@ -860,13 +860,13 @@ public void testSendAttributesByDiscovery() throws Exception { @Override public void start(PluginContext ctx) { // Distributed attribute 1. OperationContextAttribute a1 = ((IgniteEx)ctx.grid()).context() - .distributedOperationContextManager().createDistributedAttribute(attrId1, dfltDistAttr1Val); + .distributedOperationContextManager().registerDistributedAttribute(attrId1, dfltDistAttr1Val); dAttr1.set(a1); // Distributed attribute 2. OperationContextAttribute a2 = ((IgniteEx)ctx.grid()).context() - .distributedOperationContextManager().createDistributedAttribute(attrId2, dfltDistrAttr2Val); + .distributedOperationContextManager().registerDistributedAttribute(attrId2, dfltDistrAttr2Val); dAttr2.set(a2); } @@ -880,7 +880,7 @@ public void testSendAttributesByDiscovery() throws Exception { assertThrows( null, - () -> grid(0).context().distributedOperationContextManager().createDistributedAttribute((byte)1, null), + () -> grid(0).context().distributedOperationContextManager().registerDistributedAttribute((byte)1, null), IgniteException.class, "Distributed operation context attributes is registered only at the starting" ); From 91a65a15f1284135258a9888b2c502c5797d10e4 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Wed, 24 Jun 2026 20:39:23 +0300 Subject: [PATCH 35/47] fixes --- .../apache/ignite/internal/IgniteKernal.java | 8 ++++-- .../DistributedOperationContextManager.java | 4 +-- .../OperationContextAttributesTest.java | 28 ++++++------------- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java index 41832237f4ab2..0482ff5838937 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java @@ -937,12 +937,14 @@ public void start( ); distrOperationContextMgr = new DistributedOperationContextManager() { - @Override public OperationContextAttribute registerDistributedAttribute(byte id, - @Nullable T initVal) { + @Override public void registerDistributedAttribute( + byte id, + OperationContextAttribute attr + ) { if (gw.getState() != STARTING) throw new IgniteException("Distributed operation context attributes is registered only at the starting."); - return super.registerDistributedAttribute(id, initVal); + super.registerDistributedAttribute(id, attr); } }; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java index 463b08e2f52e8..f3b84313a26cd 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java @@ -63,10 +63,10 @@ public class DistributedOperationContextManager { * * @see OperationContextAttribute#newInstance(Object) */ - public OperationContextAttribute registerDistributedAttribute(byte id, OperationContextAttribute attr) { + public void registerDistributedAttribute(byte id, OperationContextAttribute attr) { assert id >= 0 && id < MAX_DISTRIBUTED_ATTR_CNT : "Invalid distributed attributed id [id=" + id + ']'; - return (OperationContextAttribute)attrs.compute(id, (id0, attr0) -> { + attrs.compute(id, (id0, attr0) -> { if (attr0 != null) throw new IgniteException("Duplicated distributed attribute id [id=" + id + ']'); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java index 8b443c5887091..ab382b39a503e 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java @@ -31,7 +31,6 @@ import java.util.concurrent.ForkJoinPool; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Consumer; @@ -849,8 +848,8 @@ public void testSendAttributesByDiscovery() throws Exception { InetSocketAddressMessage dfltDistAttr1Val = new InetSocketAddressMessage(InetAddress.getLoopbackAddress(), 80); GridCacheVersion dfltDistrAttr2Val = new GridCacheVersion(1, 1, 1); - AtomicReference> dAttr1 = new AtomicReference<>(); - AtomicReference> dAttr2 = new AtomicReference<>(); + OperationContextAttribute dAttr1 = OperationContextAttribute.newInstance(dfltDistAttr1Val); + OperationContextAttribute dAttr2 = OperationContextAttribute.newInstance(dfltDistrAttr2Val); pluginProvider = new AbstractTestPluginProvider() { @Override public String name() { @@ -858,17 +857,8 @@ public void testSendAttributesByDiscovery() throws Exception { } @Override public void start(PluginContext ctx) { - // Distributed attribute 1. - OperationContextAttribute a1 = ((IgniteEx)ctx.grid()).context() - .distributedOperationContextManager().registerDistributedAttribute(attrId1, dfltDistAttr1Val); - - dAttr1.set(a1); - - // Distributed attribute 2. - OperationContextAttribute a2 = ((IgniteEx)ctx.grid()).context() - .distributedOperationContextManager().registerDistributedAttribute(attrId2, dfltDistrAttr2Val); - - dAttr2.set(a2); + ((IgniteEx)ctx.grid()).context().distributedOperationContextManager().registerDistributedAttribute(attrId1, dAttr1); + ((IgniteEx)ctx.grid()).context().distributedOperationContextManager().registerDistributedAttribute(attrId2, dAttr2); } }; @@ -903,8 +893,8 @@ public void testSendAttributesByDiscovery() throws Exception { @Override public void onCustomEvent(AffinityTopologyVersion topVer, ClusterNode snd, DynamicCacheChangeBatch msg) { - InetSocketAddressMessage receivedVal1 = OperationContext.get(dAttr1.get()); - GridCacheVersion receivedVal2 = OperationContext.get(dAttr2.get()); + InetSocketAddressMessage receivedVal1 = OperationContext.get(dAttr1); + GridCacheVersion receivedVal2 = OperationContext.get(dAttr2); assertNotNull(receivedVal1); assertNotNull(receivedVal2); @@ -927,7 +917,7 @@ else if (grid(i0).localNode().order() == 1) } // Send from the coordinator. - try (Scope ignored = OperationContext.set(dAttr1.get(), valToSend1, dAttr2.get(), valToSend2)) { + try (Scope ignored = OperationContext.set(dAttr1, valToSend1, dAttr2, valToSend2)) { grid(0).createCache(defaultCacheConfiguration()); } @@ -936,7 +926,7 @@ else if (grid(i0).localNode().order() == 1) assertTrue(waitForCondition(() -> clientLatch.getCount() == 2, getTestTimeout())); // Send from a server. - try (Scope ignored = OperationContext.set(dAttr1.get(), valToSend1, dAttr2.get(), valToSend2)) { + try (Scope ignored = OperationContext.set(dAttr1, valToSend1, dAttr2, valToSend2)) { grid(1).destroyCache(DEFAULT_CACHE_NAME); } @@ -945,7 +935,7 @@ else if (grid(i0).localNode().order() == 1) assertTrue(waitForCondition(() -> clientLatch.getCount() == 1, getTestTimeout())); // Send from a client. - try (Scope ignored = OperationContext.set(dAttr1.get(), valToSend1, dAttr2.get(), valToSend2)) { + try (Scope ignored = OperationContext.set(dAttr1, valToSend1, dAttr2, valToSend2)) { grid(2).createCache(defaultCacheConfiguration()); } From 28844874740d9ea1949e67de05e2575f064bc302 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Wed, 24 Jun 2026 21:14:11 +0300 Subject: [PATCH 36/47] fix --- .../thread/context/DistributedOperationContextManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java index f3b84313a26cd..f91f62294c94c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java @@ -37,7 +37,7 @@ * {@link OperationContextAttribute} instance that is consistent across all cluster nodes.

* *

To enable propagation of an {@link OperationContextAttribute} value across cluster nodes, the - * attribute must be created using the {@link #registerDistributedAttribute(byte, Message)} method. +fi * attribute must be created using the {@link #registerDistributedAttribute(byte, OperationContextAttribute)} method. * *

Note, that the maximum number of distributed attribute instances that can be created is currently limited to * {@link #MAX_DISTRIBUTED_ATTR_CNT} for implementation reasons.

From 915cfd59ecb705f4bff79ee7f531831d1be78137 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 25 Jun 2026 12:51:50 +0300 Subject: [PATCH 37/47] review fixes --- .../apache/ignite/internal/IgniteKernal.java | 18 ++++-------------- .../DistributedOperationContextManager.java | 13 ++++++++++++- .../OperationContextAttributesTest.java | 4 ++-- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java index 0482ff5838937..d06e0fd55f29f 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java @@ -175,7 +175,6 @@ import org.apache.ignite.internal.suggestions.OsConfigurationSuggestions; import org.apache.ignite.internal.systemview.ConfigurationViewWalker; import org.apache.ignite.internal.thread.context.DistributedOperationContextManager; -import org.apache.ignite.internal.thread.context.OperationContextAttribute; import org.apache.ignite.internal.util.TimeBag; import org.apache.ignite.internal.util.future.GridCompoundFuture; import org.apache.ignite.internal.util.future.GridFinishedFuture; @@ -212,7 +211,6 @@ import org.apache.ignite.plugin.IgnitePlugin; import org.apache.ignite.plugin.PluginNotFoundException; import org.apache.ignite.plugin.PluginProvider; -import org.apache.ignite.plugin.extensions.communication.Message; import org.apache.ignite.plugin.extensions.communication.MessageFactory; import org.apache.ignite.plugin.extensions.communication.MessageFactoryProvider; import org.apache.ignite.spi.IgniteSpi; @@ -936,17 +934,7 @@ public void start( longJVMPauseDetector ); - distrOperationContextMgr = new DistributedOperationContextManager() { - @Override public void registerDistributedAttribute( - byte id, - OperationContextAttribute attr - ) { - if (gw.getState() != STARTING) - throw new IgniteException("Distributed operation context attributes is registered only at the starting."); - - super.registerDistributedAttribute(id, attr); - } - }; + distrOperationContextMgr = new DistributedOperationContextManager(); startProcessor(new DiagnosticProcessor(ctx)); @@ -1170,6 +1158,8 @@ public void start( // All components exept Discovery are started, time to check if maintenance is still needed. mntcProc.prepareAndExecuteMaintenance(); + distrOperationContextMgr.initialized(); + gw.writeLock(); try { @@ -3077,7 +3067,7 @@ MessageFactory messageFactory() { return msgFactory; } - /** @return Instance of {@link DistributedOperationContextManager}. */ + /** @return Distributed operation context manager. */ DistributedOperationContextManager distributedOperationContextManager() { return distrOperationContextMgr; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java index f91f62294c94c..9cb79f7fe5bcb 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java @@ -37,7 +37,7 @@ * {@link OperationContextAttribute} instance that is consistent across all cluster nodes.

* *

To enable propagation of an {@link OperationContextAttribute} value across cluster nodes, the -fi * attribute must be created using the {@link #registerDistributedAttribute(byte, OperationContextAttribute)} method. + * attribute must be created using the {@link #registerDistributedAttribute(byte, OperationContextAttribute)} method. * *

Note, that the maximum number of distributed attribute instances that can be created is currently limited to * {@link #MAX_DISTRIBUTED_ATTR_CNT} for implementation reasons.

@@ -52,6 +52,9 @@ public class DistributedOperationContextManager { /** Registered distributed attributes by their cluster-wide id. */ private final Map> attrs = new ConcurrentSkipListMap<>(); + /** The initialization flag. */ + private volatile boolean initialized; + /** * Creates a new {@link OperationContext} attribute with the specified distributed ID and initial value. * @@ -64,6 +67,9 @@ public class DistributedOperationContextManager { * @see OperationContextAttribute#newInstance(Object) */ public void registerDistributedAttribute(byte id, OperationContextAttribute attr) { + if (initialized) + throw new IgniteException("Initialization of distributed operation context attributes has already finished."); + assert id >= 0 && id < MAX_DISTRIBUTED_ATTR_CNT : "Invalid distributed attributed id [id=" + id + ']'; attrs.compute(id, (id0, attr0) -> { @@ -137,4 +143,9 @@ public Scope restoreDistributedAttributes(@Nullable DistributedOperationContextM return updater.apply(); } + + /** Deprecated fuhrter filling of distributed attributes. */ + public void initialized() { + initialized = true; + } } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java index ab382b39a503e..4874367dfca7b 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java @@ -853,7 +853,7 @@ public void testSendAttributesByDiscovery() throws Exception { pluginProvider = new AbstractTestPluginProvider() { @Override public String name() { - return "DistributedOperationContextAttributesRegistrator"; + return "TestDistributedOperationContextAttributesRegistrator"; } @Override public void start(PluginContext ctx) { @@ -872,7 +872,7 @@ public void testSendAttributesByDiscovery() throws Exception { null, () -> grid(0).context().distributedOperationContextManager().registerDistributedAttribute((byte)1, null), IgniteException.class, - "Distributed operation context attributes is registered only at the starting" + "Initialization of distributed operation context attributes has already finished" ); // Local attribute 2. From 48d9dcfd18406faf7a8483ff3e855c12a3d68767 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 25 Jun 2026 13:18:12 +0300 Subject: [PATCH 38/47] renaming --- .../ignite/internal/CoreMessagesProvider.java | 2 +- .../ignite/internal/GridKernalContext.java | 8 ++++---- .../ignite/internal/GridKernalContextImpl.java | 4 ++-- .../org/apache/ignite/internal/IgniteKernal.java | 16 ++++++++-------- ...Message.java => OperationContextMessage.java} | 10 +++++----- .../wal/reader/StandaloneGridKernalContext.java | 4 ++-- ...ager.java => OperationContextDispatcher.java} | 14 +++++++------- .../ignite/spi/discovery/tcp/ClientImpl.java | 4 ++-- .../ignite/spi/discovery/tcp/ServerImpl.java | 4 ++-- .../spi/discovery/tcp/TcpDiscoveryImpl.java | 8 ++++---- .../messages/TcpDiscoveryAbstractMessage.java | 4 ++-- .../context/OperationContextAttributesTest.java | 8 ++++---- 12 files changed, 43 insertions(+), 43 deletions(-) rename modules/core/src/main/java/org/apache/ignite/internal/{DistributedOperationContextMessage.java => OperationContextMessage.java} (79%) rename modules/core/src/main/java/org/apache/ignite/internal/thread/context/{DistributedOperationContextManager.java => OperationContextDispatcher.java} (92%) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java index cc0ab3e112b7d..f721b71764636 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java @@ -668,7 +668,7 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C // [13400 - 13600]: Operation context messages. msgIdx = 13400; - withNoSchema(DistributedOperationContextMessage.class); + withNoSchema(OperationContextMessage.class); assert msgIdx <= MAX_MESSAGE_ID; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java index 42c800d27bd7f..cab4d2a814686 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java @@ -78,7 +78,7 @@ import org.apache.ignite.internal.processors.timeout.GridTimeoutProcessor; import org.apache.ignite.internal.processors.tracing.Tracing; import org.apache.ignite.internal.suggestions.GridPerformanceSuggestions; -import org.apache.ignite.internal.thread.context.DistributedOperationContextManager; +import org.apache.ignite.internal.thread.context.OperationContextDispatcher; import org.apache.ignite.internal.util.IgniteExceptionRegistry; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.worker.WorkersRegistry; @@ -219,11 +219,11 @@ public interface GridKernalContext extends Iterable { public MessageFactory messageFactory(); /** - * Gets the distributed operation context manager. + * Gets the distributed operation context dispatcher. * - * @return The distributed operation context manager. + * @return The distributed operation context dispatcher. */ - public DistributedOperationContextManager distributedOperationContextManager(); + public OperationContextDispatcher operationContextDispatcher(); /** * Gets transformation processor. diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java index 741b99632fe99..b090e333a3cb7 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java @@ -101,7 +101,7 @@ import org.apache.ignite.internal.processors.timeout.GridTimeoutProcessor; import org.apache.ignite.internal.processors.tracing.Tracing; import org.apache.ignite.internal.suggestions.GridPerformanceSuggestions; -import org.apache.ignite.internal.thread.context.DistributedOperationContextManager; +import org.apache.ignite.internal.thread.context.OperationContextDispatcher; import org.apache.ignite.internal.thread.pool.IgniteForkJoinPool; import org.apache.ignite.internal.util.IgniteExceptionRegistry; import org.apache.ignite.internal.util.spring.IgniteSpringHelper; @@ -699,7 +699,7 @@ else if (!(comp instanceof DiscoveryNodeValidationProcessor } /** {@inheritDoc} */ - @Override public DistributedOperationContextManager distributedOperationContextManager() { + @Override public OperationContextDispatcher operationContextDispatcher() { return grid.distributedOperationContextManager(); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java index d06e0fd55f29f..eb6b7b3889bd5 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java @@ -174,7 +174,7 @@ import org.apache.ignite.internal.suggestions.JvmConfigurationSuggestions; import org.apache.ignite.internal.suggestions.OsConfigurationSuggestions; import org.apache.ignite.internal.systemview.ConfigurationViewWalker; -import org.apache.ignite.internal.thread.context.DistributedOperationContextManager; +import org.apache.ignite.internal.thread.context.OperationContextDispatcher; import org.apache.ignite.internal.util.TimeBag; import org.apache.ignite.internal.util.future.GridCompoundFuture; import org.apache.ignite.internal.util.future.GridFinishedFuture; @@ -445,8 +445,8 @@ public class IgniteKernal implements IgniteEx, Externalizable { /** Core message factory. */ private MessageFactory msgFactory; - /** */ - private DistributedOperationContextManager distrOperationContextMgr; + /** Distributed operation context dispatcher. */ + private OperationContextDispatcher operationCtxDispatcher; /** * No-arg constructor is required by externalization. @@ -934,7 +934,7 @@ public void start( longJVMPauseDetector ); - distrOperationContextMgr = new DistributedOperationContextManager(); + operationCtxDispatcher = new OperationContextDispatcher(); startProcessor(new DiagnosticProcessor(ctx)); @@ -1158,7 +1158,7 @@ public void start( // All components exept Discovery are started, time to check if maintenance is still needed. mntcProc.prepareAndExecuteMaintenance(); - distrOperationContextMgr.initialized(); + operationCtxDispatcher.initialized(); gw.writeLock(); @@ -3067,9 +3067,9 @@ MessageFactory messageFactory() { return msgFactory; } - /** @return Distributed operation context manager. */ - DistributedOperationContextManager distributedOperationContextManager() { - return distrOperationContextMgr; + /** @return Distributed operation context dispatcher. */ + OperationContextDispatcher distributedOperationContextManager() { + return operationCtxDispatcher; } /** diff --git a/modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/OperationContextMessage.java similarity index 79% rename from modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextMessage.java rename to modules/core/src/main/java/org/apache/ignite/internal/OperationContextMessage.java index 42d5c7eda859a..f556080208589 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/DistributedOperationContextMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/OperationContextMessage.java @@ -17,16 +17,16 @@ package org.apache.ignite.internal; -import org.apache.ignite.internal.thread.context.DistributedOperationContextManager; +import org.apache.ignite.internal.thread.context.OperationContextDispatcher; import org.apache.ignite.internal.thread.context.OperationContext; import org.apache.ignite.plugin.extensions.communication.Message; /** - * Transport for {@link OperationContext} distributed attributes. + * Message for {@link OperationContext} distributed attributes. * - * @see DistributedOperationContextManager + * @see OperationContextDispatcher */ -public class DistributedOperationContextMessage implements Message { +public class OperationContextMessage implements Message { /** Values of operation context attributes. */ @Order(0) public Message[] vals; @@ -36,7 +36,7 @@ public class DistributedOperationContextMessage implements Message { public byte idBitmap; /** Empty constructor for serialization purposes. */ - public DistributedOperationContextMessage() { + public OperationContextMessage() { // No-op. } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java index 29a6bb32ce0e2..a03e646982caf 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java @@ -103,7 +103,7 @@ import org.apache.ignite.internal.processors.tracing.NoopTracing; import org.apache.ignite.internal.processors.tracing.Tracing; import org.apache.ignite.internal.suggestions.GridPerformanceSuggestions; -import org.apache.ignite.internal.thread.context.DistributedOperationContextManager; +import org.apache.ignite.internal.thread.context.OperationContextDispatcher; import org.apache.ignite.internal.util.IgniteExceptionRegistry; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.typedef.internal.U; @@ -456,7 +456,7 @@ private void setField(IgniteEx kernal, String name, Object val) throws NoSuchFie } /** {@inheritDoc} */ - @Override public DistributedOperationContextManager distributedOperationContextManager() { + @Override public OperationContextDispatcher operationContextDispatcher() { return null; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java similarity index 92% rename from modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java rename to modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java index 9cb79f7fe5bcb..cb59bbfbd1b13 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/DistributedOperationContextManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java @@ -21,7 +21,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentSkipListMap; import org.apache.ignite.IgniteException; -import org.apache.ignite.internal.DistributedOperationContextMessage; +import org.apache.ignite.internal.OperationContextMessage; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.plugin.extensions.communication.Message; import org.jetbrains.annotations.Nullable; @@ -43,9 +43,9 @@ * {@link #MAX_DISTRIBUTED_ATTR_CNT} for implementation reasons.

* * @see OperationContext - * @see DistributedOperationContextMessage + * @see OperationContextMessage */ -public class DistributedOperationContextManager { +public class OperationContextDispatcher { /** Maximal number of supported distributed attributes. */ static final byte MAX_DISTRIBUTED_ATTR_CNT = Byte.SIZE; @@ -86,8 +86,8 @@ public void registerDistributedAttribute(byte id, OperationC * * @see OperationContext#get(OperationContextAttribute) */ - public @Nullable DistributedOperationContextMessage collectDistributedAttributes() { - DistributedOperationContextMessage res = null; + public @Nullable OperationContextMessage collectDistributedAttributes() { + OperationContextMessage res = null; List vals = null; for (Map.Entry> e : attrs.entrySet()) { @@ -97,7 +97,7 @@ public void registerDistributedAttribute(byte id, OperationC if (curVal != attr.initialValue()) { if (res == null) { - res = new DistributedOperationContextMessage(); + res = new OperationContextMessage(); vals = new ArrayList<>(MAX_DISTRIBUTED_ATTR_CNT / 2); } @@ -118,7 +118,7 @@ public void registerDistributedAttribute(byte id, OperationC } /** Restores distributed {@link OperationContextAttribute} values received from a remote node. */ - public Scope restoreDistributedAttributes(@Nullable DistributedOperationContextMessage msg) { + public Scope restoreDistributedAttributes(@Nullable OperationContextMessage msg) { if (msg == null) return Scope.NOOP_SCOPE; diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java index 10f62ab350030..86a4f190026d2 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ClientImpl.java @@ -1311,7 +1311,7 @@ private class SocketWriter extends IgniteSpiThread { * @param msg Message. */ private void sendMessage(TcpDiscoveryAbstractMessage msg) { - msg.opCtxMsg = distrOperationContextMgr.collectDistributedAttributes(); + msg.opCtxMsg = operationCtxDispatcher.collectDistributedAttributes(); synchronized (mux) { queue.add(msg); @@ -1764,7 +1764,7 @@ private MessageWorker(IgniteLogger log) { ? (TcpDiscoveryAbstractMessage)msg : null; - try (Scope ignored = distrOperationContextMgr.restoreDistributedAttributes(dm == null ? null : dm.opCtxMsg)) { + try (Scope ignored = operationCtxDispatcher.restoreDistributedAttributes(dm == null ? null : dm.opCtxMsg)) { if (msg instanceof JoinTimeout) { int joinCnt0 = ((JoinTimeout)msg).joinCnt; diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java index 30d289355717b..8572ece8da31f 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java @@ -3048,7 +3048,7 @@ void addMessage(TcpDiscoveryAbstractMessage msg, boolean ignoreHighPriority, boo } if (!fromSocket) - msg.opCtxMsg = distrOperationContextMgr.collectDistributedAttributes(); + msg.opCtxMsg = operationCtxDispatcher.collectDistributedAttributes(); if (msg instanceof TraceableMessage tMsg) { @@ -3320,7 +3320,7 @@ else if (msg instanceof TcpDiscoveryAuthFailedMessage) if (msg == WAKEUP) return; - try (Scope ignored = distrOperationContextMgr.restoreDistributedAttributes(msg.opCtxMsg)) { + try (Scope ignored = operationCtxDispatcher.restoreDistributedAttributes(msg.opCtxMsg)) { processMessage0(msg); } } diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java index abab4e3de3944..25ad69c147fea 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java @@ -43,7 +43,7 @@ import org.apache.ignite.internal.processors.cluster.NodeMetricsMessage; import org.apache.ignite.internal.processors.tracing.NoopTracing; import org.apache.ignite.internal.processors.tracing.Tracing; -import org.apache.ignite.internal.thread.context.DistributedOperationContextManager; +import org.apache.ignite.internal.thread.context.OperationContextDispatcher; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.LT; import org.apache.ignite.internal.util.typedef.internal.U; @@ -140,8 +140,8 @@ abstract class TcpDiscoveryImpl { /** Tracing. */ protected Tracing tracing; - /** */ - protected final DistributedOperationContextManager distrOperationContextMgr; + /** Distributed operation context dispatcher. */ + protected final OperationContextDispatcher operationCtxDispatcher; /** * @param spi Adapter. @@ -156,7 +156,7 @@ abstract class TcpDiscoveryImpl { else tracing = new NoopTracing(); - distrOperationContextMgr = ((IgniteEx)spi.ignite()).context().distributedOperationContextManager(); + operationCtxDispatcher = ((IgniteEx)spi.ignite()).context().operationContextDispatcher(); } /** diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java index 60c38866034e6..5f09498060e2d 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java @@ -21,7 +21,7 @@ import java.util.HashSet; import java.util.Set; import java.util.UUID; -import org.apache.ignite.internal.DistributedOperationContextMessage; +import org.apache.ignite.internal.OperationContextMessage; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.tostring.GridToStringInclude; @@ -80,7 +80,7 @@ public abstract class TcpDiscoveryAbstractMessage implements Message { /** Operation context attributes message. */ @GridToStringInclude @Order(5) - public @Nullable DistributedOperationContextMessage opCtxMsg; + public @Nullable OperationContextMessage opCtxMsg; /** * Default no-arg constructor for {@link Externalizable} interface. diff --git a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java index 4874367dfca7b..7602a5f75b884 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java @@ -843,7 +843,7 @@ public void testContextAwareDelayQueue() throws Exception { @Test public void testSendAttributesByDiscovery() throws Exception { byte attrId1 = 0; - byte attrId2 = DistributedOperationContextManager.MAX_DISTRIBUTED_ATTR_CNT - 1; + byte attrId2 = OperationContextDispatcher.MAX_DISTRIBUTED_ATTR_CNT - 1; InetSocketAddressMessage dfltDistAttr1Val = new InetSocketAddressMessage(InetAddress.getLoopbackAddress(), 80); GridCacheVersion dfltDistrAttr2Val = new GridCacheVersion(1, 1, 1); @@ -857,8 +857,8 @@ public void testSendAttributesByDiscovery() throws Exception { } @Override public void start(PluginContext ctx) { - ((IgniteEx)ctx.grid()).context().distributedOperationContextManager().registerDistributedAttribute(attrId1, dAttr1); - ((IgniteEx)ctx.grid()).context().distributedOperationContextManager().registerDistributedAttribute(attrId2, dAttr2); + ((IgniteEx)ctx.grid()).context().operationContextDispatcher().registerDistributedAttribute(attrId1, dAttr1); + ((IgniteEx)ctx.grid()).context().operationContextDispatcher().registerDistributedAttribute(attrId2, dAttr2); } }; @@ -870,7 +870,7 @@ public void testSendAttributesByDiscovery() throws Exception { assertThrows( null, - () -> grid(0).context().distributedOperationContextManager().registerDistributedAttribute((byte)1, null), + () -> grid(0).context().operationContextDispatcher().registerDistributedAttribute((byte)1, null), IgniteException.class, "Initialization of distributed operation context attributes has already finished" ); From 4fb30a566a60e341a450d73374e8cbfd47346874 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 25 Jun 2026 14:09:23 +0300 Subject: [PATCH 39/47] fixes --- .../internal/GridKernalContextImpl.java | 2 +- .../apache/ignite/internal/IgniteKernal.java | 2 +- .../internal/OperationContextMessage.java | 2 +- .../managers/communication/GridIoManager.java | 5 +- .../managers/communication/GridIoMessage.java | 6 +- .../context/OperationContextDispatcher.java | 6 - .../OperationContextAttributesTest.java | 116 +++++++++--------- 7 files changed, 68 insertions(+), 71 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java index b090e333a3cb7..fb3dcdb3412a7 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java @@ -700,7 +700,7 @@ else if (!(comp instanceof DiscoveryNodeValidationProcessor /** {@inheritDoc} */ @Override public OperationContextDispatcher operationContextDispatcher() { - return grid.distributedOperationContextManager(); + return grid.operationContextDispatcher(); } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java index eb6b7b3889bd5..f9cb0a9523bef 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java @@ -3068,7 +3068,7 @@ MessageFactory messageFactory() { } /** @return Distributed operation context dispatcher. */ - OperationContextDispatcher distributedOperationContextManager() { + OperationContextDispatcher operationContextDispatcher() { return operationCtxDispatcher; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/OperationContextMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/OperationContextMessage.java index f556080208589..9dc9fdb82ccea 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/OperationContextMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/OperationContextMessage.java @@ -17,8 +17,8 @@ package org.apache.ignite.internal; -import org.apache.ignite.internal.thread.context.OperationContextDispatcher; import org.apache.ignite.internal.thread.context.OperationContext; +import org.apache.ignite.internal.thread.context.OperationContextDispatcher; import org.apache.ignite.plugin.extensions.communication.Message; /** diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java index bdbc375fc9ff3..a83e6ae8e7d41 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java @@ -102,7 +102,6 @@ import org.apache.ignite.internal.processors.tracing.MTC.TraceSurroundings; import org.apache.ignite.internal.processors.tracing.Span; import org.apache.ignite.internal.processors.tracing.SpanTags; -import org.apache.ignite.internal.thread.context.DistributedOperationContextManager; import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashSet; import org.apache.ignite.internal.util.IgniteUtils; @@ -461,7 +460,7 @@ public void resetMetrics() { try { GridIoMessage msg0 = (GridIoMessage)msg; - try (Scope ignored = DistributedOperationContextManager.instance().restoreDistributedAttributes(msg0.opCtxMsg)) { + try (Scope ignored = ctx.operationContextDispatcher().restoreDistributedAttributes(msg0.opCtxMsg)) { onMessage0(nodeId, msg0, msgC); } } @@ -2055,7 +2054,7 @@ private long getInverseConnectionWaitTimeout() { else res = new GridIoMessage(plc, topic, msg, ordered, timeout, skipOnTimeout); - res.opCtxMsg = DistributedOperationContextManager.instance().collectDistributedAttributes(); + res.opCtxMsg = ctx.operationContextDispatcher().collectDistributedAttributes(); return res; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessage.java index cb09122415def..1865868a71a53 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessage.java @@ -17,9 +17,9 @@ package org.apache.ignite.internal.managers.communication; -import org.apache.ignite.internal.DistributedOperationContextMessage; import org.apache.ignite.internal.ExecutorAwareMessage; import org.apache.ignite.internal.GridTopicMessage; +import org.apache.ignite.internal.OperationContextMessage; import org.apache.ignite.internal.Order; import org.apache.ignite.internal.processors.cache.GridCacheMessage; import org.apache.ignite.internal.processors.datastreamer.DataStreamerRequest; @@ -65,10 +65,10 @@ public class GridIoMessage implements Message, SpanTransport { @Order(6) byte[] span; - /** Effective operation context attributes. */ + /** Effective operation context attributes to propagate. */ @Order(7) @GridToStringInclude - public @Nullable DistributedOperationContextMessage opCtxMsg; + public @Nullable OperationContextMessage opCtxMsg; /** * Default constructor. diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java index ab6ee17a44b90..cb59bbfbd1b13 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java @@ -144,14 +144,8 @@ public Scope restoreDistributedAttributes(@Nullable OperationContextMessage msg) return updater.apply(); } - /** Deprecated fuhrter filling of distributed attributes. */ public void initialized() { initialized = true; } - - /** For testing purposes mostly. */ - void clear() { - attrs.clear(); - } } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java index 6a8e8c42f46e1..c5545275a4aad 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java @@ -40,6 +40,9 @@ import org.apache.ignite.Ignite; import org.apache.ignite.IgniteException; import org.apache.ignite.cluster.ClusterNode; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.GridTopic; +import org.apache.ignite.internal.IgniteEx; import org.apache.ignite.internal.IgniteInternalFuture; import org.apache.ignite.internal.managers.communication.GridIoPolicy; import org.apache.ignite.internal.managers.communication.GridMessageListener; @@ -126,8 +129,6 @@ public class OperationContextAttributesTest extends GridCommonAbstractTest { // Releases attribute IDs reserved during the test. OperationContextAttribute.ID_GEN.set(beforeTestReservedAttrIds); - - DistributedOperationContextManager.instance().clear(); } /** {@inheritDoc} */ @@ -846,14 +847,11 @@ public void testContextAwareDelayQueue() throws Exception { /** */ @Test public void testSendAttributesByDiscovery() throws Exception { - byte attrId1 = 0; - byte attrId2 = OperationContextDispatcher.MAX_DISTRIBUTED_ATTR_CNT - 1; - - InetSocketAddressMessage dfltDistAttr1Val = new InetSocketAddressMessage(InetAddress.getLoopbackAddress(), 80); - GridCacheVersion dfltDistrAttr2Val = new GridCacheVersion(1, 1, 1); + OperationContextAttribute dAttr1 = + OperationContextAttribute.newInstance(new InetSocketAddressMessage(InetAddress.getLoopbackAddress(), 80)); - OperationContextAttribute dAttr1 = OperationContextAttribute.newInstance(dfltDistAttr1Val); - OperationContextAttribute dAttr2 = OperationContextAttribute.newInstance(dfltDistrAttr2Val); + OperationContextAttribute dAttr2 = + OperationContextAttribute.newInstance(new GridCacheVersion(1, 1, 1)); pluginProvider = new AbstractTestPluginProvider() { @Override public String name() { @@ -861,8 +859,12 @@ public void testSendAttributesByDiscovery() throws Exception { } @Override public void start(PluginContext ctx) { - ((IgniteEx)ctx.grid()).context().operationContextDispatcher().registerDistributedAttribute(attrId1, dAttr1); - ((IgniteEx)ctx.grid()).context().operationContextDispatcher().registerDistributedAttribute(attrId2, dAttr2); + ((IgniteEx)ctx.grid()).context().operationContextDispatcher().registerDistributedAttribute((byte)0, dAttr1); + + ((IgniteEx)ctx.grid()).context().operationContextDispatcher().registerDistributedAttribute( + (byte)(OperationContextDispatcher.MAX_DISTRIBUTED_ATTR_CNT - 1), + dAttr2 + ); } }; @@ -886,7 +888,7 @@ public void testSendAttributesByDiscovery() throws Exception { CountDownLatch srvrLatch = new CountDownLatch(3); CountDownLatch clientLatch = new CountDownLatch(3); - InetSocketAddressMessage valToSend1 = new InetSocketAddressMessage(dfltDistAttr1Val.address(), 443); + InetSocketAddressMessage valToSend1 = new InetSocketAddressMessage(dAttr1.initialValue().address(), 443); GridCacheVersion valToSend2 = new GridCacheVersion(2, 2, 2); for (int i = 0; i < G.allGrids().size(); ++i) { @@ -900,15 +902,10 @@ public void testSendAttributesByDiscovery() throws Exception { InetSocketAddressMessage receivedVal1 = OperationContext.get(dAttr1); GridCacheVersion receivedVal2 = OperationContext.get(dAttr2); - assertNotNull(receivedVal1); - assertNotNull(receivedVal2); + assertTrue(receivedVal1 != null && valToSend1.port() == receivedVal1.port()); + assertTrue(receivedVal1 != null && valToSend1.address().equals(receivedVal1.address())); - assertFalse(dfltDistAttr1Val.port() == receivedVal1.port()); - assertEquals(receivedVal1.port(), valToSend1.port()); - assertEquals(receivedVal1.address(), valToSend1.address()); - - assertFalse(dfltDistrAttr2Val.equals(receivedVal2)); - assertTrue(valToSend2.equals(receivedVal2)); + assertEquals(valToSend2, receivedVal2); if (grid(i0).localNode().isClient()) clientLatch.countDown(); @@ -951,31 +948,38 @@ else if (grid(i0).localNode().order() == 1) /** */ @Test public void testSendAttributesByCommunication() throws Exception { - byte attrId1 = 0; - byte attrId2 = DistributedOperationContextManager.MAX_DISTRIBUTED_ATTR_CNT - 1; + OperationContextAttribute dAttr1 = + OperationContextAttribute.newInstance(new InetSocketAddressMessage(InetAddress.getLoopbackAddress(), 80)); - InetSocketAddressMessage dfltDistrAttr1Val = new InetSocketAddressMessage(InetAddress.getLoopbackAddress(), 80); - GridCacheVersion dfltDistrAttr2Val = new GridCacheVersion(1, 1, 1); + OperationContextAttribute dAttr2 = + OperationContextAttribute.newInstance(new GridCacheVersion(1, 1, 1)); - // Local attribute 1. - OperationContextAttribute.newInstance(1000); + pluginProvider = new AbstractTestPluginProvider() { + @Override public String name() { + return "TestDistributedOperationContextAttributesRegistrator"; + } - // Distributed attribute 1. - OperationContextAttribute dAttr0 = DistributedOperationContextManager.instance() - .createDistributedAttribute(attrId1, dfltDistrAttr1Val); + @Override public void start(PluginContext ctx) { + ((IgniteEx)ctx.grid()).context().operationContextDispatcher().registerDistributedAttribute((byte)0, dAttr1); - // Local attribute 2. - OperationContextAttribute.newInstance("locaAttr2"); + ((IgniteEx)ctx.grid()).context().operationContextDispatcher().registerDistributedAttribute( + (byte)(OperationContextDispatcher.MAX_DISTRIBUTED_ATTR_CNT - 1), + dAttr2 + ); + } + }; - // Distributed attribute 2. - OperationContextAttribute dAttr1 = DistributedOperationContextManager.instance() - .createDistributedAttribute(attrId2, dfltDistrAttr2Val); + // Local attribute 1. + OperationContextAttribute.newInstance(1000); startGrids(2); startClientGrid(2); - InetSocketAddressMessage valToSend0 = new InetSocketAddressMessage(dfltDistrAttr1Val.address(), 443); - GridCacheVersion valToSend1 = new GridCacheVersion(2, 2, 2); + // Local attribute 2. + OperationContextAttribute.newInstance("locaAttr2"); + + InetSocketAddressMessage valToSend1 = new InetSocketAddressMessage(dAttr1.initialValue().address(), 443); + GridCacheVersion valToSend2 = new GridCacheVersion(2, 2, 2); // Coordinator -> Server, Coordinator -> Client, Server -> Client, Client -> Server, etc. for (int fromIdx = 0; fromIdx < 3; ++fromIdx) { @@ -984,13 +988,13 @@ public void testSendAttributesByCommunication() throws Exception { continue; // One value. - try (Scope ignored = OperationContext.set(dAttr0, valToSend0)) { - checkOperationContextCommunicationTransmission(fromIdx, toIdx, dAttr0, null); + try (Scope ignored = OperationContext.set(dAttr1, valToSend1)) { + checkOperationContextCommunicationTransmission(fromIdx, toIdx, dAttr1, null); } // A couple of values. - try (Scope ignored = OperationContext.set(dAttr0, valToSend0, dAttr1, valToSend1)) { - checkOperationContextCommunicationTransmission(fromIdx, toIdx, dAttr0, dAttr1); + try (Scope ignored = OperationContext.set(dAttr1, valToSend1, dAttr2, valToSend2)) { + checkOperationContextCommunicationTransmission(fromIdx, toIdx, dAttr1, dAttr2); } } } @@ -1000,44 +1004,44 @@ public void testSendAttributesByCommunication() throws Exception { private void checkOperationContextCommunicationTransmission( int gridFromIdx, int gridToIdx, - OperationContextAttribute attr0, - @Nullable OperationContextAttribute attr1 + OperationContextAttribute attr1, + @Nullable OperationContextAttribute attr2 ) throws InterruptedException { - Ignite from = grid(gridFromIdx); - Ignite to = grid(gridToIdx); + IgniteEx from = grid(gridFromIdx); + IgniteEx to = grid(gridToIdx); CountDownLatch rcvLatch = new CountDownLatch(2); - InetSocketAddressMessage expVal0 = OperationContext.get(attr0); - GridCacheVersion expVal1 = attr1 == null ? null : OperationContext.get(attr1); + InetSocketAddressMessage expVal1 = OperationContext.get(attr1); + GridCacheVersion expVal2 = attr2 == null ? null : OperationContext.get(attr2); GridMessageListener lsnr = new GridMessageListener() { @Override public void onMessage(UUID nodeId, Object msg, byte plc) { if (msg instanceof IgniteIoTestMessage && ((IgniteIoTestMessage)msg).request()) { - InetSocketAddressMessage receivedVal0 = OperationContext.get(attr0); - GridCacheVersion receivedVal1 = attr1 == null ? null : OperationContext.get(attr1); + InetSocketAddressMessage receivedVal1 = OperationContext.get(attr1); + GridCacheVersion receivedVal2 = attr2 == null ? null : OperationContext.get(attr2); - assertTrue(receivedVal0 != null && expVal0.port() == receivedVal0.port()); - assertTrue(receivedVal0 != null && expVal0.address().equals(receivedVal0.address())); + assertTrue(receivedVal1 != null && expVal1.port() == receivedVal1.port()); + assertTrue(receivedVal1 != null && expVal1.address().equals(receivedVal1.address())); - if (attr1 != null) - assertEquals(expVal1, receivedVal1); + if (attr2 != null) + assertEquals(expVal2, receivedVal2); rcvLatch.countDown(); } } }; - ((IgniteEx)to).context().io().addMessageListener(GridTopic.TOPIC_IO_TEST, lsnr); + to.context().io().addMessageListener(GridTopic.TOPIC_IO_TEST, lsnr); try { - ((IgniteEx)from).context().io().sendIoTest(node(from, to), null, false); - ((IgniteEx)from).context().io().sendIoTest(node(from, to), null, true); + from.context().io().sendIoTest(node(from, to), null, false); + from.context().io().sendIoTest(node(from, to), null, true); assertTrue(rcvLatch.await(getTestTimeout(), MILLISECONDS)); } finally { - assertTrue(((IgniteEx)to).context().io().removeMessageListener(GridTopic.TOPIC_IO_TEST, lsnr)); + assertTrue(to.context().io().removeMessageListener(GridTopic.TOPIC_IO_TEST, lsnr)); } } From 048ed2f478cc5e3970f97e0cff8ee82326def049 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 25 Jun 2026 14:23:40 +0300 Subject: [PATCH 40/47] test refactoring --- .../OperationContextAttributesTest.java | 73 +++++++++---------- 1 file changed, 34 insertions(+), 39 deletions(-) diff --git a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java index c5545275a4aad..9d5f1d6a87962 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java @@ -847,6 +847,17 @@ public void testContextAwareDelayQueue() throws Exception { /** */ @Test public void testSendAttributesByDiscovery() throws Exception { + doTestOperationContextAttributesPropagation(true); + } + + /** */ + @Test + public void testSendAttributesByCommunication() throws Exception { + doTestOperationContextAttributesPropagation(false); + } + + /** */ + private void doTestOperationContextAttributesPropagation(boolean discovery) throws Exception { OperationContextAttribute dAttr1 = OperationContextAttribute.newInstance(new InetSocketAddressMessage(InetAddress.getLoopbackAddress(), 80)); @@ -884,13 +895,26 @@ public void testSendAttributesByDiscovery() throws Exception { // Local attribute 2. OperationContextAttribute.newInstance("locaAttr2"); + InetSocketAddressMessage valToSend1 = new InetSocketAddressMessage(dAttr1.initialValue().address(), 443); + GridCacheVersion valToSend2 = new GridCacheVersion(2, 2, 2); + + if (discovery) + doTestOperationContextAttributesPropagationThroughDiscovery(dAttr1, valToSend1, dAttr2, valToSend2); + else + doTestOperationContextAttributesPropagationThroughCommunication(dAttr1, valToSend1, dAttr2, valToSend2); + } + + /** */ + private void doTestOperationContextAttributesPropagationThroughDiscovery( + OperationContextAttribute dAttr1, + InetSocketAddressMessage valToSend1, + OperationContextAttribute dAttr2, + GridCacheVersion valToSend2 + ) throws Exception { CountDownLatch coordLatch = new CountDownLatch(3); CountDownLatch srvrLatch = new CountDownLatch(3); CountDownLatch clientLatch = new CountDownLatch(3); - InetSocketAddressMessage valToSend1 = new InetSocketAddressMessage(dAttr1.initialValue().address(), 443); - GridCacheVersion valToSend2 = new GridCacheVersion(2, 2, 2); - for (int i = 0; i < G.allGrids().size(); ++i) { int i0 = i; @@ -946,41 +970,12 @@ else if (grid(i0).localNode().order() == 1) } /** */ - @Test - public void testSendAttributesByCommunication() throws Exception { - OperationContextAttribute dAttr1 = - OperationContextAttribute.newInstance(new InetSocketAddressMessage(InetAddress.getLoopbackAddress(), 80)); - - OperationContextAttribute dAttr2 = - OperationContextAttribute.newInstance(new GridCacheVersion(1, 1, 1)); - - pluginProvider = new AbstractTestPluginProvider() { - @Override public String name() { - return "TestDistributedOperationContextAttributesRegistrator"; - } - - @Override public void start(PluginContext ctx) { - ((IgniteEx)ctx.grid()).context().operationContextDispatcher().registerDistributedAttribute((byte)0, dAttr1); - - ((IgniteEx)ctx.grid()).context().operationContextDispatcher().registerDistributedAttribute( - (byte)(OperationContextDispatcher.MAX_DISTRIBUTED_ATTR_CNT - 1), - dAttr2 - ); - } - }; - - // Local attribute 1. - OperationContextAttribute.newInstance(1000); - - startGrids(2); - startClientGrid(2); - - // Local attribute 2. - OperationContextAttribute.newInstance("locaAttr2"); - - InetSocketAddressMessage valToSend1 = new InetSocketAddressMessage(dAttr1.initialValue().address(), 443); - GridCacheVersion valToSend2 = new GridCacheVersion(2, 2, 2); - + private void doTestOperationContextAttributesPropagationThroughCommunication( + OperationContextAttribute dAttr1, + InetSocketAddressMessage valToSend1, + OperationContextAttribute dAttr2, + GridCacheVersion valToSend2 + ) throws Exception { // Coordinator -> Server, Coordinator -> Client, Server -> Client, Client -> Server, etc. for (int fromIdx = 0; fromIdx < 3; ++fromIdx) { for (int toIdx = 0; toIdx < 3; ++toIdx) { @@ -1006,7 +1001,7 @@ private void checkOperationContextCommunicationTransmission( int gridToIdx, OperationContextAttribute attr1, @Nullable OperationContextAttribute attr2 - ) throws InterruptedException { + ) throws Exception { IgniteEx from = grid(gridFromIdx); IgniteEx to = grid(gridToIdx); From 5cee094511275c28573ceb0208de8a25913bf1f2 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 25 Jun 2026 14:37:23 +0300 Subject: [PATCH 41/47] javadoc --- .../thread/context/OperationContextDispatcher.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java index cb59bbfbd1b13..e65b05d0308a4 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java @@ -56,15 +56,13 @@ public class OperationContextDispatcher { private volatile boolean initialized; /** - * Creates a new {@link OperationContext} attribute with the specified distributed ID and initial value. + * Registers an attribute of {@link OperationContext} with the specified distributed ID. * *

The distributed ID is used to consistently identify the attribute across all nodes in the cluster. - * It must be unique, and its value must be in the range from {@code 0} (inclusive) to {@code Byte.SIZE} (exclusive).

+ * It must be unique, and its value must be in the range [{@code 0} : {@code Byte.SIZE}).

* - *

The value of the created attribute is automatically captured and propagated between cluster nodes + *

A value of the attribute is automatically captured and propagated between cluster nodes * during message transmission.

- * - * @see OperationContextAttribute#newInstance(Object) */ public void registerDistributedAttribute(byte id, OperationContextAttribute attr) { if (initialized) @@ -81,8 +79,7 @@ public void registerDistributedAttribute(byte id, OperationC } /** - * Collects the values of all distributed {@link OperationContextAttribute}s registered by this manager in a format - * suitable for transmission between cluster nodes. + * Collects the values of all distributed {@link OperationContextAttribute}s registered by this manager. * * @see OperationContext#get(OperationContextAttribute) */ From 91904614e0c1bb51d58d58fad11bd15fe7ab8830 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 25 Jun 2026 14:49:41 +0300 Subject: [PATCH 42/47] minor coding --- .../thread/context/OperationContextDispatcher.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java index e65b05d0308a4..e0bfd16ae1f9e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java @@ -70,12 +70,8 @@ public void registerDistributedAttribute(byte id, OperationC assert id >= 0 && id < MAX_DISTRIBUTED_ATTR_CNT : "Invalid distributed attributed id [id=" + id + ']'; - attrs.compute(id, (id0, attr0) -> { - if (attr0 != null) - throw new IgniteException("Duplicated distributed attribute id [id=" + id + ']'); - - return attr; - }); + if (attrs.putIfAbsent(id, attr) != null) + throw new IgniteException("Duplicated distributed attribute id [id=" + id + ']'); } /** From d570302de58dfcfe6bab0abba85570acd1c84bb1 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Thu, 25 Jun 2026 19:26:30 +0300 Subject: [PATCH 43/47] raw --- .../ignite/internal/CoreMessagesProvider.java | 5 +- .../discovery/GridDiscoveryManager.java | 27 +++-- .../SecurityAwareCustomMessageWrapper.java | 75 ------------ .../IgniteAuthenticationProcessor.java | 76 +----------- .../security/IgniteSecurityProcessor.java | 3 + .../security/SecurityContextImpl.java | 111 ++++++++++++++++++ .../context/OperationContextDispatcher.java | 4 +- .../ignite/internal/util/IgniteUtils.java | 6 +- .../NodeSecurityContextPropagationTest.java | 3 - 9 files changed, 137 insertions(+), 173 deletions(-) delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/SecurityAwareCustomMessageWrapper.java create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java diff --git a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java index d2180dc2baf9e..e82679318b425 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java @@ -35,7 +35,6 @@ import org.apache.ignite.internal.managers.deployment.GridDeploymentInfoBean; import org.apache.ignite.internal.managers.deployment.GridDeploymentRequest; import org.apache.ignite.internal.managers.deployment.GridDeploymentResponse; -import org.apache.ignite.internal.managers.discovery.SecurityAwareCustomMessageWrapper; import org.apache.ignite.internal.managers.encryption.ChangeCacheEncryptionRequest; import org.apache.ignite.internal.managers.encryption.EncryptionDataBagItem; import org.apache.ignite.internal.managers.encryption.GenerateEncryptionKeyRequest; @@ -236,6 +235,7 @@ import org.apache.ignite.internal.processors.query.stat.messages.StatisticsResponse; import org.apache.ignite.internal.processors.rest.handlers.task.GridTaskResultRequest; import org.apache.ignite.internal.processors.rest.handlers.task.GridTaskResultResponse; +import org.apache.ignite.internal.processors.security.SecurityContextImpl; import org.apache.ignite.internal.processors.service.ServiceChangeBatchRequest; import org.apache.ignite.internal.processors.service.ServiceClusterDeploymentResult; import org.apache.ignite.internal.processors.service.ServiceClusterDeploymentResultBatch; @@ -432,7 +432,7 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C withNoSchema(FullMessage.class); withNoSchema(InitMessage.class); withNoSchema(CacheStatisticsModeChangeMessage.class); - withNoSchema(SecurityAwareCustomMessageWrapper.class); + ++msgIdx; // Former SecurityAwareCustomMessageWrapper withNoSchema(MetadataRemoveAcceptedMessage.class); withNoSchema(MetadataRemoveProposedMessage.class); withNoSchema(WalStateFinishMessage.class); @@ -683,6 +683,7 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C // [13400 - 13500]: Operation context messages. msgIdx = 13400; withNoSchema(OperationContextMessage.class); + withNoSchema(SecurityContextImpl.class); assert msgIdx <= MAX_MESSAGE_ID; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java index da9b54b2440f7..d083d6571794c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java @@ -88,14 +88,15 @@ import org.apache.ignite.internal.processors.cluster.ChangeGlobalStateMessage; import org.apache.ignite.internal.processors.cluster.DiscoveryDataClusterState; import org.apache.ignite.internal.processors.cluster.IGridClusterStateProcessor; -import org.apache.ignite.internal.processors.security.IgniteSecurity; import org.apache.ignite.internal.processors.security.SecurityContext; +import org.apache.ignite.internal.processors.security.SecurityContextImpl; import org.apache.ignite.internal.processors.tracing.messages.SpanContainer; import org.apache.ignite.internal.systemview.ClusterNodeViewWalker; import org.apache.ignite.internal.systemview.NodeAttributeViewWalker; import org.apache.ignite.internal.systemview.NodeMetricsViewWalker; import org.apache.ignite.internal.thread.OomExceptionHandler; import org.apache.ignite.internal.thread.context.OperationContext; +import org.apache.ignite.internal.thread.context.OperationContextAttribute; import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.internal.thread.context.function.OperationContextAwareWrapper; import org.apache.ignite.internal.util.GridAtomicLong; @@ -134,7 +135,6 @@ import org.apache.ignite.spi.discovery.DiscoveryMetricsProvider; import org.apache.ignite.spi.discovery.DiscoveryNotification; import org.apache.ignite.spi.discovery.DiscoverySpi; -import org.apache.ignite.spi.discovery.DiscoverySpiCustomMessage; import org.apache.ignite.spi.discovery.DiscoverySpiDataExchange; import org.apache.ignite.spi.discovery.DiscoverySpiHistorySupport; import org.apache.ignite.spi.discovery.DiscoverySpiListener; @@ -191,6 +191,8 @@ * Discovery SPI manager. */ public class GridDiscoveryManager extends GridManagerAdapter { + /** */ + public static final OperationContextAttribute SEC_OP_CTX_ATTR = OperationContextAttribute.newInstance(); /** */ private static final String PREFIX = "Topology snapshot"; @@ -226,7 +228,7 @@ public class GridDiscoveryManager extends GridManagerAdapter { }; /** Discovery cached history size. */ - private final int DISCOVERY_HISTORY_SIZE = getInteger(IGNITE_DISCOVERY_HISTORY_SIZE, DFLT_DISCOVERY_HISTORY_SIZE); + private static final int DISCOVERY_HISTORY_SIZE = getInteger(IGNITE_DISCOVERY_HISTORY_SIZE, DFLT_DISCOVERY_HISTORY_SIZE); /** */ private final Object discoEvtMux = new Object(); @@ -924,12 +926,10 @@ public SecurityAwareNotificationTask(DiscoveryNotification notification) { /** */ @Override public void run() { - DiscoverySpiCustomMessage customMsg = notification.customMessage(); - - if (customMsg instanceof SecurityAwareCustomMessageWrapper) { - UUID secSubjId = ((SecurityAwareCustomMessageWrapper)customMsg).securitySubjectId(); + SecurityContext secOpCtx = OperationContext.get(SEC_OP_CTX_ATTR); - try (Scope ignored = ctx.security().withContext(secSubjId)) { + if (secOpCtx != null) { + try (Scope ignored = ctx.security().withContext(secOpCtx.subject().id())) { super.run(); } } @@ -2334,12 +2334,13 @@ public GridFutureAdapter localJoinFuture() { * @throws IgniteCheckedException If failed. */ public void sendCustomEvent(DiscoveryCustomMessage msg) throws IgniteCheckedException { - try { - IgniteSecurity security = ctx.security(); + UUID secSubjId = ctx.security().enabled() ? ctx.security().securityContext().subject().id() : null; - getSpi().sendCustomEvent(security.enabled() - ? new SecurityAwareCustomMessageWrapper(msg, security.securityContext().subject().id()) - : msg); + try (Scope ignored = secSubjId == null + ? Scope.NOOP_SCOPE + : OperationContext.set(SEC_OP_CTX_ATTR, new SecurityContextImpl(secSubjId)) + ) { + getSpi().sendCustomEvent(msg); } catch (IgniteClientDisconnectedException e) { IgniteFuture reconnectFut = ctx.cluster().clientReconnectFuture(); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/SecurityAwareCustomMessageWrapper.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/SecurityAwareCustomMessageWrapper.java deleted file mode 100644 index e9d33b8433cbf..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/SecurityAwareCustomMessageWrapper.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ignite.internal.managers.discovery; - -import java.util.UUID; -import org.apache.ignite.internal.Order; -import org.apache.ignite.plugin.extensions.communication.MessageFactory; -import org.apache.ignite.spi.discovery.DiscoverySpiCustomMessage; -import org.jetbrains.annotations.Nullable; - -/** Custom message wrapper with ID of security subject that initiated the current message. */ -public class SecurityAwareCustomMessageWrapper implements DiscoverySpiCustomMessage { - /** Security subject ID. */ - @Order(0) - UUID secSubjId; - - /** Original message. */ - @Order(1) - DiscoveryCustomMessage delegate; - - /** Default constructor for {@link MessageFactory}. */ - public SecurityAwareCustomMessageWrapper() { - // No-op. - } - - /** */ - public SecurityAwareCustomMessageWrapper(DiscoveryCustomMessage delegate, UUID secSubjId) { - this.delegate = delegate; - this.secSubjId = secSubjId; - } - - /** Gets security Subject ID. */ - public UUID securitySubjectId() { - return secSubjId; - } - - /** {@inheritDoc} */ - @Override public boolean isMutable() { - return delegate().isMutable(); - } - - /** {@inheritDoc} */ - @Override public boolean stopProcess() { - return delegate().stopProcess(); - } - - /** - * @return Delegate. - */ - public DiscoveryCustomMessage delegate() { - return delegate; - } - - /** {@inheritDoc} */ - @Override public @Nullable DiscoverySpiCustomMessage ackMessage() { - DiscoveryCustomMessage ack = (DiscoveryCustomMessage)delegate().ackMessage(); - - return ack == null ? null : new SecurityAwareCustomMessageWrapper(ack, secSubjId); - } -} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/authentication/IgniteAuthenticationProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/authentication/IgniteAuthenticationProcessor.java index 55a5c22f2a813..3aab17857a63d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/authentication/IgniteAuthenticationProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/authentication/IgniteAuthenticationProcessor.java @@ -17,7 +17,6 @@ package org.apache.ignite.internal.processors.authentication; -import java.io.Serializable; import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.Collection; @@ -57,12 +56,12 @@ import org.apache.ignite.internal.processors.security.GridSecurityProcessor; import org.apache.ignite.internal.processors.security.IgniteSecurityProcessor; import org.apache.ignite.internal.processors.security.SecurityContext; +import org.apache.ignite.internal.processors.security.SecurityContextImpl; import org.apache.ignite.internal.thread.pool.IgniteThreadPoolExecutor; import org.apache.ignite.internal.util.future.GridFutureAdapter; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.CU; -import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.internal.util.worker.GridWorker; import org.apache.ignite.lang.IgniteFuture; @@ -73,7 +72,6 @@ import org.apache.ignite.plugin.security.SecurityException; import org.apache.ignite.plugin.security.SecurityPermission; import org.apache.ignite.plugin.security.SecuritySubject; -import org.apache.ignite.plugin.security.SecuritySubjectType; import org.apache.ignite.spi.discovery.DiscoveryDataBag; import org.apache.ignite.spi.discovery.DiscoverySpi; import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; @@ -1302,7 +1300,7 @@ private RefreshUsersStorageWorker(ArrayList usrs) { } /** {@inheritDoc} */ - @Override protected void body() throws InterruptedException, IgniteInterruptedCheckedException { + @Override protected void body() { if (ctx.clientNode()) return; @@ -1331,74 +1329,4 @@ private RefreshUsersStorageWorker(ArrayList usrs) { } } } - - /** Represents {@link SecuritySubject} implementation. */ - private static class SecuritySubjectImpl implements SecuritySubject { - /** */ - private static final long serialVersionUID = 0L; - - /** Security subject identifier. */ - private final UUID id; - - /** Security subject login. */ - private final String login; - - /** Security subject type. */ - private final SecuritySubjectType type; - - /** Security subject address. */ - private final InetSocketAddress addr; - - /** */ - public SecuritySubjectImpl(UUID id, String login, SecuritySubjectType type, InetSocketAddress addr) { - this.id = id; - this.login = login; - this.type = type; - this.addr = addr; - } - - /** {@inheritDoc} */ - @Override public UUID id() { - return id; - } - - /** {@inheritDoc} */ - @Override public String login() { - return login; - } - - /** {@inheritDoc} */ - @Override public SecuritySubjectType type() { - return type; - } - - /** {@inheritDoc} */ - @Override public InetSocketAddress address() { - return addr; - } - - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(SecuritySubjectImpl.class, this); - } - } - - /** Represents {@link SecurityContext} implementation that ignores any security permission checks. */ - private static class SecurityContextImpl implements SecurityContext, Serializable { - /** */ - private static final long serialVersionUID = 0L; - - /** */ - private final SecuritySubject subj; - - /** */ - public SecurityContextImpl(UUID id, String login, SecuritySubjectType type, InetSocketAddress addr) { - subj = new SecuritySubjectImpl(id, login, type, addr); - } - - /** {@inheritDoc} */ - @Override public SecuritySubject subject() { - return subj; - } - } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessor.java index 7b34ed75db2dc..30f4034046a13 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessor.java @@ -29,6 +29,7 @@ import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.internal.GridKernalContext; import org.apache.ignite.internal.IgniteInternalFuture; +import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager; import org.apache.ignite.internal.processors.security.sandbox.AccessControllerSandbox; import org.apache.ignite.internal.processors.security.sandbox.IgniteSandbox; import org.apache.ignite.internal.processors.security.sandbox.NoOpSandbox; @@ -236,6 +237,8 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP @Override public void start() throws IgniteCheckedException { super.start(); + ctx.operationContextDispatcher().registerDistributedAttribute(0, GridDiscoveryManager.SEC_OP_CTX_ATTR); + ctx.addNodeAttribute(ATTR_GRID_SEC_PROC_CLASS, secPrc.getClass().getName()); secPrc.start(); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java new file mode 100644 index 0000000000000..f798f3542a4d7 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.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.processors.security; + +import java.io.Serializable; +import java.net.InetSocketAddress; +import java.util.UUID; +import org.apache.ignite.internal.Order; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.plugin.extensions.communication.Message; +import org.apache.ignite.plugin.security.SecuritySubject; +import org.apache.ignite.plugin.security.SecuritySubjectType; + +/** Represents {@link SecurityContext} implementation that ignores any security permission checks. */ +public class SecurityContextImpl implements SecurityContext, Message, Serializable { + /** */ + private static final long serialVersionUID = 0L; + + /** */ + private SecuritySubject subj; + + /** */ + @Order(0) + transient UUID subjId; + + /** Empty constructor for serialization purposes. */ + public SecurityContextImpl() { + // No-op. + } + + /** */ + public SecurityContextImpl(UUID id, String login, SecuritySubjectType type, InetSocketAddress addr) { + subj = new SecuritySubjectImpl(id, login, type, addr); + } + + /** */ + public SecurityContextImpl(UUID id) { + subjId = id; + } + + /** {@inheritDoc} */ + @Override public SecuritySubject subject() { + return subj; + } + + /** Represents {@link SecuritySubject} implementation. */ + private static class SecuritySubjectImpl implements SecuritySubject { + /** */ + private static final long serialVersionUID = 0L; + + /** Security subject identifier. */ + private final UUID id; + + /** Security subject login. */ + private final String login; + + /** Security subject type. */ + private final SecuritySubjectType type; + + /** Security subject address. */ + private final InetSocketAddress addr; + + /** */ + public SecuritySubjectImpl(UUID id, String login, SecuritySubjectType type, InetSocketAddress addr) { + this.id = id; + this.login = login; + this.type = type; + this.addr = addr; + } + + /** {@inheritDoc} */ + @Override public UUID id() { + return id; + } + + /** {@inheritDoc} */ + @Override public String login() { + return login; + } + + /** {@inheritDoc} */ + @Override public SecuritySubjectType type() { + return type; + } + + /** {@inheritDoc} */ + @Override public InetSocketAddress address() { + return addr; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(SecuritySubjectImpl.class, this); + } + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java index e0bfd16ae1f9e..18281f3112dd9 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/thread/context/OperationContextDispatcher.java @@ -64,13 +64,13 @@ public class OperationContextDispatcher { *

A value of the attribute is automatically captured and propagated between cluster nodes * during message transmission.

*/ - public void registerDistributedAttribute(byte id, OperationContextAttribute attr) { + public void registerDistributedAttribute(int id, OperationContextAttribute attr) { if (initialized) throw new IgniteException("Initialization of distributed operation context attributes has already finished."); assert id >= 0 && id < MAX_DISTRIBUTED_ATTR_CNT : "Invalid distributed attributed id [id=" + id + ']'; - if (attrs.putIfAbsent(id, attr) != null) + if (attrs.putIfAbsent((byte)id, attr) != null) throw new IgniteException("Duplicated distributed attribute id [id=" + id + ']'); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java index 1513346138589..cfb2245498c23 100755 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java @@ -188,7 +188,6 @@ import org.apache.ignite.internal.managers.deployment.GridDeploymentInfo; import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage; import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager; -import org.apache.ignite.internal.managers.discovery.SecurityAwareCustomMessageWrapper; import org.apache.ignite.internal.mxbean.IgniteStandardMXBean; import org.apache.ignite.internal.processors.cache.CacheDefaultBinaryAffinityKeyMapper; import org.apache.ignite.internal.processors.cache.CacheObjectContext; @@ -8128,12 +8127,11 @@ public static IgniteDataTransferObjectSeria } /** - * Unwraps messsage if it is wrapped by {@link SecurityAwareCustomMessageWrapper}. + * Unwraps messsage as {@link DiscoveryCustomMessage}. * * @param msg Message. */ public static DiscoveryCustomMessage unwrapCustomMessage(DiscoverySpiCustomMessage msg) { - return msg instanceof SecurityAwareCustomMessageWrapper ? - ((SecurityAwareCustomMessageWrapper)msg).delegate() : (DiscoveryCustomMessage)msg; + return (DiscoveryCustomMessage)msg; } } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/security/NodeSecurityContextPropagationTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/security/NodeSecurityContextPropagationTest.java index 8619509d5cd34..99a028c363d81 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/security/NodeSecurityContextPropagationTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/security/NodeSecurityContextPropagationTest.java @@ -34,7 +34,6 @@ import org.apache.ignite.failure.StopNodeOrHaltFailureHandler; import org.apache.ignite.internal.IgniteEx; import org.apache.ignite.internal.events.DiscoveryCustomEvent; -import org.apache.ignite.internal.managers.discovery.SecurityAwareCustomMessageWrapper; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.spi.MessagesPluginProvider; import org.apache.ignite.spi.discovery.DiscoverySpi; @@ -186,8 +185,6 @@ private boolean anyReceivedMessageMatch(IgniteEx ignite, Predicate predi if (msg instanceof TcpDiscoveryCustomEventMessage) { DiscoverySpiCustomMessage customMsg = ((TcpDiscoveryCustomEventMessage)msg).message(); - assert customMsg instanceof SecurityAwareCustomMessageWrapper; - unwrappedMsg = U.unwrapCustomMessage(customMsg); } From 0955e6529919192fca3de8b10b4d2b7cfa1f7d9f Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Fri, 26 Jun 2026 11:57:54 +0300 Subject: [PATCH 44/47] raw --- .../ignite/internal/CoreMessagesProvider.java | 5 +- .../discovery/GridDiscoveryManager.java | 15 ++- .../IgniteAuthenticationProcessor.java | 74 +++++++++++- .../security/IgniteSecurityProcessor.java | 3 - .../security/SecurityContextImpl.java | 111 ------------------ .../security/SecurityContextMessage.java | 46 ++++++++ .../ignite/internal/util/IgniteUtils.java | 2 + 7 files changed, 134 insertions(+), 122 deletions(-) delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java diff --git a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java index 118c6de7c9aee..3de42dbaab5bb 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java @@ -238,6 +238,7 @@ import org.apache.ignite.internal.processors.rollingupgrade.RollingUpgradeNodeData; import org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteFeatureSet; import org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteProductFeatures; +import org.apache.ignite.internal.processors.security.SecurityContextMessage; import org.apache.ignite.internal.processors.service.ServiceChangeBatchRequest; import org.apache.ignite.internal.processors.service.ServiceClusterDeploymentResult; import org.apache.ignite.internal.processors.service.ServiceClusterDeploymentResultBatch; @@ -605,7 +606,9 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C // [11500 - 11600]: IO, networking messages. msgIdx = NODE_ID_MSG_TYPE; withNoSchema(NodeIdMessage.class); + msgIdx = HANDSHAKE_MSG_TYPE; withNoSchema(HandshakeMessage.class); + msgIdx = HANDSHAKE_WAIT_MSG_TYPE; withNoSchema(HandshakeWaitMessage.class); withNoSchema(GridIoMessage.class); withNoSchema(IgniteIoTestMessage.class); @@ -687,7 +690,7 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C // [13400 - 13500]: Operation context messages. msgIdx = 13400; withNoSchema(OperationContextMessage.class); - withNoSchema(SecurityContextImpl.class); + withNoSchema(SecurityContextMessage.class); // [13600 - 13700]: Rolling Upgrade messages. msgIdx = 13600; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java index e3c9f6bc4019b..b0ba8ebffb946 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java @@ -89,7 +89,7 @@ import org.apache.ignite.internal.processors.cluster.DiscoveryDataClusterState; import org.apache.ignite.internal.processors.cluster.IGridClusterStateProcessor; import org.apache.ignite.internal.processors.security.SecurityContext; -import org.apache.ignite.internal.processors.security.SecurityContextImpl; +import org.apache.ignite.internal.processors.security.SecurityContextMessage; import org.apache.ignite.internal.processors.tracing.messages.SpanContainer; import org.apache.ignite.internal.systemview.ClusterNodeViewWalker; import org.apache.ignite.internal.systemview.NodeAttributeViewWalker; @@ -192,7 +192,8 @@ */ public class GridDiscoveryManager extends GridManagerAdapter { /** */ - public static final OperationContextAttribute SEC_OP_CTX_ATTR = OperationContextAttribute.newInstance(); + private static final OperationContextAttribute SEC_OP_CTX_ATTR = OperationContextAttribute.newInstance(); + /** */ private static final String PREFIX = "Topology snapshot"; @@ -480,6 +481,8 @@ private void updateClientNodes(UUID leftNodeId) { /** {@inheritDoc} */ @Override public void start() throws IgniteCheckedException { + ctx.operationContextDispatcher().registerDistributedAttribute(0, SEC_OP_CTX_ATTR); + ctx.addNodeAttribute(ATTR_OFFHEAP_SIZE, requiredOffheap()); ctx.addNodeAttribute(ATTR_DATA_REGIONS_OFFHEAP_SIZE, configuredOffheap()); @@ -931,10 +934,10 @@ public SecurityAwareNotificationTask(DiscoveryNotification notification) { /** */ @Override public void run() { - SecurityContext secOpCtx = OperationContext.get(SEC_OP_CTX_ATTR); + SecurityContextMessage secCtxMsg = OperationContext.get(SEC_OP_CTX_ATTR); - if (secOpCtx != null) { - try (Scope ignored = ctx.security().withContext(secOpCtx.subject().id())) { + if (secCtxMsg != null) { + try (Scope ignored = ctx.security().withContext(secCtxMsg.subjId)) { super.run(); } } @@ -2343,7 +2346,7 @@ public void sendCustomEvent(DiscoveryCustomMessage msg) throws IgniteCheckedExce try (Scope ignored = secSubjId == null ? Scope.NOOP_SCOPE - : OperationContext.set(SEC_OP_CTX_ATTR, new SecurityContextImpl(secSubjId)) + : OperationContext.set(SEC_OP_CTX_ATTR, new SecurityContextMessage(secSubjId)) ) { getSpi().sendCustomEvent(msg); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/authentication/IgniteAuthenticationProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/authentication/IgniteAuthenticationProcessor.java index 3aab17857a63d..74a7dca34a827 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/authentication/IgniteAuthenticationProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/authentication/IgniteAuthenticationProcessor.java @@ -17,6 +17,7 @@ package org.apache.ignite.internal.processors.authentication; +import java.io.Serializable; import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.Collection; @@ -56,12 +57,12 @@ import org.apache.ignite.internal.processors.security.GridSecurityProcessor; import org.apache.ignite.internal.processors.security.IgniteSecurityProcessor; import org.apache.ignite.internal.processors.security.SecurityContext; -import org.apache.ignite.internal.processors.security.SecurityContextImpl; import org.apache.ignite.internal.thread.pool.IgniteThreadPoolExecutor; import org.apache.ignite.internal.util.future.GridFutureAdapter; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.CU; +import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.internal.util.worker.GridWorker; import org.apache.ignite.lang.IgniteFuture; @@ -72,6 +73,7 @@ import org.apache.ignite.plugin.security.SecurityException; import org.apache.ignite.plugin.security.SecurityPermission; import org.apache.ignite.plugin.security.SecuritySubject; +import org.apache.ignite.plugin.security.SecuritySubjectType; import org.apache.ignite.spi.discovery.DiscoveryDataBag; import org.apache.ignite.spi.discovery.DiscoverySpi; import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; @@ -1329,4 +1331,74 @@ private RefreshUsersStorageWorker(ArrayList usrs) { } } } + + /** Represents {@link SecuritySubject} implementation. */ + private static class SecuritySubjectImpl implements SecuritySubject { + /** */ + private static final long serialVersionUID = 0L; + + /** Security subject identifier. */ + private final UUID id; + + /** Security subject login. */ + private final String login; + + /** Security subject type. */ + private final SecuritySubjectType type; + + /** Security subject address. */ + private final InetSocketAddress addr; + + /** */ + public SecuritySubjectImpl(UUID id, String login, SecuritySubjectType type, InetSocketAddress addr) { + this.id = id; + this.login = login; + this.type = type; + this.addr = addr; + } + + /** {@inheritDoc} */ + @Override public UUID id() { + return id; + } + + /** {@inheritDoc} */ + @Override public String login() { + return login; + } + + /** {@inheritDoc} */ + @Override public SecuritySubjectType type() { + return type; + } + + /** {@inheritDoc} */ + @Override public InetSocketAddress address() { + return addr; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(SecuritySubjectImpl.class, this); + } + } + + /** Represents {@link SecurityContext} implementation that ignores any security permission checks. */ + private static class SecurityContextImpl implements SecurityContext, Serializable { + /** */ + private static final long serialVersionUID = 0L; + + /** */ + private final SecuritySubject subj; + + /** */ + public SecurityContextImpl(UUID id, String login, SecuritySubjectType type, InetSocketAddress addr) { + subj = new SecuritySubjectImpl(id, login, type, addr); + } + + /** {@inheritDoc} */ + @Override public SecuritySubject subject() { + return subj; + } + } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessor.java index 30f4034046a13..7b34ed75db2dc 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessor.java @@ -29,7 +29,6 @@ import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.internal.GridKernalContext; import org.apache.ignite.internal.IgniteInternalFuture; -import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager; import org.apache.ignite.internal.processors.security.sandbox.AccessControllerSandbox; import org.apache.ignite.internal.processors.security.sandbox.IgniteSandbox; import org.apache.ignite.internal.processors.security.sandbox.NoOpSandbox; @@ -237,8 +236,6 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP @Override public void start() throws IgniteCheckedException { super.start(); - ctx.operationContextDispatcher().registerDistributedAttribute(0, GridDiscoveryManager.SEC_OP_CTX_ATTR); - ctx.addNodeAttribute(ATTR_GRID_SEC_PROC_CLASS, secPrc.getClass().getName()); secPrc.start(); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java deleted file mode 100644 index f798f3542a4d7..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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.processors.security; - -import java.io.Serializable; -import java.net.InetSocketAddress; -import java.util.UUID; -import org.apache.ignite.internal.Order; -import org.apache.ignite.internal.util.typedef.internal.S; -import org.apache.ignite.plugin.extensions.communication.Message; -import org.apache.ignite.plugin.security.SecuritySubject; -import org.apache.ignite.plugin.security.SecuritySubjectType; - -/** Represents {@link SecurityContext} implementation that ignores any security permission checks. */ -public class SecurityContextImpl implements SecurityContext, Message, Serializable { - /** */ - private static final long serialVersionUID = 0L; - - /** */ - private SecuritySubject subj; - - /** */ - @Order(0) - transient UUID subjId; - - /** Empty constructor for serialization purposes. */ - public SecurityContextImpl() { - // No-op. - } - - /** */ - public SecurityContextImpl(UUID id, String login, SecuritySubjectType type, InetSocketAddress addr) { - subj = new SecuritySubjectImpl(id, login, type, addr); - } - - /** */ - public SecurityContextImpl(UUID id) { - subjId = id; - } - - /** {@inheritDoc} */ - @Override public SecuritySubject subject() { - return subj; - } - - /** Represents {@link SecuritySubject} implementation. */ - private static class SecuritySubjectImpl implements SecuritySubject { - /** */ - private static final long serialVersionUID = 0L; - - /** Security subject identifier. */ - private final UUID id; - - /** Security subject login. */ - private final String login; - - /** Security subject type. */ - private final SecuritySubjectType type; - - /** Security subject address. */ - private final InetSocketAddress addr; - - /** */ - public SecuritySubjectImpl(UUID id, String login, SecuritySubjectType type, InetSocketAddress addr) { - this.id = id; - this.login = login; - this.type = type; - this.addr = addr; - } - - /** {@inheritDoc} */ - @Override public UUID id() { - return id; - } - - /** {@inheritDoc} */ - @Override public String login() { - return login; - } - - /** {@inheritDoc} */ - @Override public SecuritySubjectType type() { - return type; - } - - /** {@inheritDoc} */ - @Override public InetSocketAddress address() { - return addr; - } - - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(SecuritySubjectImpl.class, this); - } - } -} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java new file mode 100644 index 0000000000000..79333397eb3e6 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.security; + +import java.util.UUID; +import org.apache.ignite.internal.Order; +import org.apache.ignite.internal.thread.context.OperationContextDispatcher; +import org.apache.ignite.plugin.extensions.communication.Message; +import org.apache.ignite.plugin.security.SecuritySubject; + +/** + * Message for {@link SecurityContext}. + * + * @see SecuritySubject + * @see OperationContextDispatcher + */ +public class SecurityContextMessage implements Message { + /** */ + @Order(0) + public UUID subjId; + + /** Empty constructor for serialization purposes. */ + public SecurityContextMessage() { + // No-op. + } + + /** */ + public SecurityContextMessage(UUID subjId) { + this.subjId = subjId; + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java index cfb2245498c23..6e69a78746aa6 100755 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java @@ -8132,6 +8132,8 @@ public static IgniteDataTransferObjectSeria * @param msg Message. */ public static DiscoveryCustomMessage unwrapCustomMessage(DiscoverySpiCustomMessage msg) { + assert msg instanceof DiscoveryCustomMessage; + return (DiscoveryCustomMessage)msg; } } From e1d7832829d0cca133b1903769a2e4f9deaec355 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Fri, 26 Jun 2026 12:10:09 +0300 Subject: [PATCH 45/47] test fixes --- .../java/org/apache/ignite/internal/IgniteKernal.java | 4 ++-- .../java/org/apache/ignite/internal/util/IgniteUtils.java | 6 +++--- .../thread/context/OperationContextAttributesTest.java | 8 +++++--- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java index 063774e7b13b5..0e58bf6412037 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java @@ -1158,8 +1158,6 @@ public void start( // All components exept Discovery are started, time to check if maintenance is still needed. mntcProc.prepareAndExecuteMaintenance(); - operationCtxDispatcher.finishRegistration(); - gw.writeLock(); try { @@ -1172,6 +1170,8 @@ public void start( gw.writeUnlock(); } + operationCtxDispatcher.finishRegistration(); + startTimer.finishGlobalStage("Join topology"); // Check whether UTF-8 is the default character encoding. diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java index 6e69a78746aa6..6e57e19b0fb1d 100755 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java @@ -8115,7 +8115,7 @@ public void clearAllListener() { /** */ public static IgniteDataTransferObjectSerializer loadSerializer(Class cls) { try { - Class cls0 = IgniteUtils.class.getClassLoader() + Class cls0 = IgniteUtils.class.getClassLoader() .loadClass(cls.getPackage().getName() + "." + cls.getSimpleName() + "Serializer"); return (IgniteDataTransferObjectSerializer)cls0.getDeclaredConstructor().newInstance(); @@ -8131,8 +8131,8 @@ public static IgniteDataTransferObjectSeria * * @param msg Message. */ - public static DiscoveryCustomMessage unwrapCustomMessage(DiscoverySpiCustomMessage msg) { - assert msg instanceof DiscoveryCustomMessage; + public static DiscoveryCustomMessage unwrapCustomMessage(@Nullable DiscoverySpiCustomMessage msg) { + assert msg == null || msg instanceof DiscoveryCustomMessage; return (DiscoveryCustomMessage)msg; } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java index b4003de3bcf72..c14f52087d400 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/thread/context/OperationContextAttributesTest.java @@ -877,14 +877,16 @@ private void doTestOperationContextAttributesPropagation(boolean discovery) thro @Override public void start(PluginContext ctx) { GridKernalContext kctx = ((IgniteEx)ctx.grid()).context(); - kctx.operationContextDispatcher().registerDistributedAttribute(0, dAttr1); + int dAttr1Id = OperationContextDispatcher.MAX_ATTRS_CNT - 2; + int dAttr2Id = OperationContextDispatcher.MAX_ATTRS_CNT - 1; - kctx.operationContextDispatcher().registerDistributedAttribute(OperationContextDispatcher.MAX_ATTRS_CNT - 1, dAttr2); + kctx.operationContextDispatcher().registerDistributedAttribute(dAttr1Id, dAttr1); + kctx.operationContextDispatcher().registerDistributedAttribute(dAttr2Id, dAttr2); assertThrowsAnyCause( log, () -> { - kctx.operationContextDispatcher().registerDistributedAttribute(0, otherTestAttr); + kctx.operationContextDispatcher().registerDistributedAttribute(dAttr2Id, otherTestAttr); return null; }, IgniteException.class, From 3eb7f8ce9bb79e8bc6fe40368a81eec1c09ec397 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Fri, 26 Jun 2026 13:40:17 +0300 Subject: [PATCH 46/47] reimpl --- .../ignite/internal/CoreMessagesProvider.java | 4 +- .../discovery/GridDiscoveryManager.java | 13 +- .../IgniteAuthenticationProcessor.java | 74 +---------- .../security/IgniteSecurityProcessor.java | 12 +- .../security/SecurityContextImpl.java | 123 ++++++++++++++++++ .../security/SecurityContextMessage.java | 46 ------- 6 files changed, 137 insertions(+), 135 deletions(-) create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java delete mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java diff --git a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java index 3de42dbaab5bb..f2a74ed3d550d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java @@ -238,7 +238,7 @@ import org.apache.ignite.internal.processors.rollingupgrade.RollingUpgradeNodeData; import org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteFeatureSet; import org.apache.ignite.internal.processors.rollingupgrade.feature.IgniteProductFeatures; -import org.apache.ignite.internal.processors.security.SecurityContextMessage; +import org.apache.ignite.internal.processors.security.SecurityContextImpl; import org.apache.ignite.internal.processors.service.ServiceChangeBatchRequest; import org.apache.ignite.internal.processors.service.ServiceClusterDeploymentResult; import org.apache.ignite.internal.processors.service.ServiceClusterDeploymentResultBatch; @@ -690,7 +690,7 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C // [13400 - 13500]: Operation context messages. msgIdx = 13400; withNoSchema(OperationContextMessage.class); - withNoSchema(SecurityContextMessage.class); + withNoSchema(SecurityContextImpl.class); // [13600 - 13700]: Rolling Upgrade messages. msgIdx = 13600; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java index b0ba8ebffb946..b13b8ee104f39 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java @@ -88,15 +88,15 @@ import org.apache.ignite.internal.processors.cluster.ChangeGlobalStateMessage; import org.apache.ignite.internal.processors.cluster.DiscoveryDataClusterState; import org.apache.ignite.internal.processors.cluster.IGridClusterStateProcessor; +import org.apache.ignite.internal.processors.security.IgniteSecurityProcessor; import org.apache.ignite.internal.processors.security.SecurityContext; -import org.apache.ignite.internal.processors.security.SecurityContextMessage; +import org.apache.ignite.internal.processors.security.SecurityContextImpl; import org.apache.ignite.internal.processors.tracing.messages.SpanContainer; import org.apache.ignite.internal.systemview.ClusterNodeViewWalker; import org.apache.ignite.internal.systemview.NodeAttributeViewWalker; import org.apache.ignite.internal.systemview.NodeMetricsViewWalker; import org.apache.ignite.internal.thread.OomExceptionHandler; import org.apache.ignite.internal.thread.context.OperationContext; -import org.apache.ignite.internal.thread.context.OperationContextAttribute; import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.internal.thread.context.function.OperationContextAwareWrapper; import org.apache.ignite.internal.util.GridAtomicLong; @@ -191,9 +191,6 @@ * Discovery SPI manager. */ public class GridDiscoveryManager extends GridManagerAdapter { - /** */ - private static final OperationContextAttribute SEC_OP_CTX_ATTR = OperationContextAttribute.newInstance(); - /** */ private static final String PREFIX = "Topology snapshot"; @@ -481,8 +478,6 @@ private void updateClientNodes(UUID leftNodeId) { /** {@inheritDoc} */ @Override public void start() throws IgniteCheckedException { - ctx.operationContextDispatcher().registerDistributedAttribute(0, SEC_OP_CTX_ATTR); - ctx.addNodeAttribute(ATTR_OFFHEAP_SIZE, requiredOffheap()); ctx.addNodeAttribute(ATTR_DATA_REGIONS_OFFHEAP_SIZE, configuredOffheap()); @@ -934,7 +929,7 @@ public SecurityAwareNotificationTask(DiscoveryNotification notification) { /** */ @Override public void run() { - SecurityContextMessage secCtxMsg = OperationContext.get(SEC_OP_CTX_ATTR); + SecurityContextImpl secCtxMsg = OperationContext.get(IgniteSecurityProcessor.SEC_CTX_ATTR); if (secCtxMsg != null) { try (Scope ignored = ctx.security().withContext(secCtxMsg.subjId)) { @@ -2346,7 +2341,7 @@ public void sendCustomEvent(DiscoveryCustomMessage msg) throws IgniteCheckedExce try (Scope ignored = secSubjId == null ? Scope.NOOP_SCOPE - : OperationContext.set(SEC_OP_CTX_ATTR, new SecurityContextMessage(secSubjId)) + : OperationContext.set(IgniteSecurityProcessor.SEC_CTX_ATTR, new SecurityContextImpl(secSubjId)) ) { getSpi().sendCustomEvent(msg); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/authentication/IgniteAuthenticationProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/authentication/IgniteAuthenticationProcessor.java index 74a7dca34a827..3aab17857a63d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/authentication/IgniteAuthenticationProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/authentication/IgniteAuthenticationProcessor.java @@ -17,7 +17,6 @@ package org.apache.ignite.internal.processors.authentication; -import java.io.Serializable; import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.Collection; @@ -57,12 +56,12 @@ import org.apache.ignite.internal.processors.security.GridSecurityProcessor; import org.apache.ignite.internal.processors.security.IgniteSecurityProcessor; import org.apache.ignite.internal.processors.security.SecurityContext; +import org.apache.ignite.internal.processors.security.SecurityContextImpl; import org.apache.ignite.internal.thread.pool.IgniteThreadPoolExecutor; import org.apache.ignite.internal.util.future.GridFutureAdapter; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.CU; -import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.internal.util.worker.GridWorker; import org.apache.ignite.lang.IgniteFuture; @@ -73,7 +72,6 @@ import org.apache.ignite.plugin.security.SecurityException; import org.apache.ignite.plugin.security.SecurityPermission; import org.apache.ignite.plugin.security.SecuritySubject; -import org.apache.ignite.plugin.security.SecuritySubjectType; import org.apache.ignite.spi.discovery.DiscoveryDataBag; import org.apache.ignite.spi.discovery.DiscoverySpi; import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; @@ -1331,74 +1329,4 @@ private RefreshUsersStorageWorker(ArrayList usrs) { } } } - - /** Represents {@link SecuritySubject} implementation. */ - private static class SecuritySubjectImpl implements SecuritySubject { - /** */ - private static final long serialVersionUID = 0L; - - /** Security subject identifier. */ - private final UUID id; - - /** Security subject login. */ - private final String login; - - /** Security subject type. */ - private final SecuritySubjectType type; - - /** Security subject address. */ - private final InetSocketAddress addr; - - /** */ - public SecuritySubjectImpl(UUID id, String login, SecuritySubjectType type, InetSocketAddress addr) { - this.id = id; - this.login = login; - this.type = type; - this.addr = addr; - } - - /** {@inheritDoc} */ - @Override public UUID id() { - return id; - } - - /** {@inheritDoc} */ - @Override public String login() { - return login; - } - - /** {@inheritDoc} */ - @Override public SecuritySubjectType type() { - return type; - } - - /** {@inheritDoc} */ - @Override public InetSocketAddress address() { - return addr; - } - - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(SecuritySubjectImpl.class, this); - } - } - - /** Represents {@link SecurityContext} implementation that ignores any security permission checks. */ - private static class SecurityContextImpl implements SecurityContext, Serializable { - /** */ - private static final long serialVersionUID = 0L; - - /** */ - private final SecuritySubject subj; - - /** */ - public SecurityContextImpl(UUID id, String login, SecuritySubjectType type, InetSocketAddress addr) { - subj = new SecuritySubjectImpl(id, login, type, addr); - } - - /** {@inheritDoc} */ - @Override public SecuritySubject subject() { - return subj; - } - } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessor.java index 7b34ed75db2dc..6c7cf57f95e9e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessor.java @@ -88,8 +88,8 @@ static boolean hasSandboxedNodes() { return SANDBOXED_NODES_COUNTER.get() > 0; } - /** Context attribute that holds Security Context. */ - private static final OperationContextAttribute SEC_CTX = OperationContextAttribute.newInstance(); + /** Attribute that holds local and distributed Security Context. */ + public static final OperationContextAttribute SEC_CTX_ATTR = OperationContextAttribute.newInstance(); /** Security processor. */ private final GridSecurityProcessor secPrc; @@ -126,7 +126,7 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP /** {@inheritDoc} */ @Override public Scope withContext(SecurityContext secCtx) { - return OperationContext.set(SEC_CTX, secCtx == dfltSecCtx ? null : secCtx); + return OperationContext.set(SEC_CTX_ATTR, secCtx == dfltSecCtx ? null : SecurityContextImpl.of(secCtx)); } /** {@inheritDoc} */ @@ -172,12 +172,12 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP /** {@inheritDoc} */ @Override public boolean isDefaultContext() { - return OperationContext.get(SEC_CTX) == null; + return OperationContext.get(SEC_CTX_ATTR) == null; } /** {@inheritDoc} */ @Override public SecurityContext securityContext() { - SecurityContext res = OperationContext.get(SEC_CTX); + SecurityContext res = OperationContext.get(SEC_CTX_ATTR); return res == null ? dfltSecCtx : res; } @@ -236,6 +236,8 @@ public IgniteSecurityProcessor(GridKernalContext ctx, GridSecurityProcessor secP @Override public void start() throws IgniteCheckedException { super.start(); + ctx.operationContextDispatcher().registerDistributedAttribute(0, SEC_CTX_ATTR); + ctx.addNodeAttribute(ATTR_GRID_SEC_PROC_CLASS, secPrc.getClass().getName()); secPrc.start(); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java new file mode 100644 index 0000000000000..02deae0d2358c --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java @@ -0,0 +1,123 @@ +/* + * 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.processors.security; + +import java.io.Serializable; +import java.net.InetSocketAddress; +import java.util.UUID; +import org.apache.ignite.internal.Order; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.plugin.extensions.communication.Message; +import org.apache.ignite.plugin.security.SecuritySubject; +import org.apache.ignite.plugin.security.SecuritySubjectType; +import org.jetbrains.annotations.Nullable; + +/** Represents {@link SecurityContext} implementation that ignores any security permission checks. */ +public class SecurityContextImpl implements SecurityContext, Message, Serializable { + /** */ + private static final long serialVersionUID = 0L; + + /** Security subject identifier. */ + @Order(0) + public UUID subjId; + + /** */ + private @Nullable SecuritySubject subj; + + /** Empty constructor for serialization purposes. */ + public SecurityContextImpl() { + // No-op. + } + + /** Constructor to be a {@link Message} only. */ + public SecurityContextImpl(UUID subjId) { + this.subjId = subjId; + } + + /** */ + public SecurityContextImpl(SecuritySubject subj) { + this.subjId = subj.id(); + this.subj = subj; + } + + /** */ + public SecurityContextImpl(UUID id, String login, SecuritySubjectType type, InetSocketAddress addr) { + subjId = id; + subj = new SecuritySubjectImpl(login, type, addr); + } + + /** */ + public static @Nullable SecurityContextImpl of(@Nullable SecurityContext ctx) { + if (ctx == null || ctx instanceof SecurityContextImpl) + return (SecurityContextImpl)ctx; + + return new SecurityContextImpl(ctx.subject()); + } + + /** {@inheritDoc} */ + @Override public @Nullable SecuritySubject subject() { + return subj; + } + + /** Represents {@link SecuritySubject} implementation. */ + private class SecuritySubjectImpl implements SecuritySubject { + /** */ + private static final long serialVersionUID = 0L; + + /** Security subject login. */ + private final String login; + + /** Security subject type. */ + private final SecuritySubjectType type; + + /** Security subject address. */ + private final InetSocketAddress addr; + + /** */ + private SecuritySubjectImpl(String login, SecuritySubjectType type, InetSocketAddress addr) { + this.login = login; + this.type = type; + this.addr = addr; + } + + /** {@inheritDoc} */ + @Override public UUID id() { + return subjId; + } + + /** {@inheritDoc} */ + @Override public String login() { + return login; + } + + /** {@inheritDoc} */ + @Override public SecuritySubjectType type() { + return type; + } + + /** {@inheritDoc} */ + @Override public InetSocketAddress address() { + return addr; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(SecuritySubjectImpl.class, this); + } + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java deleted file mode 100644 index 79333397eb3e6..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextMessage.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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.processors.security; - -import java.util.UUID; -import org.apache.ignite.internal.Order; -import org.apache.ignite.internal.thread.context.OperationContextDispatcher; -import org.apache.ignite.plugin.extensions.communication.Message; -import org.apache.ignite.plugin.security.SecuritySubject; - -/** - * Message for {@link SecurityContext}. - * - * @see SecuritySubject - * @see OperationContextDispatcher - */ -public class SecurityContextMessage implements Message { - /** */ - @Order(0) - public UUID subjId; - - /** Empty constructor for serialization purposes. */ - public SecurityContextMessage() { - // No-op. - } - - /** */ - public SecurityContextMessage(UUID subjId) { - this.subjId = subjId; - } -} From 352c048dd1c7052c5cee5b929a78bed3ee282013 Mon Sep 17 00:00:00 2001 From: Vladimir Steshin Date: Fri, 26 Jun 2026 13:55:13 +0300 Subject: [PATCH 47/47] fix --- .../main/java/org/apache/ignite/internal/IgniteKernal.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java index 0e58bf6412037..063774e7b13b5 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java @@ -1158,6 +1158,8 @@ public void start( // All components exept Discovery are started, time to check if maintenance is still needed. mntcProc.prepareAndExecuteMaintenance(); + operationCtxDispatcher.finishRegistration(); + gw.writeLock(); try { @@ -1170,8 +1172,6 @@ public void start( gw.writeUnlock(); } - operationCtxDispatcher.finishRegistration(); - startTimer.finishGlobalStage("Join topology"); // Check whether UTF-8 is the default character encoding.