Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add validation of repair interval and alarms #567

Merged
merged 1 commit into from
Sep 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Version 5.0.0 (Not yet released)

* Add validation of repair interval and alarms - Issue #560
* Insert into repair history only on session finish - Issue #565
* Use Caffeine caches instead of Guava - Issue #534
* Validate TLS config for JMX and CQL - Issue #529
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public void setRepairConfig(final GlobalRepairConfig globalRepairConfig)
if (globalRepairConfig != null)
{
myRepairConfig = globalRepairConfig;
myRepairConfig.validate("Global");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,25 @@ public final void setRepairType(final String repairType)
myRepairType = RepairOptions.RepairType.valueOf(repairType.toUpperCase(Locale.US));
}

public final void validate(final String repairConfigType)
{
long repairIntervalSeconds = myRepairInterval.getInterval(TimeUnit.SECONDS);
long warningIntervalSeconds = myAlarm.getWarningInverval().getInterval(TimeUnit.SECONDS);
if (repairIntervalSeconds >= warningIntervalSeconds)
{
throw new IllegalArgumentException(String.format("%s repair interval must be shorter than warning interval."
+ " Current repair interval: %d seconds, warning interval: %d seconds", repairConfigType,
repairIntervalSeconds, warningIntervalSeconds));
}
long errorIntervalSeconds = myAlarm.getErrorInterval().getInterval(TimeUnit.SECONDS);
if (warningIntervalSeconds >= errorIntervalSeconds)
{
throw new IllegalArgumentException(String.format("%s warning interval must be shorter than error interval."
+ " Current warning interval: %d seconds, error interval: %d seconds", repairConfigType,
warningIntervalSeconds, errorIntervalSeconds));
}
}

