This is an automated email from the ASF dual-hosted git repository.
markt-asf pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/main by this push:
new 69c70f228c Review "Reject non-positive membership timing properties at
start"
69c70f228c is described below
commit 69c70f228c47652cf206f1c5c28b76dc36056166
Author: Mark Thomas <[email protected]>
AuthorDate: Thu Oct 22 18:44:15 2026 +0100
Review "Reject non-positive membership timing properties at start"
Additional checks
---
.../catalina/tribes/membership/McastService.java | 10 ++++++---
.../membership/cloud/CloudMembershipProvider.java | 4 ++++
.../membership/cloud/CloudMembershipService.java | 11 ++++++----
.../membership/cloud/LocalStrings.properties | 1 +
.../tribes/membership/TestMcastService.java | 3 ++-
.../cloud/TestKubernetesMembershipProvider.java | 24 ++++++++++++++++++++++
6 files changed, 45 insertions(+), 8 deletions(-)
diff --git a/java/org/apache/catalina/tribes/membership/McastService.java
b/java/org/apache/catalina/tribes/membership/McastService.java
index 900ed90271..16027c6075 100644
--- a/java/org/apache/catalina/tribes/membership/McastService.java
+++ b/java/org/apache/catalina/tribes/membership/McastService.java
@@ -393,18 +393,22 @@ public class McastService extends MembershipServiceBase
implements MessageListen
throw new IllegalArgumentException(
sm.getString("membershipService.invalidTimingProperty",
"memberDropTime", Long.valueOf(dropTime)));
}
+ // The recovery sleep time only matters if recovery is enabled
+ boolean recEnabled =
Boolean.parseBoolean(properties.getProperty("recoveryEnabled"));
+ long recSlpTime =
Long.parseLong(properties.getProperty("recoverySleepTime"));
+ if (recEnabled && recSlpTime <= 0) {
+ throw new
IllegalArgumentException(sm.getString("membershipService.invalidTimingProperty",
+ "recoverySleepTime", Long.valueOf(recSlpTime)));
+ }
impl = new McastServiceImpl(localMember, frequency, dropTime,
Integer.parseInt(properties.getProperty("mcastPort")), bind,
java.net.InetAddress.getByName(properties.getProperty("mcastAddress")), ttl,
soTimeout, this, this,
Boolean.parseBoolean(properties.getProperty("localLoopbackDisabled")));
impl.setMembershipService(this);
- String value = properties.getProperty("recoveryEnabled");
- boolean recEnabled = Boolean.parseBoolean(value);
impl.setRecoveryEnabled(recEnabled);
int recCnt =
Integer.parseInt(properties.getProperty("recoveryCounter"));
impl.setRecoveryCounter(recCnt);
- long recSlpTime =
Long.parseLong(properties.getProperty("recoverySleepTime"));
impl.setRecoverySleepTime(recSlpTime);
impl.setChannel(channel);
diff --git
a/java/org/apache/catalina/tribes/membership/cloud/CloudMembershipProvider.java
b/java/org/apache/catalina/tribes/membership/cloud/CloudMembershipProvider.java
index 3839136fce..a861d6b120 100644
---
a/java/org/apache/catalina/tribes/membership/cloud/CloudMembershipProvider.java
+++
b/java/org/apache/catalina/tribes/membership/cloud/CloudMembershipProvider.java
@@ -176,6 +176,10 @@ public abstract class CloudMembershipProvider extends
MembershipProviderBase imp
connectionTimeout = service.getConnectTimeout();
readTimeout = service.getReadTimeout();
expirationTime = service.getExpirationTime();
+ if (expirationTime <= 0) {
+ throw new
IllegalArgumentException(sm.getString("cloudMembershipProvider.invalidTimingProperty",
+ "expirationTime", Long.valueOf(expirationTime)));
+ }
localIp = InetAddress.getLocalHost().getHostAddress();
port = Integer.parseInt(properties.getProperty("tcpListenPort"));
diff --git
a/java/org/apache/catalina/tribes/membership/cloud/CloudMembershipService.java
b/java/org/apache/catalina/tribes/membership/cloud/CloudMembershipService.java
index 15d0fd45b0..61db668616 100644
---
a/java/org/apache/catalina/tribes/membership/cloud/CloudMembershipService.java
+++
b/java/org/apache/catalina/tribes/membership/cloud/CloudMembershipService.java
@@ -162,10 +162,13 @@ public class CloudMembershipService extends
MembershipServiceBase implements Clo
if (log.isTraceEnabled()) {
log.trace("Using membershipProvider: " + provider);
}
- membershipProvider = (MembershipProvider)
Class.forName(provider).getConstructor().newInstance();
- membershipProvider.setMembershipListener(this);
- membershipProvider.setMembershipService(this);
- membershipProvider.init(properties);
+ MembershipProvider newProvider = (MembershipProvider)
Class.forName(provider).getConstructor().newInstance();
+ newProvider.setMembershipListener(this);
+ newProvider.setMembershipService(this);
+ newProvider.init(properties);
+ // Only keep the provider once it has been initialised so that a
rejected configuration does not leave an
+ // uninitialised provider behind for the next start
+ membershipProvider = newProvider;
}
membershipProvider.start(level);
diff --git
a/java/org/apache/catalina/tribes/membership/cloud/LocalStrings.properties
b/java/org/apache/catalina/tribes/membership/cloud/LocalStrings.properties
index 274e59630d..a55ca89c11 100644
--- a/java/org/apache/catalina/tribes/membership/cloud/LocalStrings.properties
+++ b/java/org/apache/catalina/tribes/membership/cloud/LocalStrings.properties
@@ -22,6 +22,7 @@ abstractStream.trustManagerError=Could not create trust
manager for [{0}]
certificateStream.clientCertError=Could not create key manager for [{0}]
([{1}])
cloudMembershipProvider.add=Member [{0}] added
+cloudMembershipProvider.invalidTimingProperty=The timing property [{0}] is set
to [{1}]. It must be greater than zero.
cloudMembershipProvider.noDigest=Unable to create an MD5 MessageDigest instance
cloudMembershipProvider.remove=Member [{0}] disappeared
cloudMembershipProvider.start=Namespace [{0}] set; clustering enabled
diff --git a/test/org/apache/catalina/tribes/membership/TestMcastService.java
b/test/org/apache/catalina/tribes/membership/TestMcastService.java
index b54696b3a5..325f9e3bf4 100644
--- a/test/org/apache/catalina/tribes/membership/TestMcastService.java
+++ b/test/org/apache/catalina/tribes/membership/TestMcastService.java
@@ -129,7 +129,8 @@ public class TestMcastService {
*/
@Test
public void testStartRejectsNonPositiveTimingProperties() throws Exception
{
- String[] invalid = { "mcastFrequency=0", "mcastFrequency=-1",
"memberDropTime=0", "memberDropTime=-5" };
+ String[] invalid = { "mcastFrequency=0", "mcastFrequency=-1",
"memberDropTime=0", "memberDropTime=-5",
+ "recoverySleepTime=0", "recoverySleepTime=-1" };
for (String entry : invalid) {
String[] property = entry.split("=");
Properties props = new Properties();
diff --git
a/test/org/apache/catalina/tribes/membership/cloud/TestKubernetesMembershipProvider.java
b/test/org/apache/catalina/tribes/membership/cloud/TestKubernetesMembershipProvider.java
index b54cae7de6..9c38a4b857 100644
---
a/test/org/apache/catalina/tribes/membership/cloud/TestKubernetesMembershipProvider.java
+++
b/test/org/apache/catalina/tribes/membership/cloud/TestKubernetesMembershipProvider.java
@@ -61,4 +61,28 @@ public class TestKubernetesMembershipProvider {
Assert.assertTrue(expected.getCause() instanceof IOException);
}
}
+
+ /*
+ * A non-positive expiration time expires every member on every heartbeat.
Such a configuration must be
+ * rejected when the provider is initialised, and must not leave an
uninitialised provider behind.
+ */
+ @Test
+ public void testStartRejectsNonPositiveExpirationTime() throws Exception {
+ for (long expirationTime : new long[] { 0, -5 }) {
+ GroupChannel channel = new GroupChannel();
+ channel.setName("TestKubernetesMembershipProvider-" +
System.nanoTime());
+
+ CloudMembershipService service = new CloudMembershipService();
+ service.setChannel(channel);
+ service.setLocalMemberProperties("127.0.0.1", 4007, 0, 0);
+ service.setExpirationTime(expirationTime);
+ try {
+ service.start(CloudMembershipService.MBR_RX);
+ Assert.fail("start() must reject an expiration time of " +
expirationTime);
+ } catch (IllegalArgumentException expected) {
+ // The configuration must be rejected before the provider is
used
+ }
+ Assert.assertNull(service.getMembershipProvider());
+ }
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]