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 1af6f8945cff7..14fef8e6ef99b 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 @@ -28,7 +28,6 @@ import org.apache.ignite.internal.managers.communication.CompressedMessage; import org.apache.ignite.internal.managers.communication.ErrorMessage; import org.apache.ignite.internal.managers.communication.GridIoMessage; -import org.apache.ignite.internal.managers.communication.GridIoSecurityAwareMessage; import org.apache.ignite.internal.managers.communication.GridIoUserMessage; import org.apache.ignite.internal.managers.communication.IgniteIoTestMessage; import org.apache.ignite.internal.managers.communication.SessionChannelMessage; @@ -240,6 +239,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.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; @@ -608,12 +608,14 @@ 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); withSchema(GridIoUserMessage.class); - withSchema(GridIoSecurityAwareMessage.class); + ++msgIdx; // Former GridIoSecurityAwareMessage withNoSchema(RecoveryLastReceivedMessage.class); withNoSchema(TcpInverseConnectionResponseMessage.class); withNoSchema(SessionChannelMessage.class); @@ -690,9 +692,10 @@ public CoreMessagesProvider(Marshaller dfltMarsh, Marshaller schemaAwareMarsh, C // [13400 - 13500]: Operation context messages. msgIdx = 13400; withNoSchema(OperationContextMessage.class); + withNoSchema(SecurityContextImpl.class); - // [13500 - 13600]: Rolling Upgrade messages. - msgIdx = 13500; + // [13600 - 13700]: Rolling Upgrade messages. + msgIdx = 13600; withNoSchema(IgniteFeatureSet.class); withNoSchema(IgniteProductFeatures.class); withNoSchema(RollingUpgradeNodeData.class); 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 a83e6ae8e7d41..658ca82e25c5b 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 @@ -97,11 +97,14 @@ import org.apache.ignite.internal.processors.cache.persistence.file.RandomAccessFileIOFactory; import org.apache.ignite.internal.processors.platform.message.PlatformMessageFilter; import org.apache.ignite.internal.processors.pool.PoolProcessor; +import org.apache.ignite.internal.processors.security.IgniteSecurityProcessor; +import org.apache.ignite.internal.processors.security.SecurityContextImpl; import org.apache.ignite.internal.processors.timeout.GridTimeoutObject; import org.apache.ignite.internal.processors.tracing.MTC; 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.OperationContext; import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashSet; import org.apache.ignite.internal.util.IgniteUtils; @@ -137,7 +140,6 @@ import org.apache.ignite.spi.communication.tcp.internal.ConnectionRequestor; import org.apache.ignite.spi.communication.tcp.internal.TcpConnectionRequestDiscoveryMessage; import org.apache.ignite.spi.communication.tcp.internal.TcpInverseConnectionResponseMessage; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import static org.apache.ignite.events.EventType.EVT_NODE_FAILED; @@ -1317,7 +1319,7 @@ private void processP2PMessage( assert obj != null; - invokeListener(msg.policy(), lsnr, nodeId, obj, secSubjId(msg)); + invokeListener(msg.policy(), lsnr, nodeId, obj); } finally { threadProcessingMessage(false, null); @@ -1455,7 +1457,7 @@ private void processRegularMessage0(GridIoMessage msg, UUID nodeId) { assert obj != null; - invokeListener(msg.policy(), lsnr, nodeId, obj, secSubjId(msg)); + invokeListener(msg.policy(), lsnr, nodeId, obj); } /** @@ -1819,9 +1821,8 @@ private void unwindMessageSet(GridCommunicationMessageSet msgSet, GridMessageLis * @param lsnr Listener. * @param nodeId Node ID. * @param msg Message. - * @param secSubjId Security subject that will be used to open a security session. */ - private void invokeListener(Byte plc, GridMessageListener lsnr, UUID nodeId, Object msg, UUID secSubjId) { + private void invokeListener(Byte plc, GridMessageListener lsnr, UUID nodeId, Object msg) { MTC.span().addLog(() -> "Invoke listener"); Byte oldPlc = CUR_PLC.get(); @@ -1831,7 +1832,9 @@ private void invokeListener(Byte plc, GridMessageListener lsnr, UUID nodeId, Obj if (change) CUR_PLC.set(plc); - UUID newSecSubjId = secSubjId != null ? secSubjId : nodeId; + SecurityContextImpl secCtxMsg = OperationContext.get(IgniteSecurityProcessor.SEC_CTX_ATTR); + + UUID newSecSubjId = secCtxMsg == null ? nodeId : secCtxMsg.subjId; try (Scope ignored = ctx.security().withContext(newSecSubjId)) { lsnr.onMessage(nodeId, msg, plc); @@ -2029,11 +2032,8 @@ private long getInverseConnectionWaitTimeout() { return ctx.config().getFailureDetectionTimeout(); } - /** - * @return One of two message wrappers. The first is {@link GridIoMessage}, the second is secured version {@link - * GridIoSecurityAwareMessage}. - */ - private @NotNull GridIoMessage createGridIoMessage( + /** @return A {@link GridIoMessage} wrapper for {@code msg}. */ + private GridIoMessage createGridIoMessage( Object topic, Message msg, byte plc, @@ -2043,18 +2043,16 @@ private long getInverseConnectionWaitTimeout() { ) { GridIoMessage res; - if (ctx.security().enabled()) { - UUID secSubjId = null; + UUID secSubjId = ctx.security().enabled() && !ctx.security().isDefaultContext() + ? ctx.security().securityContext().subject().id() + : null; - if (!ctx.security().isDefaultContext()) - secSubjId = ctx.security().securityContext().subject().id(); + res = new GridIoMessage(plc, topic, msg, ordered, timeout, skipOnTimeout); - res = new GridIoSecurityAwareMessage(secSubjId, plc, topic, msg, ordered, timeout, skipOnTimeout); + try (Scope ignored = secSubjId == null ? Scope.NOOP_SCOPE + : OperationContext.set(IgniteSecurityProcessor.SEC_CTX_ATTR, new SecurityContextImpl(secSubjId))) { + res.opCtxMsg = ctx.operationContextDispatcher().collectDistributedAttributes(); } - else - res = new GridIoMessage(plc, topic, msg, ordered, timeout, skipOnTimeout); - - res.opCtxMsg = ctx.operationContextDispatcher().collectDistributedAttributes(); return res; } @@ -3812,7 +3810,7 @@ void unwind(GridMessageListener lsnr) { MTC.span().addTag(SpanTags.MESSAGE, () -> traceName(fmc.message)); - invokeListener(plc, lsnr, nodeId, mc.message.message(), secSubjId(mc.message)); + invokeListener(plc, lsnr, nodeId, mc.message.message()); } finally { if (mc.closure != null) @@ -4241,19 +4239,6 @@ public long binLatencyMcs() { } } - /** - * @return Security subject id. - */ - private UUID secSubjId(GridIoMessage msg) { - if (ctx.security().enabled()) { - assert msg instanceof GridIoSecurityAwareMessage; - - return ((GridIoSecurityAwareMessage)msg).securitySubjectId(); - } - - return null; - } - /** * Responsible for handling network situation where server cannot open connection to client and * has to ask client to establish a connection to specific server. diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoSecurityAwareMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoSecurityAwareMessage.java deleted file mode 100644 index d1a6040d3d682..0000000000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoSecurityAwareMessage.java +++ /dev/null @@ -1,68 +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.communication; - -import java.util.UUID; -import org.apache.ignite.internal.Order; -import org.apache.ignite.plugin.extensions.communication.Message; - -/** - * - */ -public class GridIoSecurityAwareMessage extends GridIoMessage { - /** Security subject ID that will be used during message processing on a remote node. */ - @Order(0) - UUID secSubjId; - - /** - * Default constructor. - */ - public GridIoSecurityAwareMessage() { - // No-op. - } - - /** - * @param secSubjId Security subject ID. - * @param plc Policy. - * @param topic Communication topic. - * @param msg Message. - * @param ordered Message ordered flag. - * @param timeout Timeout. - * @param skipOnTimeout Whether message can be skipped on timeout. - */ - public GridIoSecurityAwareMessage( - UUID secSubjId, - byte plc, - Object topic, - Message msg, - boolean ordered, - long timeout, - boolean skipOnTimeout - ) { - super(plc, topic, msg, ordered, timeout, skipOnTimeout); - - this.secSubjId = secSubjId; - } - - /** - * @return Security subject ID. - */ - UUID securitySubjectId() { - return secSubjId; - } -} 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 d7a599271f04e..23877a26244fc 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 @@ -226,7 +226,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(); 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..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..cfe08cedfded0 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextImpl.java @@ -0,0 +1,128 @@ +/* + * 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 and is able to transfer + * id of {@link SecuritySubject} as a {@link Message}. + * + * @see #SecurityContextImpl(UUID) + */ +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. Doesn't suppose working with {@link #subject()}. */ + 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/resources/META-INF/classnames.properties b/modules/core/src/main/resources/META-INF/classnames.properties index 4e14099e871c2..431e7ee68b9b7 100644 --- a/modules/core/src/main/resources/META-INF/classnames.properties +++ b/modules/core/src/main/resources/META-INF/classnames.properties @@ -705,7 +705,6 @@ org.apache.ignite.internal.managers.checkpoint.GridCheckpointManager$CheckpointS org.apache.ignite.internal.managers.checkpoint.GridCheckpointRequest org.apache.ignite.internal.managers.communication.GridIoManager$ConcurrentHashMap0 org.apache.ignite.internal.managers.communication.GridIoMessage -org.apache.ignite.internal.managers.communication.GridIoSecurityAwareMessage org.apache.ignite.internal.managers.communication.GridIoUserMessage org.apache.ignite.internal.managers.communication.IgniteIoTestMessage org.apache.ignite.internal.managers.communication.SessionChannelMessage diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteExchangeLatchManagerDiscoHistoryTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteExchangeLatchManagerDiscoHistoryTest.java index d7bde459fa589..0b9bec9338f95 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteExchangeLatchManagerDiscoHistoryTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteExchangeLatchManagerDiscoHistoryTest.java @@ -21,9 +21,9 @@ import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import org.apache.ignite.Ignite; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteException; import org.apache.ignite.ShutdownPolicy; import org.apache.ignite.configuration.IgniteConfiguration; @@ -37,7 +37,6 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.latch.ExchangeLatchManager; import org.apache.ignite.internal.processors.metastorage.DistributedMetastorageLifecycleListener; import org.apache.ignite.internal.processors.metastorage.ReadableDistributedMetaStorage; -import org.apache.ignite.internal.util.typedef.X; import org.apache.ignite.lifecycle.LifecycleBean; import org.apache.ignite.lifecycle.LifecycleEventType; import org.apache.ignite.resources.IgniteInstanceResource; @@ -52,6 +51,8 @@ import org.junit.Test; import static org.apache.ignite.IgniteSystemProperties.IGNITE_DISCOVERY_HISTORY_SIZE; +import static org.apache.ignite.testframework.GridTestUtils.assertContains; +import static org.apache.ignite.testframework.GridTestUtils.waitForCondition; /** * Test {@link ExchangeLatchManager} throws {@link IgniteException} with appropriate message when topology history @@ -79,6 +80,13 @@ public class IgniteExchangeLatchManagerDiscoHistoryTest extends GridCommonAbstra /** Failure context. */ private final AtomicReference cpFailureCtx = new AtomicReference<>(); + /** {@inheritDoc} */ + @Override protected void beforeTestsStarted() throws Exception { + super.beforeTestsStarted(); + + stopAllGrids(true); + } + /** {@inheritDoc} */ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); @@ -142,11 +150,10 @@ public void shutdown() { public void testProperException() throws Exception { final IgniteEx crd = startGrid(0); - final CountDownLatch exchangeLatch = new CountDownLatch(1); - - final CountDownLatch startSrvsLatch = new CountDownLatch(1); + log.error("TEST | nodes cnt 0: " + crd.cluster().nodes().size()); - final AtomicReference err = new AtomicReference<>(); + final CountDownLatch victimStartDelayLatch = new CountDownLatch(1); + final CountDownLatch victimStartingLatch = new CountDownLatch(1); // Lifecycle bean that is used to register PartitionsExchangeAware listener. lifecycleBean = new LifecycleBean() { @@ -166,14 +173,14 @@ public void testProperException() throws Exception { @Override public void onInitBeforeTopologyLock( GridDhtPartitionsExchangeFuture fut) { try { - // Let's start nodes. - startSrvsLatch.countDown(); + // Let's start the other nodes. + victimStartingLatch.countDown(); // Blocks the initial exchange and waits for other nodes. - exchangeLatch.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); + assertTrue(victimStartDelayLatch.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)); } - catch (Exception e) { - err.compareAndSet(null, e); + catch (Throwable e) { + log.error("Unexpected victim start error.", e); } } }); @@ -191,20 +198,19 @@ public void testProperException() throws Exception { GridTestUtils.runAsync(() -> startGrid(1)); // Waits for the initial exchange. - startSrvsLatch.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); + assertTrue(victimStartingLatch.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)); victim = false; - lifecycleBean = null; - List srvFuts = new ArrayList<>(TOPOLOGY_HISTORY_SIZE); + List> srvFuts = new ArrayList<>(TOPOLOGY_HISTORY_SIZE); try { // Major topology version that is corresponding to the start of the node with short topology history. final long topVer = 2; // Starting server nodes to exhaust the topology history. - for (int i = 2; i < 3 * TOPOLOGY_HISTORY_SIZE && !disco.isEmptyTopologyHistory(topVer); ++i) { + for (int i = 2; i < 2 + TOPOLOGY_HISTORY_SIZE; ++i) { final int currNodeIdx = i; final int joinedNodesCnt = disco.totalJoinedNodes(); @@ -212,50 +218,54 @@ public void testProperException() throws Exception { srvFuts.add(GridTestUtils.runAsync(() -> startGrid(currNodeIdx))); assertTrue("Failed to wait for a new server node [joinedNodesCnt=" + joinedNodesCnt + "]", - GridTestUtils.waitForCondition( + waitForCondition( () -> disco.totalJoinedNodes() >= (joinedNodesCnt + 1), DEFAULT_TIMEOUT)); - } - - assertTrue( - "Disco cache history is not empty for the topology [majorTopVer=" + topVer + ']', - disco.isEmptyTopologyHistory(topVer)); - // Let's continue the ongoing exchange. - exchangeLatch.countDown(); + log.error("TEST | nodes cnt 1: " + crd.cluster().nodes().size() + ", i = " + i); + } - boolean failureHnd = GridTestUtils.waitForCondition(() -> cpFailureCtx.get() != null, DEFAULT_TIMEOUT); + assertTrue(waitForCondition(() -> disco.isEmptyTopologyHistory(topVer), getTestTimeout(), 50)); - assertNull( - "Unexpected exception (probably, the topology history still exists [err=" + err + ']', - err.get()); + log.error("TEST | nodes cnt 2: " + crd.cluster().nodes().size()); - assertTrue("Failure handler was not triggered.", failureHnd); + // Let's continue the ongoing exchange. + victimStartDelayLatch.countDown(); - // Check that IgniteException was thrown instead of NullPointerException. - assertTrue( - "IgniteException must be thrown.", - X.hasCause(cpFailureCtx.get().error(), IgniteException.class)); + assertTrue(waitForCondition(() -> cpFailureCtx.get() != null, getTestTimeout(), 50)); - // Check that message contains a hint to fix the issue. - GridTestUtils.assertContains( - log, - cpFailureCtx.get().error().getMessage(), + assertContains(log, cpFailureCtx.get().error().getMessage(), "Consider increasing IGNITE_DISCOVERY_HISTORY_SIZE property. Current value is " + DISCO_HISTORY_SIZE); } finally { + log.error("TEST | nodes cnt 4: " + crd.cluster().nodes().size()); + IgnitionEx.stop(getTestIgniteInstanceName(1), true, ShutdownPolicy.IMMEDIATE, true); + log.error("TEST | nodes cnt 5: " + crd.cluster().nodes().size()); + + AtomicInteger i0 = new AtomicInteger(1); + + AtomicReference addNodesStopErr = new AtomicReference<>(); + srvFuts.forEach(f -> { + log.error("TEST | stopping additional node " + i0.getAndIncrement()); + try { f.get(DEFAULT_TIMEOUT); + + log.error("TEST | additional node " + i0.get() + " stopped"); } - catch (IgniteCheckedException e) { - err.compareAndSet(null, e); + catch (Throwable e) { + log.error("TEST | error stopoing additional node " + i0.get(), e); + + addNodesStopErr.set(e); } }); + + assertNull("Unexpected additional nodes stop exception [err=" + addNodesStopErr.get() + ']', addNodesStopErr.get()); } - assertNull("Unexpected exception [err=" + err.get() + ']', err.get()); + log.error("TEST | nodes cnt 6: " + crd.cluster().nodes().size()); } /** diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessorTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessorTest.java index 32da11cbc7da6..e66bafef0e241 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessorTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/security/IgniteSecurityProcessorTest.java @@ -23,8 +23,9 @@ import org.apache.ignite.internal.IgniteDiagnosticRequest; import org.apache.ignite.internal.IgniteEx; import org.apache.ignite.internal.managers.GridManagerAdapter; -import org.apache.ignite.internal.managers.communication.GridIoSecurityAwareMessage; -import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi; +import org.apache.ignite.internal.processors.security.impl.TestSecuritySubject; +import org.apache.ignite.internal.thread.context.OperationContext; +import org.apache.ignite.internal.thread.context.Scope; import org.apache.ignite.testframework.GridTestUtils; import org.apache.ignite.testframework.ListeningTestLogger; import org.apache.ignite.testframework.LogListener; @@ -67,8 +68,6 @@ public void testThrowIllegalStateExceptionIfNodeNotFoundInDiscoCache() throws Ex getSpiMethod.setAccessible(true); - TcpCommunicationSpi spi = (TcpCommunicationSpi)getSpiMethod.invoke(cli.context().io()); - LogListener logPattern = LogListener .matches(s -> s.contains("Failed to obtain a security context.")) .times(1) @@ -76,15 +75,11 @@ public void testThrowIllegalStateExceptionIfNodeNotFoundInDiscoCache() throws Ex listeningLog.registerListener(logPattern); - spi.sendMessage(srv.localNode(), new GridIoSecurityAwareMessage( - UUID.randomUUID(), - PUBLIC_POOL, - TOPIC_CACHE, - new IgniteDiagnosticRequest(), - false, - 0, - false - )); + SecurityContextImpl testSecCtx = new SecurityContextImpl(new TestSecuritySubject().setId(UUID.randomUUID())); + + try (Scope ignored = OperationContext.set(IgniteSecurityProcessor.SEC_CTX_ATTR, testSecCtx)) { + cli.context().io().sendToGridTopic(srv.localNode(), TOPIC_CACHE, new IgniteDiagnosticRequest(), PUBLIC_POOL); + } GridTestUtils.waitForCondition(logPattern::check, getTestTimeout()); } 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,