This is an automated email from the ASF dual-hosted git repository.
markt-asf pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/10.1.x by this push:
new eb8f46852a Review "Reject non-positive membership timing properties at
start"
eb8f46852a is described below
commit eb8f46852aa059b656c53e9dea92682233cde290
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 | 25 ++++++++++++++++++++++
6 files changed, 46 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 b31b3efa37..ba2054b295 100644
---
a/java/org/apache/catalina/tribes/membership/cloud/CloudMembershipProvider.java
+++
b/java/org/apache/catalina/tribes/membership/cloud/CloudMembershipProvider.java
@@ -173,6 +173,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 3037e9feb5..07b1e38686 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 ee641fcaeb..3f433d3635 100644
--- a/java/org/apache/catalina/tribes/membership/cloud/LocalStrings.properties
+++ b/java/org/apache/catalina/tribes/membership/cloud/LocalStrings.properties
@@ -25,6 +25,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 9fc962c54e..335d3d1244 100644
---
a/test/org/apache/catalina/tribes/membership/cloud/TestKubernetesMembershipProvider.java
+++
b/test/org/apache/catalina/tribes/membership/cloud/TestKubernetesMembershipProvider.java
@@ -62,6 +62,31 @@ public class TestKubernetesMembershipProvider {
}
}
+
+ /*
+ * 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());
+ }
+ }
+
/*
* The local member is resolved when the channel receiver starts, or is
configured explicitly. Starting the
* membership alone, without either, must fail with a clear error rather
than a NumberFormatException from a
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]