This is an automated email from the ASF dual-hosted git repository.

ycai pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra-sidecar.git


The following commit(s) were added to refs/heads/trunk by this push:
     new c4b5f402 CASSSIDECAR-189: Fix SidecarSchema stuck at initialization 
due to ClusterLeaseTask scheduling (#175)
c4b5f402 is described below

commit c4b5f402098cadecb68193fefd0ad7bd58215965
Author: Yifan Cai <[email protected]>
AuthorDate: Tue Jan 21 18:25:23 2025 -0800

    CASSSIDECAR-189: Fix SidecarSchema stuck at initialization due to 
ClusterLeaseTask scheduling (#175)
    
    Patch by Yifan Cai; Reviewed by Francisco Guerrero for CASSSIDECAR-189
---
 CHANGES.txt                                        |   1 +
 .../sidecar/config/KeyStoreConfiguration.java      |   7 +-
 .../coordination/ClusterLeaseClaimTask.java        |   5 +-
 .../sidecar/db/schema/SidecarInternalKeyspace.java |   8 +-
 .../cassandra/sidecar/server/MainModule.java       |   4 +-
 .../ClusterLeaseClaimTaskIntegrationTest.java      |  73 ++++++--------
 .../cassandra/sidecar/db/SidecarSchemaIntTest.java | 110 +++++++++++++++++++++
 .../sidecar/testing/IntegrationTestBase.java       |  24 ++++-
 .../sidecar/testing/IntegrationTestModule.java     |  12 ++-
 9 files changed, 188 insertions(+), 56 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index 357d3374..fbb426bc 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,6 @@
 1.0.0
 -----
+ * Fix SidecarSchema stuck at initialization due to ClusterLeaseTask 
scheduling (CASSSIDECAR-189)
  * Add RBAC Authorization support in Sidecar (CASSSIDECAR-161)
  * Standardize configuration for duration units (CASSSIDECAR-186)
  * Adds sidecar endpoint for node decommissioning operation (CASSANDRASC-151)
diff --git 
a/server/src/main/java/org/apache/cassandra/sidecar/config/KeyStoreConfiguration.java
 
b/server/src/main/java/org/apache/cassandra/sidecar/config/KeyStoreConfiguration.java
index 152248f6..7123b7ec 100644
--- 
a/server/src/main/java/org/apache/cassandra/sidecar/config/KeyStoreConfiguration.java
+++ 
b/server/src/main/java/org/apache/cassandra/sidecar/config/KeyStoreConfiguration.java
@@ -19,6 +19,7 @@
 package org.apache.cassandra.sidecar.config;
 
 import 
org.apache.cassandra.sidecar.common.server.utils.SecondBoundConfiguration;
+import org.jetbrains.annotations.NotNull;
 
 /**
  * Encapsulates key or trust store option configurations
@@ -44,10 +45,11 @@ public interface KeyStoreConfiguration
 
     /**
      * Returns the interval in which the key store will be checked for 
filesystem changes. Setting
-     * this value to 0 or negative will disable reloading the store.
+     * this value to {@link SecondBoundConfiguration#ZERO} will disable 
reloading the store.
      *
      * @return the interval in which the key store will be checked for changes 
in the filesystem
      */
+    @NotNull
     SecondBoundConfiguration checkInterval();
 
     /**
@@ -55,7 +57,8 @@ public interface KeyStoreConfiguration
      */
     default boolean reloadStore()
     {
-        return checkInterval().compareTo(SecondBoundConfiguration.ZERO) > 0;
+        SecondBoundConfiguration interval = checkInterval();
+        return interval != SecondBoundConfiguration.ZERO && 
!interval.equals(SecondBoundConfiguration.ZERO);
     }
 
     /**
diff --git 
a/server/src/main/java/org/apache/cassandra/sidecar/coordination/ClusterLeaseClaimTask.java
 
b/server/src/main/java/org/apache/cassandra/sidecar/coordination/ClusterLeaseClaimTask.java
index e584dc3d..4f0942e4 100644
--- 
a/server/src/main/java/org/apache/cassandra/sidecar/coordination/ClusterLeaseClaimTask.java
+++ 
b/server/src/main/java/org/apache/cassandra/sidecar/coordination/ClusterLeaseClaimTask.java
@@ -26,8 +26,8 @@ import java.util.function.Function;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.datastax.driver.core.exceptions.CASWriteUnknownException;
 import com.datastax.driver.core.exceptions.NoHostAvailableException;
+import com.datastax.driver.core.exceptions.QueryConsistencyException;
 import io.vertx.core.Promise;
 import io.vertx.core.Vertx;
 import org.apache.cassandra.sidecar.common.server.utils.DurationSpec;
@@ -187,7 +187,7 @@ public class ClusterLeaseClaimTask implements PeriodicTask
             LOGGER.debug("Attempting to {} lease for sidecarHostId={}", 
actionName, sidecarHostId);
             return actionFn.apply(sidecarHostId).currentOwner;
         }
-        catch (CASWriteUnknownException | NoHostAvailableException e)
+        catch (QueryConsistencyException | NoHostAvailableException e)
         {
             LOGGER.debug("Unable to {} lease for sidecarHostId={}", 
actionName, sidecarHostId, e);
         }
@@ -195,7 +195,6 @@ public class ClusterLeaseClaimTask implements PeriodicTask
         {
             LOGGER.error("Unable to {} lease for sidecarHostId={}", 
actionName, sidecarHostId, e);
         }
-        LOGGER.debug("Unable to perform lease operation for sidecarHostId={}", 
sidecarHostId);
         return null; // owner is unknown
     }
 
diff --git 
a/server/src/main/java/org/apache/cassandra/sidecar/db/schema/SidecarInternalKeyspace.java
 
b/server/src/main/java/org/apache/cassandra/sidecar/db/schema/SidecarInternalKeyspace.java
index 01fb01ea..dd5af278 100644
--- 
a/server/src/main/java/org/apache/cassandra/sidecar/db/schema/SidecarInternalKeyspace.java
+++ 
b/server/src/main/java/org/apache/cassandra/sidecar/db/schema/SidecarInternalKeyspace.java
@@ -73,13 +73,15 @@ public class SidecarInternalKeyspace extends AbstractSchema
     {
         super.initializeInternal(session, shouldCreateSchema);
 
+        boolean initialized = true;
         for (AbstractSchema schema : tableSchemas)
         {
-            if (!schema.initialize(session, shouldCreateSchema))
-                return false;
+            // Attempts to initialize all schemas.
+            // Sets initialized to false if any of the schema initialization 
fails
+            initialized = schema.initialize(session, shouldCreateSchema) && 
initialized;
         }
 
-        return true;
+        return initialized;
     }
 
     @Override
diff --git 
a/server/src/main/java/org/apache/cassandra/sidecar/server/MainModule.java 
b/server/src/main/java/org/apache/cassandra/sidecar/server/MainModule.java
index 293075bd..8f7d6a94 100644
--- a/server/src/main/java/org/apache/cassandra/sidecar/server/MainModule.java
+++ b/server/src/main/java/org/apache/cassandra/sidecar/server/MainModule.java
@@ -153,8 +153,8 @@ import org.apache.cassandra.sidecar.utils.XXHash32Provider;
 
 import static 
org.apache.cassandra.sidecar.common.ApiEndpointsV1.API_V1_ALL_ROUTES;
 import static 
org.apache.cassandra.sidecar.common.server.utils.ByteUtils.bytesToHumanReadableBinaryPrefix;
+import static 
org.apache.cassandra.sidecar.server.SidecarServerEvents.ON_CASSANDRA_CQL_READY;
 import static 
org.apache.cassandra.sidecar.server.SidecarServerEvents.ON_SERVER_STOP;
-import static 
org.apache.cassandra.sidecar.server.SidecarServerEvents.ON_SIDECAR_SCHEMA_INITIALIZED;
 
 /**
  * Provides main binding for more complex Guice dependencies
@@ -853,7 +853,7 @@ public class MainModule extends AbstractModule
                                                      ClusterLeaseClaimTask 
clusterLeaseClaimTask)
     {
         PeriodicTaskExecutor periodicTaskExecutor = new 
PeriodicTaskExecutor(executorPools, clusterLease);
-        vertx.eventBus().localConsumer(ON_SIDECAR_SCHEMA_INITIALIZED.address(),
+        vertx.eventBus().localConsumer(ON_CASSANDRA_CQL_READY.address(),
                                        ignored -> 
periodicTaskExecutor.schedule(clusterLeaseClaimTask));
         return periodicTaskExecutor;
     }
diff --git 
a/server/src/test/integration/org/apache/cassandra/sidecar/coordination/ClusterLeaseClaimTaskIntegrationTest.java
 
b/server/src/test/integration/org/apache/cassandra/sidecar/coordination/ClusterLeaseClaimTaskIntegrationTest.java
index bee4e1f2..0e614339 100644
--- 
a/server/src/test/integration/org/apache/cassandra/sidecar/coordination/ClusterLeaseClaimTaskIntegrationTest.java
+++ 
b/server/src/test/integration/org/apache/cassandra/sidecar/coordination/ClusterLeaseClaimTaskIntegrationTest.java
@@ -33,6 +33,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.StreamSupport;
 
+import com.google.common.util.concurrent.Uninterruptibles;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.params.ParameterizedTest;
@@ -89,8 +90,9 @@ import static org.mockito.Mockito.when;
 @Tag("heavy")
 class ClusterLeaseClaimTaskIntegrationTest
 {
-    private static final Logger LOGGER = 
LoggerFactory.getLogger(ClusterLeaseClaimTaskIntegrationTest.class);
     public static final int CONCURRENT_PROCESSES = 12;
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(ClusterLeaseClaimTaskIntegrationTest.class);
+    private static final int LEASE_SCHEMA_TTL_SECONDS = 10;
     final List<CQLSessionProvider> sessionProviderList = new ArrayList<>();
     final Vertx vertx = Vertx.vertx();
     SchemaKeyspaceConfiguration mockSchemaConfig;
@@ -105,7 +107,7 @@ class ClusterLeaseClaimTaskIntegrationTest
         
when(mockSchemaConfig.keyspace()).thenReturn(SchemaKeyspaceConfigurationImpl.DEFAULT_KEYSPACE);
         
when(mockSchemaConfig.replicationStrategy()).thenReturn(SchemaKeyspaceConfigurationImpl.DEFAULT_REPLICATION_STRATEGY);
         
when(mockSchemaConfig.replicationFactor()).thenReturn(SchemaKeyspaceConfigurationImpl.DEFAULT_REPLICATION_FACTOR);
-        
when(mockSchemaConfig.leaseSchemaTTL()).thenReturn(SecondBoundConfiguration.parse("5s"));
+        
when(mockSchemaConfig.leaseSchemaTTL()).thenReturn(SecondBoundConfiguration.parse(LEASE_SCHEMA_TTL_SECONDS
 + "s"));
     }
 
     @ParameterizedTest(name = "{index} => version {0}")
@@ -117,10 +119,9 @@ class ClusterLeaseClaimTaskIntegrationTest
         Versions.Version requestedVersion = versions.getLatest(new 
Semver(version.version(), Semver.SemverType.LOOSE));
 
         // Spin up a 3-node cluster
-        try (AbstractCluster<?> cluster = UpgradeableCluster.build(0)
+        try (AbstractCluster<?> cluster = UpgradeableCluster.build(3)
                                                             
.withDynamicPortAllocation(true) // to allow parallel test runs
                                                             
.withVersion(requestedVersion)
-                                                            .withDC("dc0", 3)
                                                             .withConfig(config 
-> config.with(Feature.NATIVE_PROTOCOL))
                                                             .start())
         {
@@ -146,6 +147,7 @@ class ClusterLeaseClaimTaskIntegrationTest
         AtomicReference<Object[][]> currentLeaseholderQueryResult = new 
AtomicReference<>();
         AtomicReference<TestInstanceWrapper> currentLeaseholder = new 
AtomicReference<>();
         loopAssert(3, () -> {
+            cleanupDeltaGaugeMetrics(simulatedInstances);
             runLeaseAcquireProcess(pool, simulatedInstances);
             Object[][] resultSet = queryCurrentLeaseholders(cluster);
             currentLeaseholderQueryResult.set(resultSet);
@@ -246,37 +248,18 @@ class ClusterLeaseClaimTaskIntegrationTest
         // then disable binary
         simulateDisableBinaryOfLeaseholder(simulatedInstances);
 
-        ScheduleDecision scheduleDecision = null;
-        for (int i = 0; i < 20; i++)
-        {
-            leaseholder.clusterLeaseClaimTask.runClaimProcess();
-            scheduleDecision = leaseholder.clusterLease.toScheduleDecision();
+        // Wait for lease to expire in both leaseholder and database
+        Uninterruptibles.sleepUninterruptibly(LEASE_SCHEMA_TTL_SECONDS, 
TimeUnit.SECONDS);
 
-            if (scheduleDecision != ScheduleDecision.RESCHEDULE)
-            {
-                int ttlSeconds = Math.max(1, maybeDetermineTTL(cluster));
-                LOGGER.info("TTL is {} seconds", ttlSeconds);
-                // wait for the leaseholder to give the lease
-                // query the TTL value and sleep for that amount of time
-                // before attempting again
-                sleepUninterruptibly(ttlSeconds, TimeUnit.SECONDS);
-            }
-            else break;
-        }
-        assertThat(scheduleDecision).as("The leaseholder should give up the 
lease")
-                                    .isEqualTo(ScheduleDecision.RESCHEDULE);
-        // ensure the data is TTL'd in the database
-        for (int i = 0; i < 20; i++)
-        {
+        loopAssert(3, 1000, () -> {
+            leaseholder.clusterLeaseClaimTask.runClaimProcess();
+            ScheduleDecision scheduleDecision = 
leaseholder.clusterLease.toScheduleDecision();
+            assertThat(scheduleDecision).as("The leaseholder should give up 
the lease")
+                                        
.isEqualTo(ScheduleDecision.RESCHEDULE);
+            // ensure the data is TTL'd in the database
             long rowCount = rowCountInLeaseTable(cluster);
-            if (rowCount == 0)
-            {
-                // data has been TTL'd
-                return;
-            }
-            sleepUninterruptibly(1, TimeUnit.SECONDS);
-        }
-        fail("Data was not TTL'd in the database");
+            assertThat(rowCount).describedAs("Lease should be TTL'd").isZero();
+        });
     }
 
     private void validateMetrics(List<TestInstanceWrapper> simulatedInstances, 
int expectedLeaseholderCount)
@@ -289,8 +272,18 @@ class ClusterLeaseClaimTaskIntegrationTest
                                                                       
.isEqualTo(expectedLeaseholderCount);
     }
 
+    // similar to validateMetrics but w/o validation. Read the delta gauge 
values out to reset
+    private void cleanupDeltaGaugeMetrics(List<TestInstanceWrapper> 
simulatedInstances)
+    {
+        // Validate metrics, metrics instance is shared so we check on any 
instance
+        CoordinationMetrics coordinationMetrics = 
simulatedInstances.get(0).metrics.server().coordination();
+        coordinationMetrics.participants.metric.getValue();
+        coordinationMetrics.leaseholders.metric.getValue();
+    }
+
     private void runLeaseAcquireProcess(ExecutorService pool, 
List<TestInstanceWrapper> simulatedInstances)
     {
+        cleanupDeltaGaugeMetrics(simulatedInstances);
         int electorateSize = simulatedInstances.size();
         CountDownLatch latch = new CountDownLatch(electorateSize);
         CountDownLatch completedLatch = new CountDownLatch(electorateSize);
@@ -438,16 +431,6 @@ class ClusterLeaseClaimTaskIntegrationTest
         return instances;
     }
 
-    static int maybeDetermineTTL(AbstractCluster<?> cluster)
-    {
-        SimpleQueryResult result
-        = cluster.getFirstRunningInstance()
-                 .coordinator()
-                 .executeWithResult("SELECT ttl(owner) FROM 
sidecar_internal.sidecar_lease_v1 WHERE name = 'cluster_lease_holder'",
-                                    ConsistencyLevel.LOCAL_QUORUM);
-        return result.hasNext() ? result.next().getInteger(0) : 0;
-    }
-
     static long rowCountInLeaseTable(AbstractCluster<?> cluster)
     {
         SimpleQueryResult rows = cluster.getFirstRunningInstance()
@@ -476,7 +459,9 @@ class ClusterLeaseClaimTaskIntegrationTest
         {
             try
             {
-                
cluster.getFirstRunningInstance().coordinator().execute("DELETE FROM 
sidecar_internal.sidecar_lease_v1 WHERE name = 'cluster_lease_holder'",
+                
cluster.getFirstRunningInstance().coordinator().execute("DELETE FROM 
sidecar_internal.sidecar_lease_v1 " +
+                                                                        "WHERE 
name = 'cluster_lease_holder' " +
+                                                                        "IF 
EXISTS",
                                                                         
ConsistencyLevel.QUORUM);
                 LOGGER.info("Successfully removed current leaseholder from 
database");
                 return;
diff --git 
a/server/src/test/integration/org/apache/cassandra/sidecar/db/SidecarSchemaIntTest.java
 
b/server/src/test/integration/org/apache/cassandra/sidecar/db/SidecarSchemaIntTest.java
new file mode 100644
index 00000000..d2e79f42
--- /dev/null
+++ 
b/server/src/test/integration/org/apache/cassandra/sidecar/db/SidecarSchemaIntTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.cassandra.sidecar.db;
+
+import java.util.concurrent.TimeUnit;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
+import com.google.inject.Singleton;
+import io.vertx.core.Vertx;
+import org.apache.cassandra.sidecar.common.server.utils.DurationSpec;
+import 
org.apache.cassandra.sidecar.common.server.utils.MillisecondBoundConfiguration;
+import org.apache.cassandra.sidecar.config.CoordinationConfiguration;
+import org.apache.cassandra.sidecar.config.PeriodicTaskConfiguration;
+import org.apache.cassandra.sidecar.config.ServiceConfiguration;
+import org.apache.cassandra.sidecar.config.yaml.CoordinationConfigurationImpl;
+import org.apache.cassandra.sidecar.config.yaml.PeriodicTaskConfigurationImpl;
+import org.apache.cassandra.sidecar.coordination.ClusterLease;
+import org.apache.cassandra.sidecar.coordination.ClusterLeaseClaimTask;
+import org.apache.cassandra.sidecar.coordination.ElectorateMembership;
+import org.apache.cassandra.sidecar.db.schema.SidecarSchema;
+import org.apache.cassandra.sidecar.metrics.SidecarMetrics;
+import org.apache.cassandra.sidecar.testing.IntegrationTestBase;
+import org.apache.cassandra.testing.CassandraIntegrationTest;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class SidecarSchemaIntTest extends IntegrationTestBase
+{
+    @Override
+    protected void beforeSetup()
+    {
+        installTestSpecificModule(new AbstractModule()
+        {
+            @Provides
+            @Singleton
+            public ClusterLease clusterLease()
+            {
+                // start with INDETERMINATE to compete for a leaseholder 
first, then init schema
+                return new ClusterLease(ClusterLease.Ownership.INDETERMINATE);
+            }
+
+            @Provides
+            @Singleton
+            public CoordinationConfiguration 
clusterLeaseClaimTaskConfiguration()
+            {
+                // increase the claim frequency
+                PeriodicTaskConfiguration taskConfig = new 
PeriodicTaskConfigurationImpl(true,
+                                                                               
          MillisecondBoundConfiguration.parse("1s"),
+                                                                               
          MillisecondBoundConfiguration.parse("1s"));
+                return new CoordinationConfigurationImpl(taskConfig);
+            }
+
+            @Provides
+            @Singleton
+            public ClusterLeaseClaimTask clusterLeaseClaimTask(Vertx vertx,
+                                                               
ServiceConfiguration serviceConfiguration,
+                                                               
ElectorateMembership electorateMembership,
+                                                               
SidecarLeaseDatabaseAccessor accessor,
+                                                               ClusterLease 
clusterLease,
+                                                               SidecarMetrics 
metrics)
+            {
+                return new ClusterLeaseClaimTask(vertx,
+                                                 serviceConfiguration,
+                                                 electorateMembership,
+                                                 accessor,
+                                                 clusterLease,
+                                                 metrics)
+                {
+                    @Override
+                    public DurationSpec delay()
+                    {
+                        // ignore the minimum delay check that is coded in 
ClusterLeaseClaimTask
+                        return MillisecondBoundConfiguration.parse("1s");
+                    }
+                };
+            }
+        });
+    }
+
+    @CassandraIntegrationTest
+    void testSidecarSchemaInitializationFromBlank()
+    {
+        waitForSchemaReady(60, TimeUnit.SECONDS);
+        SidecarSchema sidecarSchema = 
injector.getInstance(SidecarSchema.class);
+        assertThat(sidecarSchema.isInitialized())
+        .describedAs("SidecarSchema should be initialized")
+        .isTrue();
+        ClusterLease clusterLease = injector.getInstance(ClusterLease.class);
+        assertThat(clusterLease.isClaimedByLocalSidecar())
+        .describedAs("ClusterLease should be claimed by the local sidecar")
+        .isTrue();
+    }
+}
diff --git 
a/server/src/test/integration/org/apache/cassandra/sidecar/testing/IntegrationTestBase.java
 
b/server/src/test/integration/org/apache/cassandra/sidecar/testing/IntegrationTestBase.java
index d04723ae..78a728f1 100644
--- 
a/server/src/test/integration/org/apache/cassandra/sidecar/testing/IntegrationTestBase.java
+++ 
b/server/src/test/integration/org/apache/cassandra/sidecar/testing/IntegrationTestBase.java
@@ -50,6 +50,7 @@ import com.datastax.driver.core.Metadata;
 import com.datastax.driver.core.Session;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
+import com.google.inject.Module;
 import com.google.inject.util.Modules;
 import io.vertx.core.Vertx;
 import io.vertx.core.eventbus.Message;
@@ -109,12 +110,15 @@ public abstract class IntegrationTestBase
     protected CassandraSidecarTestContext sidecarTestContext;
     protected Injector injector;
     private final List<Throwable> testExceptions = new ArrayList<>();
+    private Module testSpecificModule;
 
     @BeforeEach
     void setup(AbstractCassandraTestContext cassandraTestContext, TestInfo 
testInfo) throws Exception
     {
         testExceptions.clear();
 
+        beforeSetup();
+
         ca = cassandraTestContext.ca;
         truststorePath = cassandraTestContext.truststorePath;
         serverKeystorePath = cassandraTestContext.serverKeystorePath;
@@ -126,7 +130,16 @@ public abstract class IntegrationTestBase
         System.setProperty("cassandra.testtag", 
testInfo.getTestClass().get().getCanonicalName());
         System.setProperty("suitename", testInfo.getDisplayName() + ": " + 
cassandraTestContext.version);
         int clusterSize = cassandraTestContext.clusterSize();
-        injector = Guice.createInjector(Modules.override(new 
MainModule()).with(integrationTestModule));
+        // list of modules that override the priors; hence order matters
+        List<Module> modules = new ArrayList<>();
+        modules.add(new MainModule());
+        modules.add(integrationTestModule);
+        if (testSpecificModule != null)
+        {
+            modules.add(testSpecificModule);
+        }
+        Module mergedModule = modules.stream().reduce((m1, m2) -> 
Modules.override(m1).with(m2)).get();
+        injector = Guice.createInjector(mergedModule);
         vertx = injector.getInstance(Vertx.class);
 
         SslConfiguration sslConfig = 
cassandraTestContext.annotation.authMode().equals(AuthMode.MUTUAL_TLS)
@@ -184,6 +197,15 @@ public abstract class IntegrationTestBase
         sidecarTestContext.close();
     }
 
+    protected void beforeSetup()
+    {
+    }
+
+    protected void installTestSpecificModule(Module testSpecificModule)
+    {
+        this.testSpecificModule = testSpecificModule;
+    }
+
     protected void waitForSchemaReady(long timeout, TimeUnit timeUnit)
     {
         CountDownLatch latch = new CountDownLatch(1);
diff --git 
a/server/src/test/integration/org/apache/cassandra/sidecar/testing/IntegrationTestModule.java
 
b/server/src/test/integration/org/apache/cassandra/sidecar/testing/IntegrationTestModule.java
index c07e8700..dc341770 100644
--- 
a/server/src/test/integration/org/apache/cassandra/sidecar/testing/IntegrationTestModule.java
+++ 
b/server/src/test/integration/org/apache/cassandra/sidecar/testing/IntegrationTestModule.java
@@ -35,6 +35,7 @@ import 
org.apache.cassandra.sidecar.common.server.CQLSessionProvider;
 import 
org.apache.cassandra.sidecar.common.server.utils.MillisecondBoundConfiguration;
 import 
org.apache.cassandra.sidecar.common.server.utils.SecondBoundConfiguration;
 import org.apache.cassandra.sidecar.config.AccessControlConfiguration;
+import org.apache.cassandra.sidecar.config.CoordinationConfiguration;
 import org.apache.cassandra.sidecar.config.ParameterizedClassConfiguration;
 import org.apache.cassandra.sidecar.config.PeriodicTaskConfiguration;
 import org.apache.cassandra.sidecar.config.ServiceConfiguration;
@@ -42,6 +43,7 @@ import 
org.apache.cassandra.sidecar.config.SidecarConfiguration;
 import org.apache.cassandra.sidecar.config.SslConfiguration;
 import org.apache.cassandra.sidecar.config.yaml.AccessControlConfigurationImpl;
 import org.apache.cassandra.sidecar.config.yaml.CacheConfigurationImpl;
+import org.apache.cassandra.sidecar.config.yaml.CoordinationConfigurationImpl;
 import org.apache.cassandra.sidecar.config.yaml.KeyStoreConfigurationImpl;
 import 
org.apache.cassandra.sidecar.config.yaml.ParameterizedClassConfigurationImpl;
 import org.apache.cassandra.sidecar.config.yaml.PeriodicTaskConfigurationImpl;
@@ -89,13 +91,14 @@ public class IntegrationTestModule extends AbstractModule
 
     @Provides
     @Singleton
-    public SidecarConfiguration configuration()
+    public SidecarConfiguration configuration(CoordinationConfiguration 
clusterLeaseClaimTaskConfiguration)
     {
         ServiceConfiguration conf
         = TestServiceConfiguration.builder()
                                   
.schemaKeyspaceConfiguration(SchemaKeyspaceConfigurationImpl.builder()
                                                                                
               .isEnabled(true)
                                                                                
               .build())
+                                  
.coordinationConfiguration(clusterLeaseClaimTaskConfiguration)
                                   .build();
         PeriodicTaskConfiguration healthCheckConfiguration
         = new PeriodicTaskConfigurationImpl(true,
@@ -122,6 +125,13 @@ public class IntegrationTestModule extends AbstractModule
                                        .build();
     }
 
+    @Provides
+    @Singleton
+    public CoordinationConfiguration clusterLeaseClaimTaskConfiguration()
+    {
+        return new CoordinationConfigurationImpl(new 
PeriodicTaskConfigurationImpl());
+    }
+
     @Provides
     @Singleton
     public CQLSessionProvider cqlSessionProvider(Vertx vertx)


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to