/**
* Convert this object to {@link com.ericsson.bss.cassandra.ecchronos.core.repair.RepairConfiguration}.
* @return {@link com.ericsson.bss.cassandra.ecchronos.core.repair.RepairConfiguration}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,14 @@ void setTableConfigs(final List<TableRepairConfig> tableRepairConfigs)
if (tableRepairConfigs != null)
{
Map<String, Set<TableRepairConfig>> tableConfigs = new HashMap<>();
for (TableRepairConfig table : tableRepairConfigs)
for (TableRepairConfig tableRepairConfig : tableRepairConfigs)
{
tableRepairConfig.validate("Schedule \"" + getKeyspaceName() + "\".\""
+ tableRepairConfig.getTableName() + "\"");
Set<TableRepairConfig> repairConfigs = tableConfigs.getOrDefault(
table.getTableName(), new HashSet<>());
repairConfigs.add(table);
tableConfigs.put(table.getTableName(), repairConfigs);
tableRepairConfig.getTableName(), new HashSet<>());
repairConfigs.add(tableRepairConfig);
tableConfigs.put(tableRepairConfig.getTableName(), repairConfigs);
}
myTableConfigs = tableConfigs;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,12 @@ public void testNoSchedule() throws Exception
@Test
public void testAllSchedules() throws Exception
{
AbstractRepairConfigurationProvider repairConfigProvider = withSchedule("regex_schedule.yml");
AbstractRepairConfigurationProvider repairConfigProvider = withSchedule("repair/regex_schedule.yml");

RepairConfiguration allKeyspacesPattern = RepairConfiguration.newBuilder()
.withRepairInterval(8, TimeUnit.DAYS)
.withRepairWarningTime(9, TimeUnit.DAYS)
.withRepairErrorTime(10, TimeUnit.DAYS)
.build();

RepairConfiguration allKeyspacesTb2 = RepairConfiguration.newBuilder()
Expand Down Expand Up @@ -97,7 +99,7 @@ public void testAllSchedules() throws Exception
@Test (expected = ConfigurationException.class)
public void testNullScheduleConfig() throws Exception
{
withSchedule("null_schedule.yml");
withSchedule("repair/null_schedule.yml");
}

private void assertConfig(AbstractRepairConfigurationProvider repairConfigProvider, String keyspace, String table,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import com.ericsson.bss.cassandra.ecchronos.application.config.metrics.StatisticsConfig;
import com.ericsson.bss.cassandra.ecchronos.application.config.repair.GlobalRepairConfig;
import com.ericsson.bss.cassandra.ecchronos.application.config.repair.RepairHistory;
import com.ericsson.bss.cassandra.ecchronos.application.config.repair.RepairSchedule;
import com.ericsson.bss.cassandra.ecchronos.application.config.rest.RestServerConfig;
import com.ericsson.bss.cassandra.ecchronos.application.config.runpolicy.RunPolicyConfig;
import com.ericsson.bss.cassandra.ecchronos.application.config.scheduler.SchedulerConfig;
Expand All @@ -50,6 +51,7 @@
import com.ericsson.bss.cassandra.ecchronos.core.utils.UnitConverter;
import com.ericsson.bss.cassandra.ecchronos.fm.RepairFaultReporter;
import com.ericsson.bss.cassandra.ecchronos.fm.impl.LoggingFaultReporter;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import io.micrometer.core.instrument.MeterRegistry;
Expand All @@ -67,6 +69,7 @@
import java.util.function.Supplier;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;

public class TestConfig
{
Expand Down Expand Up @@ -333,6 +336,28 @@ public void testDefault() throws Exception
assertThat(restServerConfig.getPort()).isEqualTo(8080);
}

@Test
public void testRepairIntervalLongerThanWarn()
{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
File file = new File(classLoader.getResource("repair_interval_longer_than_warn.yml").getFile());

ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());

assertThatExceptionOfType(JsonMappingException.class).isThrownBy(() -> objectMapper.readValue(file, Config.class));
}

@Test
public void testWarnIntervalLongerThanError()
{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
File file = new File(classLoader.getResource("warn_interval_longer_than_error.yml").getFile());

ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());

assertThatExceptionOfType(JsonMappingException.class).isThrownBy(() -> objectMapper.readValue(file, Config.class));
}

@Test
public void testStatisticsDisabledIfNoReporting() throws Exception
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@
package com.ericsson.bss.cassandra.ecchronos.application.config.repair;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;

import java.io.File;
import java.util.concurrent.TimeUnit;

import com.ericsson.bss.cassandra.ecchronos.application.config.repair.RepairSchedule;
import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairOptions;
import com.fasterxml.jackson.databind.JsonMappingException;
import org.junit.Test;

import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairConfiguration;
Expand All @@ -47,7 +48,7 @@ public void testDefault() throws Exception
public void testSettings() throws Exception
{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
File file = new File(classLoader.getResource("test_schedule.yml").getFile());
File file = new File(classLoader.getResource("repair/test_schedule.yml").getFile());

ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());

Expand Down Expand Up @@ -83,14 +84,16 @@ public void testSettings() throws Exception
public void testRegex() throws Exception
{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
File file = new File(classLoader.getResource("regex_schedule.yml").getFile());
File file = new File(classLoader.getResource("repair/regex_schedule.yml").getFile());

ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());

RepairSchedule schedule = objectMapper.readValue(file, RepairSchedule.class);

RepairConfiguration allKeyspacesPattern = RepairConfiguration.newBuilder()
.withRepairInterval(8, TimeUnit.DAYS)
.withRepairWarningTime(9, TimeUnit.DAYS)
.withRepairErrorTime(10, TimeUnit.DAYS)
.build();

RepairConfiguration allKeyspacesTb2 = RepairConfiguration.newBuilder()
Expand Down Expand Up @@ -121,14 +124,14 @@ public void testRegex() throws Exception
public void testMultipleSchedulesForSameTable() throws Exception
{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
File file = new File(classLoader.getResource("multiple_schedules.yml").getFile());
File file = new File(classLoader.getResource("repair/multiple_schedules.yml").getFile());

ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());

RepairSchedule schedule = objectMapper.readValue(file, RepairSchedule.class);

RepairConfiguration vnodeKs1tb1 = RepairConfiguration.newBuilder()
.withRepairInterval(44, TimeUnit.DAYS)
.withRepairInterval(6, TimeUnit.DAYS)
.withRepairType(RepairOptions.RepairType.VNODE)
.build();

Expand All @@ -144,14 +147,14 @@ public void testMultipleSchedulesForSameTable() throws Exception
public void testMultipleSchedulesForSameTableRegex() throws Exception
{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
File file = new File(classLoader.getResource("multiple_schedules_regex.yml").getFile());
File file = new File(classLoader.getResource("repair/multiple_schedules_regex.yml").getFile());

ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());

RepairSchedule schedule = objectMapper.readValue(file, RepairSchedule.class);

RepairConfiguration vnodeRegexTable = RepairConfiguration.newBuilder()
.withRepairInterval(44, TimeUnit.DAYS)
.withRepairInterval(6, TimeUnit.DAYS)
.withRepairType(RepairOptions.RepairType.VNODE)
.build();

Expand All @@ -163,4 +166,26 @@ public void testMultipleSchedulesForSameTableRegex() throws Exception
assertThat(schedule.getRepairConfigurations("ks1", "tb1")).containsExactlyInAnyOrder(vnodeRegexTable, incrementalRegexTable);
assertThat(schedule.getRepairConfigurations("ks1", "tb2")).containsExactlyInAnyOrder(vnodeRegexTable, incrementalRegexTable);
}

@Test
public void testRepairIntervalLongerThanWarn()
{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
File file = new File(classLoader.getResource("repair/schedule_repair_interval_longer_than_warn.yml").getFile());

ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());

assertThatExceptionOfType(JsonMappingException.class).isThrownBy(() -> objectMapper.readValue(file, RepairSchedule.class));
}

@Test
public void testWarnIntervalLongerThanError()
{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
File file = new File(classLoader.getResource("repair/schedule_warn_interval_longer_than_error.yml").getFile());

ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());

assertThatExceptionOfType(JsonMappingException.class).isThrownBy(() -> objectMapper.readValue(file, RepairSchedule.class));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ keyspaces:
tables:
- name: tb1
interval:
time: 44
time: 6
unit: days
- name: tb1
interval:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ keyspaces:
tables:
- name: ".*"
interval:
time: 44
time: 6
unit: days
- name: ".*"
interval:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ keyspaces:
interval:
time: 8
unit: days
alarm:
warn:
time: 9
unit: days
error:
time: 10
unit: days
- name: tb2
interval:
time: 5
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#
# Copyright 2023 Telefonaktiebolaget LM Ericsson
#
# Licensed 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.
#

keyspaces:
- name: ks1
tables:
- name: tb1
interval:
time: 200
unit: days
alarm:
warn:
time: 9
unit: days
error:
time: 11
unit: days
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#
# Copyright 2023 Telefonaktiebolaget LM Ericsson
#
# Licensed 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.
#

keyspaces:
- name: ks1
tables:
- name: tb1
interval:
time: 7
unit: days
alarm:
warn:
time: 200
unit: days
error:
time: 11
unit: days
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#
# Copyright 2023 Telefonaktiebolaget LM Ericsson
#
# Licensed 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.
#

repair:
interval:
time: 10
unit: days
alarm:
warn:
time: 2
unit: days
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#
# Copyright 2023 Telefonaktiebolaget LM Ericsson
#
# Licensed 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.
#

repair:
alarm:
warn:
time: 4
unit: days
error:
time: 3
unit: days