From 6f043207a2e3b9fd3d62d45678b6172def2c45d5 Mon Sep 17 00:00:00 2001 From: Johan Andersson W <96044147+jwaeab@users.noreply.github.com> Date: Tue, 24 Sep 2024 10:36:23 +0200 Subject: [PATCH 1/2] Removes OSGI/Karaf support Closes #657 --- .github/workflows/actions.yml | 6 - connection.impl/pom.xml | 7 +- .../impl/OSGiLocalJmxConnectionProvider.java | 68 --- .../OSGiLocalNativeConnectionProvider.java | 121 ----- core.osgi/pom.xml | 135 ------ .../core/osgi/CASLockFactoryService.java | 105 ----- ...tRepairConfigurationProviderComponent.java | 145 ------ .../core/osgi/HostStatesService.java | 76 ---- .../core/osgi/JmxProxyFactoryService.java | 52 --- .../core/osgi/NodeResolverService.java | 62 --- .../core/osgi/RepairHistoryService.java | 184 -------- .../core/osgi/RepairSchedulerService.java | 135 ------ .../core/osgi/RepairStateFactoryService.java | 72 --- .../osgi/ReplicatedTableProviderService.java | 66 --- .../core/osgi/ReplicationStateService.java | 83 ---- .../core/osgi/ScheduleManagerService.java | 134 ------ .../osgi/TableReferenceFactoryService.java | 72 --- .../core/osgi/TableRepairMetricsService.java | 107 ----- .../core/osgi/TableStorageStatesService.java | 90 ---- .../core/osgi/TimeBasedRunPolicyService.java | 88 ---- .../core/osgi/commands/PrintUtils.java | 78 ---- .../osgi/commands/RepairConfigCommand.java | 107 ----- .../osgi/commands/RepairStatusCommand.java | 200 --------- .../commands/RepairTableStatusCommand.java | 172 -------- .../commands/TableReferenceCompleter.java | 51 --- .../core/osgi/commands/package-info.java | 19 - .../ecchronos/core/osgi/package-info.java | 19 - .../core/osgi/commands/TestPrintUtils.java | 48 -- .../commands/TestRepairConfigCommand.java | 91 ---- .../commands/TestRepairStatusCommand.java | 223 ---------- .../TestRepairTableStatusCommand.java | 213 --------- docs/REPAIR_MONITORING.md | 14 - docs/TESTS.md | 16 +- karaf-feature/pom.xml | 176 -------- karaf-feature/src/main/feature/feature.xml | 30 -- osgi-integration/pom.xml | 251 ----------- .../ecchronos/osgi/ITTableRepairJob.java | 412 ------------------ .../ecchronos/osgi/ITTestECChronos.java | 250 ----------- .../cassandra/ecchronos/osgi/TestBase.java | 150 ------- .../src/test/resources/credentials.properties | 2 - pom.xml | 42 -- rest.osgi/pom.xml | 69 --- .../osgi/RepairManagementRESTComponent.java | 119 ----- .../ecchronos/rest/osgi/package-info.java | 19 - 44 files changed, 5 insertions(+), 4574 deletions(-) delete mode 100644 connection.impl/src/main/java/com/ericsson/bss/cassandra/ecchronos/connection/impl/OSGiLocalJmxConnectionProvider.java delete mode 100644 connection.impl/src/main/java/com/ericsson/bss/cassandra/ecchronos/connection/impl/OSGiLocalNativeConnectionProvider.java delete mode 100644 core.osgi/pom.xml delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/CASLockFactoryService.java delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/DefaultRepairConfigurationProviderComponent.java delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/HostStatesService.java delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/JmxProxyFactoryService.java delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/NodeResolverService.java delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/RepairHistoryService.java delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/RepairSchedulerService.java delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/RepairStateFactoryService.java delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/ReplicatedTableProviderService.java delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/ReplicationStateService.java delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/ScheduleManagerService.java delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/TableReferenceFactoryService.java delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/TableRepairMetricsService.java delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/TableStorageStatesService.java delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/TimeBasedRunPolicyService.java delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/PrintUtils.java delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/RepairConfigCommand.java delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/RepairStatusCommand.java delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/RepairTableStatusCommand.java delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/TableReferenceCompleter.java delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/package-info.java delete mode 100644 core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/package-info.java delete mode 100644 core.osgi/src/test/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/TestPrintUtils.java delete mode 100644 core.osgi/src/test/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/TestRepairConfigCommand.java delete mode 100644 core.osgi/src/test/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/TestRepairStatusCommand.java delete mode 100644 core.osgi/src/test/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/TestRepairTableStatusCommand.java delete mode 100644 karaf-feature/pom.xml delete mode 100644 karaf-feature/src/main/feature/feature.xml delete mode 100644 osgi-integration/pom.xml delete mode 100644 osgi-integration/src/test/java/com/ericsson/bss/cassandra/ecchronos/osgi/ITTableRepairJob.java delete mode 100644 osgi-integration/src/test/java/com/ericsson/bss/cassandra/ecchronos/osgi/ITTestECChronos.java delete mode 100644 osgi-integration/src/test/java/com/ericsson/bss/cassandra/ecchronos/osgi/TestBase.java delete mode 100644 osgi-integration/src/test/resources/credentials.properties delete mode 100644 rest.osgi/pom.xml delete mode 100644 rest.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/rest/osgi/RepairManagementRESTComponent.java delete mode 100644 rest.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/rest/osgi/package-info.java diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index d6193d26b..19deab2f9 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -29,10 +29,6 @@ jobs: test_suite: 'compile com.mycila:license-maven-plugin:check pmd:pmd pmd:cpd pmd:check pmd:cpd-check javadoc:jar' python: 3.6 java: 8 - - name: "OSGi integration" - test_suite: 'install -P docker-integration-test,osgi-integration-tests -Dit.cassandra.version=3.0 -DskipUTs' - python: 3.6 - java: 8 - name: "Standalone integration 3.0" test_suite: 'verify -P docker-integration-test,standalone-integration-tests -Dit.cassandra.version=3.0 -DskipUTs' python: 3.6 @@ -100,9 +96,7 @@ jobs: fail_ci_if_error: false files: > ./rest/target/site/jacoco/jacoco.xml, - ./core.osgi/target/site/jacoco/jacoco.xml, ./application/target/site/jacoco/jacoco.xml, - ./osgi-integration/target/site/jacoco/jacoco.xml, ./core/target/site/jacoco/jacoco.xml, ./fm.impl/target/site/jacoco/jacoco.xml, ./connection/target/site/jacoco/jacoco.xml diff --git a/connection.impl/pom.xml b/connection.impl/pom.xml index 0225540e0..6e55cd822 100644 --- a/connection.impl/pom.xml +++ b/connection.impl/pom.xml @@ -47,15 +47,10 @@ - - org.osgi - org.osgi.service.component.annotations - provided - org.osgi - org.osgi.service.metatype.annotations + org.osgi.service.component.annotations provided diff --git a/connection.impl/src/main/java/com/ericsson/bss/cassandra/ecchronos/connection/impl/OSGiLocalJmxConnectionProvider.java b/connection.impl/src/main/java/com/ericsson/bss/cassandra/ecchronos/connection/impl/OSGiLocalJmxConnectionProvider.java deleted file mode 100644 index c49ed4a23..000000000 --- a/connection.impl/src/main/java/com/ericsson/bss/cassandra/ecchronos/connection/impl/OSGiLocalJmxConnectionProvider.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2018 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. - */ -package com.ericsson.bss.cassandra.ecchronos.connection.impl; - -import java.io.IOException; - -import javax.management.remote.JMXConnector; - -import com.ericsson.bss.cassandra.ecchronos.connection.JmxConnectionProvider; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.ConfigurationPolicy; -import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.metatype.annotations.AttributeDefinition; -import org.osgi.service.metatype.annotations.Designate; -import org.osgi.service.metatype.annotations.ObjectClassDefinition; - -@Component(service = JmxConnectionProvider.class, configurationPolicy = ConfigurationPolicy.REQUIRE) -@Designate(ocd = OSGiLocalJmxConnectionProvider.Configuration.class) -public class OSGiLocalJmxConnectionProvider implements JmxConnectionProvider -{ - private volatile LocalJmxConnectionProvider myDelegateJmxConnectionProvider; - - @Activate - public final synchronized void activate(final Configuration configuration) throws IOException - { - String localhost = configuration.jmxHost(); - int port = configuration.jmxPort(); - - myDelegateJmxConnectionProvider = new LocalJmxConnectionProvider(localhost, port); - } - - @Deactivate - public final synchronized void deactivate() throws IOException - { - myDelegateJmxConnectionProvider.close(); - } - - @Override - public final JMXConnector getJmxConnector() throws IOException - { - return myDelegateJmxConnectionProvider.getJmxConnector(); - } - - @ObjectClassDefinition - public @interface Configuration - { - @AttributeDefinition(name = "Cassandra JMX Port", - description = "The port to use for JMX communication with Cassandra") - int jmxPort() default LocalJmxConnectionProvider.DEFAULT_PORT; - - @AttributeDefinition(name = "Cassandra JMX Host", - description = "The host to use for JMX communication with Cassandra") - String jmxHost() default LocalJmxConnectionProvider.DEFAULT_HOST; - } -} diff --git a/connection.impl/src/main/java/com/ericsson/bss/cassandra/ecchronos/connection/impl/OSGiLocalNativeConnectionProvider.java b/connection.impl/src/main/java/com/ericsson/bss/cassandra/ecchronos/connection/impl/OSGiLocalNativeConnectionProvider.java deleted file mode 100644 index e941fc3ad..000000000 --- a/connection.impl/src/main/java/com/ericsson/bss/cassandra/ecchronos/connection/impl/OSGiLocalNativeConnectionProvider.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2018 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. - */ -package com.ericsson.bss.cassandra.ecchronos.connection.impl; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.auth.ProgrammaticPlainTextAuthProvider; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.ericsson.bss.cassandra.ecchronos.connection.NativeConnectionProvider; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.ConfigurationPolicy; -import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.metatype.annotations.AttributeDefinition; -import org.osgi.service.metatype.annotations.ObjectClassDefinition; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; - -@Component(service = NativeConnectionProvider.class, configurationPolicy = ConfigurationPolicy.REQUIRE) -public class OSGiLocalNativeConnectionProvider implements NativeConnectionProvider -{ - private static final Logger LOG = LoggerFactory.getLogger(OSGiLocalNativeConnectionProvider.class); - - private static final String USERNAME_KEY = "username"; - private static final String PASSWORD_KEY = "password"; - private static final String DEFAULT_USERNAME = "cassandra"; - private static final String DEFAULT_PASSWORD = "cassandra"; - - private volatile LocalNativeConnectionProvider myDelegateNativeConnectionProvider; - - @Activate - public final synchronized void activate(final Configuration configuration) - { - String localhost = configuration.localHost(); - int port = configuration.nativePort(); - boolean remoteRouting = configuration.remoteRouting(); - - LocalNativeConnectionProvider.Builder builder = LocalNativeConnectionProvider.builder() - .withLocalhost(localhost) - .withPort(port) - .withRemoteRouting(remoteRouting); - - if (!configuration.credentialsFile().isEmpty()) - { - try (InputStream inputStream = new FileInputStream(configuration.credentialsFile())) - { - Properties properties = new Properties(); - properties.load(inputStream); - String username = properties.getProperty(USERNAME_KEY, DEFAULT_USERNAME); - String password = properties.getProperty(PASSWORD_KEY, DEFAULT_PASSWORD); - builder.withAuthProvider(new ProgrammaticPlainTextAuthProvider(username, password)); - } - catch (IOException e) - { - LOG.error("Unable to read provided credentials file {}, will not be using authentication", - configuration.credentialsFile()); - } - } - - myDelegateNativeConnectionProvider = builder.build(); - } - - @Deactivate - public final synchronized void deactivate() - { - myDelegateNativeConnectionProvider.close(); - } - - @Override - public final CqlSession getSession() - { - return myDelegateNativeConnectionProvider.getSession(); - } - - @Override - public final Node getLocalNode() - { - return myDelegateNativeConnectionProvider.getLocalNode(); - } - - @Override - public final boolean getRemoteRouting() - { - return myDelegateNativeConnectionProvider.getRemoteRouting(); - } - - @ObjectClassDefinition - public @interface Configuration - { - @AttributeDefinition(name = "Cassandra native port", - description = "The port to use for native communication with Cassandra") - int nativePort() default LocalNativeConnectionProvider.DEFAULT_NATIVE_PORT; - - @AttributeDefinition(name = "Cassandra host", - description = "The host to use for native communication with Cassandra") - String localHost() default LocalNativeConnectionProvider.DEFAULT_LOCAL_HOST; - - @AttributeDefinition(name = "Credentials file", - description = "A file containing credentials for communication with Cassandra") - String credentialsFile() default ""; - - @AttributeDefinition(name = "Remote routing", description = "Enables remote routing between datacenters") - boolean remoteRouting() default true; - } -} diff --git a/core.osgi/pom.xml b/core.osgi/pom.xml deleted file mode 100644 index c8afab059..000000000 --- a/core.osgi/pom.xml +++ /dev/null @@ -1,135 +0,0 @@ - - - - 4.0.0 - - parent - com.ericsson.bss.cassandra.ecchronos - 4.0.7-SNAPSHOT - - bundle - - core.osgi - OSGi service wrappers for the core classes - EcChronos Core OSGi - - - - - com.ericsson.bss.cassandra.ecchronos - connection - ${project.version} - - - - com.ericsson.bss.cassandra.ecchronos - fm - ${project.version} - - - - com.ericsson.bss.cassandra.ecchronos - core - ${project.version} - - - - - org.slf4j - slf4j-api - - - - - com.google.guava - guava - - - - - com.datastax.oss - java-driver-core - - - - - org.osgi - org.osgi.service.component.annotations - provided - - - - org.osgi - org.osgi.service.metatype.annotations - provided - - - - org.apache.karaf.shell - org.apache.karaf.shell.core - - - - - org.junit.vintage - junit-vintage-engine - test - - - - org.mockito - mockito-core - test - - - - org.assertj - assertj-core - test - - - - pl.pragmatists - JUnitParams - test - - - - - - - org.apache.felix - maven-bundle-plugin - - true - META-INF - - - - com.ericsson.bss.cassandra.ecchronos.core.osgi.* - com.ericsson.bss.cassandra.ecchronos.core.osgi.commands - - - - - - diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/CASLockFactoryService.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/CASLockFactoryService.java deleted file mode 100644 index 0655e5ff6..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/CASLockFactoryService.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2018 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi; - -import com.ericsson.bss.cassandra.ecchronos.core.CASLockFactory; -import com.ericsson.bss.cassandra.ecchronos.core.HostStates; -import com.ericsson.bss.cassandra.ecchronos.core.exceptions.LockException; - -import com.ericsson.bss.cassandra.ecchronos.connection.NativeConnectionProvider; -import com.ericsson.bss.cassandra.ecchronos.connection.StatementDecorator; -import com.ericsson.bss.cassandra.ecchronos.core.scheduling.LockFactory; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; -import org.osgi.service.metatype.annotations.AttributeDefinition; -import org.osgi.service.metatype.annotations.Designate; -import org.osgi.service.metatype.annotations.ObjectClassDefinition; - -import java.util.Map; - -@Component(service = LockFactory.class) -@Designate(ocd = CASLockFactoryService.Configuration.class) -public class CASLockFactoryService implements LockFactory -{ - private static final String DEFAULT_KEYSPACE_NAME = "ecchronos"; - - @Reference(service = NativeConnectionProvider.class, - cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile NativeConnectionProvider myNativeConnectionProvider; - - @Reference (service = StatementDecorator.class, - cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile StatementDecorator myStatementDecorator; - - @Reference (service = HostStates.class, - cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile HostStates myHostStates; - - private volatile CASLockFactory myDelegateLockFactory; - - @Activate - public final synchronized void activate(final Configuration configuration) - { - myDelegateLockFactory = CASLockFactory.builder() - .withNativeConnectionProvider(myNativeConnectionProvider) - .withHostStates(myHostStates) - .withStatementDecorator(myStatementDecorator) - .withKeyspaceName(configuration.keyspaceName()) - .build(); - } - - @Deactivate - public final synchronized void deactivate() - { - myDelegateLockFactory.close(); - } - - @Override - public final DistributedLock tryLock(final String dataCenter, - final String resource, - final int priority, - final Map metadata) - throws LockException - { - return myDelegateLockFactory.tryLock(dataCenter, resource, priority, metadata); - } - - @Override - public final Map getLockMetadata(final String dataCenter, final String resource) - { - return myDelegateLockFactory.getLockMetadata(dataCenter, resource); - } - - @Override - public final boolean sufficientNodesForLocking(final String dataCenter, final String resource) - { - return myDelegateLockFactory.sufficientNodesForLocking(dataCenter, resource); - } - - @ObjectClassDefinition - public @interface Configuration - { - @AttributeDefinition(name = "The lock factory keyspace to use", - description = "The name of the keyspace containing the lock factory tables") - String keyspaceName() default DEFAULT_KEYSPACE_NAME; - } -} diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/DefaultRepairConfigurationProviderComponent.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/DefaultRepairConfigurationProviderComponent.java deleted file mode 100644 index b4e48a99e..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/DefaultRepairConfigurationProviderComponent.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2018 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi; - -import java.util.concurrent.TimeUnit; - -import com.ericsson.bss.cassandra.ecchronos.core.repair.DefaultRepairConfigurationProvider; -import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairConfiguration; -import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairOptions; -import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairScheduler; -import com.ericsson.bss.cassandra.ecchronos.core.utils.TableReferenceFactory; -import com.ericsson.bss.cassandra.ecchronos.core.utils.UnitConverter; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; -import org.osgi.service.metatype.annotations.AttributeDefinition; -import org.osgi.service.metatype.annotations.Designate; -import org.osgi.service.metatype.annotations.ObjectClassDefinition; - -import com.ericsson.bss.cassandra.ecchronos.connection.NativeConnectionProvider; -import com.ericsson.bss.cassandra.ecchronos.core.utils.ReplicatedTableProvider; - -/** - * OSGi component wrapping {@link DefaultRepairConfigurationProvider} bound with OSGi services. - */ -@Component -@Designate(ocd = DefaultRepairConfigurationProviderComponent.Configuration.class) -public class DefaultRepairConfigurationProviderComponent -{ - private static final long DEFAULT_REPAIR_INTERVAL_SECONDS = 7L * 24L * 60L * 60L; - private static final long DEFAULT_REPAIR_WARNING_SECONDS = 8L * 24L * 60L * 60L; - private static final long DEFAULT_REPAIR_ERROR_SECONDS = 10L * 24L * 60L * 60L; - private static final long DEFAULT_TARGET_REPAIR_SIZE_IN_BYTES = RepairConfiguration.FULL_REPAIR_SIZE; - - @Reference (service = NativeConnectionProvider.class, - cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile NativeConnectionProvider myNativeConnectionProvider; - - @Reference (service = ReplicatedTableProvider.class, - cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile ReplicatedTableProvider myReplicatedTableProvider; - - @Reference (service = RepairScheduler.class, - cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile RepairScheduler myRepairScheduler; - - @Reference(service = TableReferenceFactory.class, - cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile TableReferenceFactory myTableReferenceFactory; - - private volatile DefaultRepairConfigurationProvider myDelegateRepairConfigurationProvider; - - @Activate - public final synchronized void activate(final Configuration configuration) - { - if (configuration.enabled()) - { - long repairInterval = configuration.repairIntervalSeconds(); - long repairSizeInBytes = DEFAULT_TARGET_REPAIR_SIZE_IN_BYTES; - if (!configuration.targetRepairSize().isEmpty()) - { - repairSizeInBytes = UnitConverter.toBytes(configuration.targetRepairSize()); - } - - RepairConfiguration repairConfiguration = RepairConfiguration.newBuilder() - .withParallelism(configuration.repairParallelism()) - .withRepairInterval(repairInterval, TimeUnit.SECONDS) - .withRepairWarningTime(configuration.repairWarningSeconds(), TimeUnit.SECONDS) - .withRepairErrorTime(configuration.repairErrorSeconds(), TimeUnit.SECONDS) - .withRepairUnwindRatio(configuration.repairUnwindRatio()) - .withTargetRepairSizeInBytes(repairSizeInBytes) - .build(); - - myDelegateRepairConfigurationProvider = DefaultRepairConfigurationProvider.newBuilder() - .withReplicatedTableProvider(myReplicatedTableProvider) - .withRepairScheduler(myRepairScheduler) - .withSession(myNativeConnectionProvider.getSession()) - .withDefaultRepairConfiguration(repairConfiguration) - .withTableReferenceFactory(myTableReferenceFactory) - .build(); - } - } - - @Deactivate - public final synchronized void deactivate() - { - if (myDelegateRepairConfigurationProvider != null) - { - myDelegateRepairConfigurationProvider.close(); - } - } - - @ObjectClassDefinition - public @interface Configuration - { - @AttributeDefinition (name = "Enable or disable", - description = "If the default repair configuration provider should be enabled or disabled") - boolean enabled() default true; - - @AttributeDefinition (name = "Repair interval in seconds", - description = "The wanted interval between successful repairs in seconds") - long repairIntervalSeconds() default DEFAULT_REPAIR_INTERVAL_SECONDS; - - @AttributeDefinition (name = "Repair warning time", - description = "After a table has not been repaired for the specified") - long repairWarningSeconds() default DEFAULT_REPAIR_WARNING_SECONDS; - - @AttributeDefinition (name = "Repair error time", - description = "The wanted interval between successful repairs in seconds") - long repairErrorSeconds() default DEFAULT_REPAIR_ERROR_SECONDS; - - @AttributeDefinition (name = "Repair paralleism", - description = "The repair parallelism to use") - RepairOptions.RepairParallelism repairParallelism() default RepairOptions.RepairParallelism.PARALLEL; - - @AttributeDefinition (name = "Repair unwind ratio", - description = "The ratio of time to wait before starting the next repair. The amount of time " - + "to wait is based on the time it took to perform the repair. A value of 1.0 gives " - + "100% of the repair time as wait time.") - double repairUnwindRatio() default RepairConfiguration.NO_UNWIND; - - @AttributeDefinition (name = "Target repair size", - description = "An indication of how much data a repair session should handle.") - String targetRepairSize() default ""; - } -} diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/HostStatesService.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/HostStatesService.java deleted file mode 100644 index 8b709affc..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/HostStatesService.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2018 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi; - -import com.datastax.oss.driver.api.core.metadata.Node; -import com.ericsson.bss.cassandra.ecchronos.core.HostStates; -import com.ericsson.bss.cassandra.ecchronos.core.HostStatesImpl; -import com.ericsson.bss.cassandra.ecchronos.core.JmxProxyFactory; -import com.ericsson.bss.cassandra.ecchronos.core.utils.DriverNode; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; - -import java.net.InetAddress; - -/** - * Implementation of the {@link HostStates} interface using JMX to retrieve node statuses and then caches the retrieved - * statuses for some time. - */ -@Component(service = HostStates.class) -public class HostStatesService implements HostStates -{ - @Reference(service = JmxProxyFactory.class, - cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile JmxProxyFactory myJmxProxyFactory; - - private volatile HostStatesImpl myDelegateHostStates; - - @Activate - public final void activate() - { - myDelegateHostStates = HostStatesImpl.builder() - .withJmxProxyFactory(myJmxProxyFactory) - .build(); - } - - @Deactivate - public final void deactivate() - { - myDelegateHostStates.close(); - } - - @Override - public final boolean isUp(final InetAddress address) - { - return myDelegateHostStates.isUp(address); - } - - @Override - public final boolean isUp(final Node node) - { - return myDelegateHostStates.isUp(node); - } - - @Override - public final boolean isUp(final DriverNode node) - { - return myDelegateHostStates.isUp(node); - } -} diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/JmxProxyFactoryService.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/JmxProxyFactoryService.java deleted file mode 100644 index 8bd40711a..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/JmxProxyFactoryService.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2018 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi; - -import com.ericsson.bss.cassandra.ecchronos.connection.JmxConnectionProvider; -import com.ericsson.bss.cassandra.ecchronos.core.JmxProxy; -import com.ericsson.bss.cassandra.ecchronos.core.JmxProxyFactory; -import com.ericsson.bss.cassandra.ecchronos.core.JmxProxyFactoryImpl; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; - -import java.io.IOException; - -@Component(service = JmxProxyFactory.class) -public class JmxProxyFactoryService implements JmxProxyFactory -{ - @Reference(service = JmxConnectionProvider.class, - cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile JmxConnectionProvider myJmxConnectionProvider; - - private volatile JmxProxyFactoryImpl myDelegateJmxProxyFactory; - - @Activate - public final void activate() - { - myDelegateJmxProxyFactory = JmxProxyFactoryImpl.builder() - .withJmxConnectionProvider(myJmxConnectionProvider) - .build(); - } - - @Override - public final JmxProxy connect() throws IOException - { - return myDelegateJmxProxyFactory.connect(); - } -} diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/NodeResolverService.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/NodeResolverService.java deleted file mode 100644 index 2b2c576ba..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/NodeResolverService.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2020 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi; - -import java.net.InetAddress; -import java.util.Optional; -import java.util.UUID; - -import com.datastax.oss.driver.api.core.CqlSession; - -import com.ericsson.bss.cassandra.ecchronos.connection.NativeConnectionProvider; -import com.ericsson.bss.cassandra.ecchronos.core.utils.DriverNode; -import com.ericsson.bss.cassandra.ecchronos.core.utils.NodeResolver; -import com.ericsson.bss.cassandra.ecchronos.core.utils.NodeResolverImpl; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; - -@Component(service = NodeResolver.class) -public class NodeResolverService implements NodeResolver -{ - @Reference(service = NativeConnectionProvider.class, - cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile NativeConnectionProvider myNativeConnectionProvider; - - private volatile NodeResolver delegateNodeResolver; - - @Activate - public final void activate() - { - CqlSession session = myNativeConnectionProvider.getSession(); - - delegateNodeResolver = new NodeResolverImpl(session); - } - - @Override - public final Optional fromIp(final InetAddress inetAddress) - { - return delegateNodeResolver.fromIp(inetAddress); - } - - @Override - public final Optional fromUUID(final UUID nodeId) - { - return delegateNodeResolver.fromUUID(nodeId); - } -} diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/RepairHistoryService.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/RepairHistoryService.java deleted file mode 100644 index e6ccc8f4c..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/RepairHistoryService.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright 2020 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.ericsson.bss.cassandra.ecchronos.connection.NativeConnectionProvider; -import com.ericsson.bss.cassandra.ecchronos.connection.StatementDecorator; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.EccRepairHistory; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.RepairEntry; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.RepairHistory; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.RepairHistoryProvider; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.RepairHistoryProviderImpl; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.ReplicationState; -import com.ericsson.bss.cassandra.ecchronos.core.utils.LongTokenRange; -import com.ericsson.bss.cassandra.ecchronos.core.utils.DriverNode; -import com.ericsson.bss.cassandra.ecchronos.core.utils.NodeResolver; -import com.ericsson.bss.cassandra.ecchronos.core.utils.TableReference; -import com.google.common.base.Predicate; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; -import org.osgi.service.metatype.annotations.AttributeDefinition; -import org.osgi.service.metatype.annotations.Designate; -import org.osgi.service.metatype.annotations.ObjectClassDefinition; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Iterator; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.TimeUnit; - -@Component(service = { RepairHistory.class, RepairHistoryProvider.class }) -@Designate(ocd = RepairHistoryService.Configuration.class) -public class RepairHistoryService implements RepairHistory, RepairHistoryProvider -{ - private static final int ONE_SECOND_MILLIS = 1000; - private static final Logger LOG = LoggerFactory.getLogger(RepairHistoryService.class); - - private static final String DEFAULT_PROVIDER_KEYSPACE = "ecchronos"; - - private static final long DEFAULT_REPAIR_HISTORY_LOOKBACK_SECONDS = 30L * 24L * 60L * 60L; - - public enum Provider - { - CASSANDRA, - UPGRADE, - ECC - } - - @Reference(service = StatementDecorator.class, cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile StatementDecorator statementDecorator; - - @Reference(service = NativeConnectionProvider.class, cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile NativeConnectionProvider nativeConnectionProvider; - - @Reference(service = NodeResolver.class, cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile NodeResolver nodeResolver; - - @Reference(service = ReplicationState.class, cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile ReplicationState replicationState; - - private volatile RepairHistory delegateRepairHistory; - - private volatile RepairHistoryProvider delegateRepairHistoryProvider; - - @Activate - public final void activate(final Configuration configuration) - { - Node node = nativeConnectionProvider.getLocalNode(); - Optional localNode = nodeResolver.fromUUID(node.getHostId()); - if (!localNode.isPresent()) - { - LOG.error("Local node ({}) not found in resolver", node.getHostId()); - throw new IllegalStateException("Local node (" + node.getHostId() + ") not found in resolver"); - } - - long lookbackTimeInMillis = configuration.lookbackTimeSeconds() * ONE_SECOND_MILLIS; - - CqlSession session = nativeConnectionProvider.getSession(); - - if (configuration.provider() == Provider.CASSANDRA) - { - delegateRepairHistoryProvider = new RepairHistoryProviderImpl(nodeResolver, - session, statementDecorator, - lookbackTimeInMillis); - delegateRepairHistory = RepairHistory.NO_OP; - } - else - { - EccRepairHistory eccRepairHistory = EccRepairHistory.newBuilder() - .withLocalNode(localNode.get()) - .withReplicationState(replicationState) - .withSession(nativeConnectionProvider.getSession()) - .withStatementDecorator(statementDecorator) - .withLookbackTime(lookbackTimeInMillis, TimeUnit.MILLISECONDS) - .build(); - - if (configuration.provider() == Provider.UPGRADE) - { - delegateRepairHistoryProvider = new RepairHistoryProviderImpl(nodeResolver, session, statementDecorator, - lookbackTimeInMillis); - } - else - { - delegateRepairHistoryProvider = eccRepairHistory; - } - - delegateRepairHistory = eccRepairHistory; - } - } - - @Override - public final RepairSession newSession(final TableReference tableReference, - final UUID jobId, - final LongTokenRange range, - final Set participants) - { - return delegateRepairHistory.newSession(tableReference, jobId, range, participants); - } - - @Override - public final Iterator iterate(final TableReference tableReference, - final long to, - final Predicate predicate) - { - return delegateRepairHistoryProvider.iterate(tableReference, to, predicate); - } - - @Override - public final Iterator iterate(final TableReference tableReference, - final long to, - final long from, - final Predicate predicate) - { - return delegateRepairHistoryProvider.iterate(tableReference, to, from, predicate); - } - - @Override - public final Iterator iterate(final UUID nodeId, - final TableReference tableReference, - final long to, - final long from, - final Predicate predicate) - { - return delegateRepairHistoryProvider.iterate(nodeId, tableReference, to, from, predicate); - } - - @ObjectClassDefinition - public @interface Configuration - { - @AttributeDefinition(name = "The provider to use for repair history", - description = "The provider to use for repair history") - Provider provider() default Provider.ECC; - - @AttributeDefinition(name = "Provider keyspace", description = "The keyspace used for ecc history if enabled") - String providerKeyspace() default DEFAULT_PROVIDER_KEYSPACE; - - @AttributeDefinition(name = "Repair history lookback time", - description = "The lookback time in seconds for when the repair_history table is queried to get " - + "initial repair state at startup") - long lookbackTimeSeconds() default DEFAULT_REPAIR_HISTORY_LOOKBACK_SECONDS; - } -} diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/RepairSchedulerService.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/RepairSchedulerService.java deleted file mode 100644 index 991e3173b..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/RepairSchedulerService.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2018 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi; - -import java.util.List; - -import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairConfiguration; -import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairLockType; -import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairScheduler; -import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairSchedulerImpl; -import com.ericsson.bss.cassandra.ecchronos.core.repair.ScheduledRepairJobView; -import com.ericsson.bss.cassandra.ecchronos.core.repair.TableRepairPolicy; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; -import org.osgi.service.metatype.annotations.AttributeDefinition; -import org.osgi.service.metatype.annotations.Designate; -import org.osgi.service.metatype.annotations.ObjectClassDefinition; - -import com.ericsson.bss.cassandra.ecchronos.core.JmxProxyFactory; -import com.ericsson.bss.cassandra.ecchronos.core.TableStorageStates; -import com.ericsson.bss.cassandra.ecchronos.core.metrics.TableRepairMetrics; - -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.RepairHistory; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.RepairStateFactory; -import com.ericsson.bss.cassandra.ecchronos.core.scheduling.ScheduleManager; -import com.ericsson.bss.cassandra.ecchronos.core.utils.TableReference; -import com.ericsson.bss.cassandra.ecchronos.fm.RepairFaultReporter; - -/** - * A factory creating TableRepairJob's for tables that replicates data over multiple nodes. - *

- * This factory will schedule new jobs automatically when new tables are added. - */ -@Component(service = RepairScheduler.class) -@Designate(ocd = RepairSchedulerService.Configuration.class) -public class RepairSchedulerService implements RepairScheduler -{ - @Reference(service = RepairFaultReporter.class, - cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.STATIC) - private volatile RepairFaultReporter myFaultReporter; - - @Reference(service = JmxProxyFactory.class, - cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.STATIC) - private volatile JmxProxyFactory myJmxProxyFactory; - - @Reference(service = TableRepairMetrics.class, - cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.STATIC) - private volatile TableRepairMetrics myTableRepairMetrics; - - @Reference(service = ScheduleManager.class, - cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.STATIC) - private volatile ScheduleManager myScheduleManager; - - @Reference(service = RepairStateFactory.class, - cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.STATIC) - private volatile RepairStateFactory myRepairStateFactory; - - @Reference(service = TableStorageStates.class, - cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.STATIC) - private volatile TableStorageStates myTableStorageStates; - - @Reference(service = TableRepairPolicy.class, - cardinality = ReferenceCardinality.AT_LEAST_ONE, policy = ReferencePolicy.STATIC) - private volatile List myRepairPolicies; - - @Reference(service = RepairHistory.class, - cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.STATIC) - private volatile RepairHistory myRepairHistory; - - private volatile RepairSchedulerImpl myDelegateRepairSchedulerImpl; - - @Activate - public final synchronized void activate(final Configuration configuration) - { - myDelegateRepairSchedulerImpl = RepairSchedulerImpl.builder() - .withFaultReporter(myFaultReporter) - .withJmxProxyFactory(myJmxProxyFactory) - .withTableRepairMetrics(myTableRepairMetrics) - .withScheduleManager(myScheduleManager) - .withRepairStateFactory(myRepairStateFactory) - .withRepairLockType(configuration.repairLockType()) - .withTableStorageStates(myTableStorageStates) - .withRepairPolicies(myRepairPolicies) - .withRepairHistory(myRepairHistory) - .build(); - } - - @Deactivate - public final synchronized void deactivate() - { - myDelegateRepairSchedulerImpl.close(); - } - - @Override - public final void putConfiguration(final TableReference tableReference, - final RepairConfiguration repairConfiguration) - { - myDelegateRepairSchedulerImpl.putConfiguration(tableReference, repairConfiguration); - } - - @Override - public final void removeConfiguration(final TableReference tableReference) - { - myDelegateRepairSchedulerImpl.removeConfiguration(tableReference); - } - - @Override - public final List getCurrentRepairJobs() - { - return myDelegateRepairSchedulerImpl.getCurrentRepairJobs(); - } - - @ObjectClassDefinition - public @interface Configuration - { - @AttributeDefinition(name = "Type of repair lock", description = "The type of locks to take for repair jobs") - RepairLockType repairLockType() default RepairLockType.VNODE; - } -} diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/RepairStateFactoryService.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/RepairStateFactoryService.java deleted file mode 100644 index 1c3816bd6..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/RepairStateFactoryService.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2018 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi; - -import com.ericsson.bss.cassandra.ecchronos.core.HostStates; -import com.ericsson.bss.cassandra.ecchronos.core.metrics.TableRepairMetrics; -import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairConfiguration; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.PostUpdateHook; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.RepairHistoryProvider; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.RepairState; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.RepairStateFactory; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.RepairStateFactoryImpl; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.ReplicationState; -import com.ericsson.bss.cassandra.ecchronos.core.utils.TableReference; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; - -@Component(service = RepairStateFactory.class) -public class RepairStateFactoryService implements RepairStateFactory -{ - @Reference(service = HostStates.class, - cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.STATIC) - private volatile HostStates myHostStates; - - @Reference(service = TableRepairMetrics.class, - cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.STATIC) - private volatile TableRepairMetrics myTableRepairMetrics; - - @Reference(service = RepairHistoryProvider.class, - cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.STATIC) - private volatile RepairHistoryProvider myRepairHistoryProvider; - - @Reference(service = ReplicationState.class, - cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.STATIC) - private volatile ReplicationState myReplicationState; - - private volatile RepairStateFactoryImpl myDelegateRepairStateFactory; - - @Activate - public final void activate() - { - myDelegateRepairStateFactory = RepairStateFactoryImpl.builder() - .withReplicationState(myReplicationState) - .withHostStates(myHostStates) - .withRepairHistoryProvider(myRepairHistoryProvider) - .withTableRepairMetrics(myTableRepairMetrics) - .build(); - } - - @Override - public final RepairState create(final TableReference tableReference, - final RepairConfiguration repairConfiguration, - final PostUpdateHook postUpdateHook) - { - return myDelegateRepairStateFactory.create(tableReference, repairConfiguration, postUpdateHook); - } -} diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/ReplicatedTableProviderService.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/ReplicatedTableProviderService.java deleted file mode 100644 index 5b541d35a..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/ReplicatedTableProviderService.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2018 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.ericsson.bss.cassandra.ecchronos.connection.NativeConnectionProvider; -import com.ericsson.bss.cassandra.ecchronos.core.utils.ReplicatedTableProvider; -import com.ericsson.bss.cassandra.ecchronos.core.utils.ReplicatedTableProviderImpl; -import com.ericsson.bss.cassandra.ecchronos.core.utils.TableReference; -import com.ericsson.bss.cassandra.ecchronos.core.utils.TableReferenceFactory; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; - -import java.util.Set; - -@Component(service = ReplicatedTableProvider.class) -public class ReplicatedTableProviderService implements ReplicatedTableProvider -{ - private volatile ReplicatedTableProvider myDelegateReplicatedTableProvider; - - @Reference(service = NativeConnectionProvider.class, cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile NativeConnectionProvider myNativeConnectionProvider; - - @Reference(service = TableReferenceFactory.class, cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile TableReferenceFactory myTableReferenceFactory; - - @Activate - public final void activate() - { - CqlSession session = myNativeConnectionProvider.getSession(); - Node localhost = myNativeConnectionProvider.getLocalNode(); - - myDelegateReplicatedTableProvider = new ReplicatedTableProviderImpl(localhost, session, - myTableReferenceFactory); - } - - @Override - public final Set getAll() - { - return myDelegateReplicatedTableProvider.getAll(); - } - - @Override - public final boolean accept(final String keyspace) - { - return myDelegateReplicatedTableProvider.accept(keyspace); - } -} diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/ReplicationStateService.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/ReplicationStateService.java deleted file mode 100644 index 8615f4862..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/ReplicationStateService.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2020 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.ericsson.bss.cassandra.ecchronos.connection.NativeConnectionProvider; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.ReplicationState; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.ReplicationStateImpl; -import com.ericsson.bss.cassandra.ecchronos.core.utils.LongTokenRange; -import com.ericsson.bss.cassandra.ecchronos.core.utils.DriverNode; -import com.ericsson.bss.cassandra.ecchronos.core.utils.NodeResolver; -import com.ericsson.bss.cassandra.ecchronos.core.utils.TableReference; -import com.google.common.collect.ImmutableSet; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; - -import java.util.Map; - -@Component(service = ReplicationState.class) -public class ReplicationStateService implements ReplicationState -{ - @Reference(service = NativeConnectionProvider.class, cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile NativeConnectionProvider nativeConnectionProvider; - - @Reference(service = NodeResolver.class, cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile NodeResolver nodeResolver; - - private volatile ReplicationState delegateReplicationState; - - @Activate - public final void activate() - { - CqlSession session = nativeConnectionProvider.getSession(); - Node localNode = nativeConnectionProvider.getLocalNode(); - - delegateReplicationState = new ReplicationStateImpl(nodeResolver, session, localNode); - } - - @Override - public final ImmutableSet getNodes(final TableReference tableReference, - final LongTokenRange tokenRange) - { - return delegateReplicationState.getNodes(tableReference, tokenRange); - } - - @Override - public final ImmutableSet getNodesClusterWide(final TableReference tableReference, - final LongTokenRange tokenRange) - { - return delegateReplicationState.getNodesClusterWide(tableReference, tokenRange); - } - - @Override - public final Map> getTokenRangeToReplicas( - final TableReference tableReference) - { - return delegateReplicationState.getTokenRangeToReplicas(tableReference); - } - - @Override - public final Map> getTokenRanges(final TableReference tableReference) - { - return delegateReplicationState.getTokenRanges(tableReference); - } -} diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/ScheduleManagerService.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/ScheduleManagerService.java deleted file mode 100644 index fef48ef72..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/ScheduleManagerService.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2018 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi; - -import java.util.Set; -import java.util.concurrent.TimeUnit; - -import com.ericsson.bss.cassandra.ecchronos.core.scheduling.LockFactory; -import com.ericsson.bss.cassandra.ecchronos.core.scheduling.RunPolicy; -import com.ericsson.bss.cassandra.ecchronos.core.scheduling.ScheduleManager; -import com.ericsson.bss.cassandra.ecchronos.core.scheduling.ScheduleManagerImpl; -import com.ericsson.bss.cassandra.ecchronos.core.scheduling.ScheduledJob; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; -import org.osgi.service.metatype.annotations.AttributeDefinition; -import org.osgi.service.metatype.annotations.Designate; -import org.osgi.service.metatype.annotations.ObjectClassDefinition; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.collect.Sets; - -@Component(service = ScheduleManager.class) -@Designate(ocd = ScheduleManagerService.Configuration.class) -public class ScheduleManagerService implements ScheduleManager -{ - private static final Logger LOG = LoggerFactory.getLogger(ScheduleManagerService.class); - - private static final long DEFAULT_SCHEDULE_INTERVAL_IN_SECONDS = 60L; - - @Reference(service = RunPolicy.class, - cardinality = ReferenceCardinality.MULTIPLE, - policy = ReferencePolicy.DYNAMIC, - bind = "bindRunPolicy", - unbind = "unbindRunPolicy") - private final Set myRunPolicies = Sets.newConcurrentHashSet(); - - @Reference (service = LockFactory.class, - cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile LockFactory myLockFactory; - - private volatile ScheduleManagerImpl myDelegateSchedulerManager; - - @Activate - public final synchronized void activate(final Configuration configuration) - { - long scheduleIntervalInSeconds = configuration.scheduleIntervalInSeconds(); - - myDelegateSchedulerManager = ScheduleManagerImpl.builder() - .withLockFactory(myLockFactory) - .withRunInterval(scheduleIntervalInSeconds, TimeUnit.SECONDS) - .build(); - - for (RunPolicy runPolicy : myRunPolicies) - { - myDelegateSchedulerManager.addRunPolicy(runPolicy); - } - } - - @Deactivate - public final synchronized void deactivate() - { - myDelegateSchedulerManager.close(); - } - - @Override - public final void schedule(final ScheduledJob job) - { - myDelegateSchedulerManager.schedule(job); - } - - @Override - public final void deschedule(final ScheduledJob job) - { - myDelegateSchedulerManager.deschedule(job); - } - - public final synchronized void bindRunPolicy(final RunPolicy runPolicy) - { - if (myRunPolicies.add(runPolicy)) - { - LOG.trace("Run policy {} added", runPolicy); - if (myDelegateSchedulerManager != null) - { - myDelegateSchedulerManager.addRunPolicy(runPolicy); - } - } - else - { - LOG.warn("Run policy {} already added", runPolicy); - } - } - - public final synchronized void unbindRunPolicy(final RunPolicy runPolicy) - { - if (myRunPolicies.remove(runPolicy)) - { - LOG.trace("Run policy {} removed", runPolicy); - if (myDelegateSchedulerManager != null) - { - myDelegateSchedulerManager.removeRunPolicy(runPolicy); - } - } - else - { - LOG.warn("Run policy {} already removed", runPolicy); - } - } - - @ObjectClassDefinition - public @interface Configuration - { - @AttributeDefinition(name = "Schedule interval in seconds", - description = "The interval in which jobs will be scheduled to run") - long scheduleIntervalInSeconds() default DEFAULT_SCHEDULE_INTERVAL_IN_SECONDS; - } -} diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/TableReferenceFactoryService.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/TableReferenceFactoryService.java deleted file mode 100644 index 2bc9421d2..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/TableReferenceFactoryService.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2020 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.metadata.schema.TableMetadata; -import com.ericsson.bss.cassandra.ecchronos.connection.NativeConnectionProvider; -import com.ericsson.bss.cassandra.ecchronos.core.exceptions.EcChronosException; -import com.ericsson.bss.cassandra.ecchronos.core.utils.TableReference; -import com.ericsson.bss.cassandra.ecchronos.core.utils.TableReferenceFactory; -import com.ericsson.bss.cassandra.ecchronos.core.utils.TableReferenceFactoryImpl; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; - -import java.util.Set; - -@Component(service = TableReferenceFactory.class) -public class TableReferenceFactoryService implements TableReferenceFactory -{ - @Reference(service = NativeConnectionProvider.class, cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile NativeConnectionProvider nativeConnectionProvider; - - private volatile TableReferenceFactory delegateTableReferenceFactory; - - @Activate - public final void activate() - { - CqlSession session = nativeConnectionProvider.getSession(); - - delegateTableReferenceFactory = new TableReferenceFactoryImpl(session); - } - - @Override - public final TableReference forTable(final String keyspace, final String table) - { - return delegateTableReferenceFactory.forTable(keyspace, table); - } - - @Override - public final TableReference forTable(final TableMetadata table) - { - return delegateTableReferenceFactory.forTable(table); - } - - @Override - public final Set forKeyspace(final String keyspace) throws EcChronosException - { - return delegateTableReferenceFactory.forKeyspace(keyspace); - } - - @Override - public final Set forCluster() - { - return delegateTableReferenceFactory.forCluster(); - } -} diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/TableRepairMetricsService.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/TableRepairMetricsService.java deleted file mode 100644 index 8defefb7b..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/TableRepairMetricsService.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2018 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi; - -import java.util.Optional; -import java.util.concurrent.TimeUnit; - -import com.ericsson.bss.cassandra.ecchronos.core.TableStorageStates; -import com.ericsson.bss.cassandra.ecchronos.core.metrics.TableRepairMetrics; -import com.ericsson.bss.cassandra.ecchronos.core.metrics.TableRepairMetricsImpl; -import com.ericsson.bss.cassandra.ecchronos.core.metrics.TableRepairMetricsProvider; -import com.ericsson.bss.cassandra.ecchronos.core.utils.TableReference; -import io.micrometer.core.instrument.Metrics; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; -import org.osgi.service.metatype.annotations.AttributeDefinition; -import org.osgi.service.metatype.annotations.Designate; -import org.osgi.service.metatype.annotations.ObjectClassDefinition; - -@Component(service = {TableRepairMetrics.class, TableRepairMetricsProvider.class}) -@Designate(ocd = TableRepairMetricsService.Configuration.class) -public final class TableRepairMetricsService implements TableRepairMetrics, TableRepairMetricsProvider -{ - private static final long DEFAULT_STATISTICS_REPORT_INTERVAL_IN_SECONDS = 60L; - - @Reference(service = TableStorageStates.class, - cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.STATIC) - private volatile TableStorageStates myTableStorageStates; - - private volatile TableRepairMetricsImpl myDelegateTableRepairMetrics; - - @Activate - public void activate(final Configuration configuration) - { - myDelegateTableRepairMetrics = TableRepairMetricsImpl.builder() - .withTableStorageStates(myTableStorageStates) - .withMeterRegistry(Metrics.globalRegistry) - .build(); - } - - @Deactivate - public void deactivate() - { - myDelegateTableRepairMetrics.close(); - } - - @Override - public void repairState(final TableReference tableReference, final int repairedRanges, final int notRepairedRanges) - { - myDelegateTableRepairMetrics.repairState(tableReference, repairedRanges, notRepairedRanges); - } - - @Override - public Optional getRepairRatio(final TableReference tableReference) - { - return myDelegateTableRepairMetrics.getRepairRatio(tableReference); - } - - @Override - public void lastRepairedAt(final TableReference tableReference, final long lastRepairedAt) - { - myDelegateTableRepairMetrics.lastRepairedAt(tableReference, lastRepairedAt); - } - - @Override - public void remainingRepairTime(final TableReference tableReference, final long remainingRepairTime) - { - myDelegateTableRepairMetrics.remainingRepairTime(tableReference, remainingRepairTime); - } - - @Override - public void repairSession(final TableReference tableReference, - final long timeTaken, - final TimeUnit timeUnit, - final boolean successful) - { - myDelegateTableRepairMetrics.repairSession(tableReference, timeTaken, timeUnit, successful); - } - - @ObjectClassDefinition - public @interface Configuration - { - @AttributeDefinition(name = "Metrics directory", - description = "The directory which the repair metrics will be stored in") - String metricsDirectory(); - - @AttributeDefinition(name = "Report interval in seconds", - description = "The interval in which the metrics will be reported") - long metricsReportIntervalInSeconds() default DEFAULT_STATISTICS_REPORT_INTERVAL_IN_SECONDS; - } -} diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/TableStorageStatesService.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/TableStorageStatesService.java deleted file mode 100644 index 15aa7f020..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/TableStorageStatesService.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2018 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi; - -import java.util.concurrent.TimeUnit; - -import com.ericsson.bss.cassandra.ecchronos.core.JmxProxyFactory; -import com.ericsson.bss.cassandra.ecchronos.core.TableStorageStates; -import com.ericsson.bss.cassandra.ecchronos.core.TableStorageStatesImpl; - -import com.ericsson.bss.cassandra.ecchronos.core.utils.ReplicatedTableProvider; -import com.ericsson.bss.cassandra.ecchronos.core.utils.TableReference; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; -import org.osgi.service.metatype.annotations.AttributeDefinition; -import org.osgi.service.metatype.annotations.Designate; -import org.osgi.service.metatype.annotations.ObjectClassDefinition; - -@Component(service = TableStorageStates.class) -@Designate(ocd = TableStorageStatesService.Configuration.class) -public class TableStorageStatesService implements TableStorageStates -{ - private static final short DEFAULT_UPDATE_DELAY_IN_SECONDS = 60; - - @Reference(service = ReplicatedTableProvider.class, - cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile ReplicatedTableProvider myReplicatedTableProvider; - - @Reference (service = JmxProxyFactory.class, - cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile JmxProxyFactory myJmxProxyFactory; - - private volatile TableStorageStatesImpl myDelegateTableStorageStates; - - @Activate - public final synchronized void activate(final Configuration configuration) - { - long updateDelayInSeconds = configuration.updateStartupDelayInSeconds(); - - myDelegateTableStorageStates = TableStorageStatesImpl.builder() - .withReplicatedTableProvider(myReplicatedTableProvider) - .withJmxProxyFactory(myJmxProxyFactory) - .withUpdateDelay(updateDelayInSeconds, TimeUnit.SECONDS) - .build(); - } - - @Deactivate - public final synchronized void deactivate() - { - myDelegateTableStorageStates.close(); - } - - @Override - public final long getDataSize(final TableReference tableReference) - { - return myDelegateTableStorageStates.getDataSize(tableReference); - } - - @Override - public final long getDataSize() - { - return myDelegateTableStorageStates.getDataSize(); - } - - @ObjectClassDefinition - public @interface Configuration - { - @AttributeDefinition(name = "Startup delay of fetching storage state", - description = "The interval in seconds between updates of the storage states of tables") - long updateStartupDelayInSeconds() default DEFAULT_UPDATE_DELAY_IN_SECONDS; - } -} diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/TimeBasedRunPolicyService.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/TimeBasedRunPolicyService.java deleted file mode 100644 index 1d666b2f1..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/TimeBasedRunPolicyService.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2018 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi; - -import com.ericsson.bss.cassandra.ecchronos.core.TimeBasedRunPolicy; - -import com.ericsson.bss.cassandra.ecchronos.connection.NativeConnectionProvider; -import com.ericsson.bss.cassandra.ecchronos.connection.StatementDecorator; -import com.ericsson.bss.cassandra.ecchronos.core.repair.TableRepairPolicy; -import com.ericsson.bss.cassandra.ecchronos.core.scheduling.RunPolicy; -import com.ericsson.bss.cassandra.ecchronos.core.scheduling.ScheduledJob; -import com.ericsson.bss.cassandra.ecchronos.core.utils.TableReference; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Deactivate; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; -import org.osgi.service.metatype.annotations.AttributeDefinition; -import org.osgi.service.metatype.annotations.Designate; -import org.osgi.service.metatype.annotations.ObjectClassDefinition; - -@Component(service = {RunPolicy.class, TableRepairPolicy.class}) -@Designate(ocd = TimeBasedRunPolicyService.Configuration.class) -public class TimeBasedRunPolicyService implements RunPolicy, TableRepairPolicy -{ - private static final String DEFAULT_KEYSPACE_NAME = "ecchronos"; - - @Reference(service = NativeConnectionProvider.class, - cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile NativeConnectionProvider myNativeConnectionProvider; - - @Reference (service = StatementDecorator.class, - cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile StatementDecorator myStatementDecorator; - - private volatile TimeBasedRunPolicy myDelegatePolicy; - - @Activate - public final synchronized void activate(final Configuration configuration) - { - myDelegatePolicy = TimeBasedRunPolicy.builder() - .withSession(myNativeConnectionProvider.getSession()) - .withStatementDecorator(myStatementDecorator) - .withKeyspaceName(configuration.keyspaceName()) - .build(); - } - - @Deactivate - public final synchronized void deactivate() - { - myDelegatePolicy.close(); - } - - @Override - public final long validate(final ScheduledJob job) - { - return myDelegatePolicy.validate(job); - } - - @Override - public final boolean shouldRun(final TableReference tableReference) - { - return myDelegatePolicy.shouldRun(tableReference); - } - - @ObjectClassDefinition - public @interface Configuration - { - @AttributeDefinition(name = "The time based runpolicy keyspace to use", - description = "The name of the keyspace containing the time based runpolicy tables") - String keyspaceName() default DEFAULT_KEYSPACE_NAME; - } -} diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/PrintUtils.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/PrintUtils.java deleted file mode 100644 index fbf60ba62..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/PrintUtils.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2019 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi.commands; - -import java.time.Duration; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.time.format.DateTimeFormatter; -import java.time.temporal.ChronoUnit; - -final class PrintUtils -{ - private static final int PERCENT_FACTOR = 100; - - private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - - private PrintUtils() - { - } - - public static String epochToHumanReadable(final long timeInMillis) - { - return DATE_FORMATTER.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(timeInMillis), - ZoneId.systemDefault())); - } - - public static String durationToHumanReadable(final long durationInMillis) - { - Duration currentDuration = Duration.of(durationInMillis, ChronoUnit.MILLIS); - - long days = currentDuration.toDays(); - currentDuration = currentDuration.minusDays(days); - long hours = currentDuration.toHours(); - currentDuration = currentDuration.minusHours(hours); - long minutes = currentDuration.toMinutes(); - currentDuration = currentDuration.minusMinutes(minutes); - long seconds = currentDuration.getSeconds(); - - StringBuilder sb = new StringBuilder(); - - if (days > 0) - { - sb.append(days).append("d "); - } - if (hours > 0) - { - sb.append(hours).append("h "); - } - if (minutes > 0) - { - sb.append(minutes).append("m "); - } - if (seconds > 0) - { - sb.append(seconds).append("s "); - } - - return sb.toString().trim(); - } - - public static String toPercentage(final Double ratio) - { - return String.format("%.0f%%", ratio * PERCENT_FACTOR); - } -} diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/RepairConfigCommand.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/RepairConfigCommand.java deleted file mode 100644 index 96d4fa441..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/RepairConfigCommand.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2019 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi.commands; - -import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairConfiguration; -import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairScheduler; -import com.ericsson.bss.cassandra.ecchronos.core.repair.ScheduledRepairJobView; -import com.ericsson.bss.cassandra.ecchronos.core.utils.TableReference; -import com.google.common.annotations.VisibleForTesting; -import org.apache.karaf.shell.api.action.Action; -import org.apache.karaf.shell.api.action.Command; -import org.apache.karaf.shell.api.action.lifecycle.Reference; -import org.apache.karaf.shell.api.action.lifecycle.Service; -import org.apache.karaf.shell.support.table.ShellTable; - -import java.io.PrintStream; -import java.util.Arrays; -import java.util.List; - -@Service -@Command(scope = "repair", name = "config", description = "Give the current repair configuration") -public class RepairConfigCommand implements Action -{ - @Reference - private RepairScheduler myRepairScheduler; - - public RepairConfigCommand() - { - } - - @VisibleForTesting - RepairConfigCommand(final RepairScheduler repairScheduler) - { - myRepairScheduler = repairScheduler; - } - - @Override - public final Object execute() throws Exception - { - printConfig(System.out); - return null; - } - - public final void printConfig(final PrintStream out) - { - ShellTable table = createShellTable(); - - myRepairScheduler.getCurrentRepairJobs() - .stream() - .sorted(RepairConfigCommand::sortedByName) - .forEach(job -> table.addRow().addContent(createRowContent(job))); - - table.print(out); - } - - private ShellTable createShellTable() - { - ShellTable table = new ShellTable(); - table.column("Table name"); - table.column("Interval"); - table.column("Parallelism"); - table.column("Unwind ratio"); - table.column("Warning time"); - table.column("Error time"); - return table; - } - - private List createRowContent(final ScheduledRepairJobView job) - { - RepairConfiguration config = job.getRepairConfiguration(); - String tableName = job.getTableReference().getKeyspace() + "." + job.getTableReference().getTable(); - return Arrays.asList( - tableName, - PrintUtils.durationToHumanReadable(config.getRepairIntervalInMs()), - config.getRepairParallelism(), - PrintUtils.toPercentage(config.getRepairUnwindRatio()), - PrintUtils.durationToHumanReadable(config.getRepairWarningTimeInMs()), - PrintUtils.durationToHumanReadable(config.getRepairErrorTimeInMs()) - ); - } - - private static int sortedByName(final ScheduledRepairJobView view1, final ScheduledRepairJobView view2) - { - TableReference table1 = view1.getTableReference(); - TableReference table2 = view2.getTableReference(); - - int cmp = table1.getKeyspace().compareTo(table2.getKeyspace()); - if (cmp != 0) - { - return cmp; - } - - return table1.getTable().compareTo(table2.getKeyspace()); - } -} diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/RepairStatusCommand.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/RepairStatusCommand.java deleted file mode 100644 index 219ea007a..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/RepairStatusCommand.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright 2019 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi.commands; - -import java.io.PrintStream; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairScheduler; -import com.ericsson.bss.cassandra.ecchronos.core.repair.types.Schedule; -import org.apache.karaf.shell.api.action.Action; -import org.apache.karaf.shell.api.action.Command; -import org.apache.karaf.shell.api.action.Option; -import org.apache.karaf.shell.api.action.lifecycle.Reference; -import org.apache.karaf.shell.api.action.lifecycle.Service; -import org.apache.karaf.shell.support.ansi.SimpleAnsi; -import org.apache.karaf.shell.support.table.ShellTable; - -import static com.ericsson.bss.cassandra.ecchronos.core.repair.ScheduledRepairJobView.Status; - -@Service -@Command(scope = "repair", name = "status", description = "Give the current repair status") -@SuppressWarnings("visibilitymodifier") -public class RepairStatusCommand implements Action -{ - @Option(name = "-l", aliases = "--limit", - description = "Number of entries to display") - int limit = Integer.MAX_VALUE; - - @Option(name = "-s", aliases = "--sort-by", - description = "Sort output based on TABLE_NAME/STATUS/REPAIRED_RATIO/REPAIRED_AT/NEXT_REPAIR") - SortBy sortBy = SortBy.TABLE_NAME; - - @Option(name = "-r", aliases = "--reverse", - description = "Reverse the sort order") - boolean reverse = false; - - @Option(name = "-a", aliases = "--all", - description = "Show status for all tables (including complete status)") - boolean showAll = false; - - @Option(name = "--summary", - description = "Show summary only") - boolean summaryOnly = false; - - @Option(name = "--no-format", - description = "Disable output formatting of table and colors") - boolean noFormat = false; - - @Reference - private RepairScheduler myRepairScheduler; - - @Override - public final Object execute() throws Exception - { - List schedules = getScheduledRepairJobs(); - printTable(System.out, schedules); - printSummary(System.out, schedules); - return null; - } - - public final List getScheduledRepairJobs() - { - return myRepairScheduler.getCurrentRepairJobs() - .stream() - .map(Schedule::new) - .collect(Collectors.toList()); - } - - public final void printTable(final PrintStream out, final List schedules) - { - if (!summaryOnly) - { - ShellTable table = createShellTable(); - schedules.stream() - .filter(this::filterSchedule) - .sorted(getScheduleComparator()) - .limit(limit) - .forEach(job -> table.addRow().addContent(toRowContent(job))); - table.print(out, !noFormat); - } - } - - private ShellTable createShellTable() - { - ShellTable table = new ShellTable(); - table.column("Table name"); - table.column("Status"); - table.column("Repaired ratio"); - table.column("Repaired at"); - table.column("Next repair"); - return table; - } - - private boolean filterSchedule(final Schedule schedule) - { - return showAll || schedule.status != Status.COMPLETED; - } - - public final Comparator getScheduleComparator() - { - Comparator comparator; - switch (sortBy) - { - case STATUS: - comparator = Comparator.comparing(job -> job.status); - break; - case REPAIRED_RATIO: - comparator = Comparator.comparing(job -> job.repairedRatio); - break; - case REPAIRED_AT: - comparator = Comparator.comparing(job -> job.lastRepairedAtInMs); - break; - case NEXT_REPAIR: - comparator = Comparator.comparing(job -> job.nextRepairInMs); - break; - case TABLE_NAME: - default: - comparator = Comparator.comparing(job -> getTableReference(job.keyspace, job.table)); - break; - } - - return reverse - ? comparator.reversed() - : comparator; - } - - private static String getTableReference(final String keyspace, final String table) - { - return keyspace + "." + table; - } - - public final List toRowContent(final Schedule schedule) - { - return Arrays.asList( - getTableReference(schedule.keyspace, schedule.table), - schedule.status.name(), - PrintUtils.toPercentage(schedule.repairedRatio), - PrintUtils.epochToHumanReadable(schedule.lastRepairedAtInMs), - PrintUtils.epochToHumanReadable(schedule.nextRepairInMs)); - } - - public final void printSummary(final PrintStream out, final List schedules) - { - Map stats = getStatusCount(schedules); - - StringBuilder sb = new StringBuilder("Summary: "); - sb.append(stats.getOrDefault(Status.COMPLETED, 0L)).append(" completed, "); - sb.append(stats.getOrDefault(Status.ON_TIME, 0L)).append(" on time, "); - sb.append(maybeCreateDescription(stats.get(Status.LATE), SimpleAnsi.COLOR_YELLOW, " late")); - sb.append(maybeCreateDescription(stats.get(Status.OVERDUE), SimpleAnsi.COLOR_RED, " overdue")); - sb.setLength(sb.length() - 2); - - out.println(sb.toString()); - } - - private Map getStatusCount(final List schedules) - { - return schedules.stream().collect(Collectors.groupingBy(schedule -> schedule.status, Collectors.counting())); - } - - private String maybeCreateDescription(final Long number, final String color, final String description) - { - StringBuilder sb = new StringBuilder(); - if (number != null) - { - sb.append(formatColor(color)) - .append(number) - .append(description) - .append(formatColor(SimpleAnsi.COLOR_DEFAULT)) - .append(", "); - } - return sb.toString(); - } - - private String formatColor(final String color) - { - return noFormat ? "" : color; - } - - enum SortBy - { - TABLE_NAME, STATUS, REPAIRED_RATIO, REPAIRED_AT, NEXT_REPAIR; - } -} diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/RepairTableStatusCommand.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/RepairTableStatusCommand.java deleted file mode 100644 index e2e79c84d..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/RepairTableStatusCommand.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright 2019 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi.commands; - -import java.io.PrintStream; -import java.net.InetAddress; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.stream.Collectors; - -import com.ericsson.bss.cassandra.ecchronos.core.repair.ScheduledRepairJobView; -import org.apache.karaf.shell.api.action.Action; -import org.apache.karaf.shell.api.action.Command; -import org.apache.karaf.shell.api.action.Completion; -import org.apache.karaf.shell.api.action.Option; -import org.apache.karaf.shell.api.action.lifecycle.Reference; -import org.apache.karaf.shell.api.action.lifecycle.Service; -import org.apache.karaf.shell.support.CommandException; -import org.apache.karaf.shell.support.completers.StringsCompleter; -import org.apache.karaf.shell.support.table.ShellTable; - -import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairScheduler; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.RepairStateSnapshot; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.VnodeRepairState; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.VnodeRepairStates; -import com.ericsson.bss.cassandra.ecchronos.core.utils.LongTokenRange; -import com.ericsson.bss.cassandra.ecchronos.core.utils.DriverNode; -import com.ericsson.bss.cassandra.ecchronos.core.utils.TableReference; -import com.google.common.annotations.VisibleForTesting; - -@Service -@Command(scope = "repair", name = "table-status", description = "Give the current repair status for the given table") -public class RepairTableStatusCommand implements Action -{ - private static final String SORT_RANGE = "RANGE"; - private static final String SORT_REPAIRED_AT = "REPAIRED_AT"; - - @Reference - private RepairScheduler myRepairSchedulerService; - - @Option(name = "-t", aliases = "--table-reference", - description = "The table reference in format .", required = true) - @Completion(TableReferenceCompleter.class) - private String myTableRef; - - @Option(name = "-s", aliases = "--sort-by", - description = "Sort output based on " + SORT_RANGE + "/" - + SORT_REPAIRED_AT) - @Completion(value = StringsCompleter.class, values = { SORT_RANGE, SORT_REPAIRED_AT }) - private String mySortBy = SORT_RANGE; - - @Option(name = "-r", aliases = "--reverse", - description = "Reverse the sort order") - private boolean myReverse = false; - - @Option(name = "-l", aliases = "--limit", - description = "Number of entries to display") - private int myLimit = Integer.MAX_VALUE; - - public RepairTableStatusCommand() - { - } - - @VisibleForTesting - RepairTableStatusCommand(final RepairScheduler repairScheduler, - final String tableRef, - final String sortBy, - final boolean reverse, - final int limit) - { - myRepairSchedulerService = repairScheduler; - myTableRef = tableRef; - mySortBy = sortBy; - myReverse = reverse; - myLimit = limit; - } - - @Override - public final Object execute() throws Exception - { - printTableRanges(System.out, getVnodeRepairStates(), getRepairStateComparator()); - return null; - } - - public final VnodeRepairStates getVnodeRepairStates() throws CommandException - { - return myRepairSchedulerService.getCurrentRepairJobs() - .stream() - .filter(this::correctTable) - .findFirst() - .map(ScheduledRepairJobView::getRepairStateSnapshot) - .map(RepairStateSnapshot::getVnodeRepairStates) - .orElseThrow(() -> new CommandException( - "Table reference '" + myTableRef + "' was not found. Format must be .
")); - } - - public final Comparator getRepairStateComparator() - { - Comparator comparator; - switch (mySortBy) - { - case SORT_REPAIRED_AT: - comparator = Comparator.comparing(VnodeRepairState::lastRepairedAt); - break; - case SORT_RANGE: - default: - comparator = Comparator.comparing(vnodeRepairState -> vnodeRepairState.getTokenRange().start); - break; - } - - return myReverse - ? comparator.reversed() - : comparator; - } - - public final void printTableRanges(final PrintStream out, - final VnodeRepairStates repairStates, - final Comparator comparator) - { - ShellTable table = createShellTable(); - - repairStates.getVnodeRepairStates() - .stream() - .sorted(comparator) - .limit(myLimit) - .forEach(state -> table.addRow().addContent(getRowContent(state))); - - table.print(out); - } - - private boolean correctTable(final ScheduledRepairJobView tableView) - { - TableReference tableReference = tableView.getTableReference(); - String tableRef = tableReference.getKeyspace() + "." + tableReference.getTable(); - return tableRef.equalsIgnoreCase(myTableRef); - } - - private ShellTable createShellTable() - { - ShellTable table = new ShellTable(); - table.column("Range"); - table.column("Last repaired at"); - table.column("Replicas"); - return table; - } - - private static List getRowContent(final VnodeRepairState state) - { - LongTokenRange tokenRange = state.getTokenRange(); - String lastRepairedAt = PrintUtils.epochToHumanReadable(state.lastRepairedAt()); - List replicas = state.getReplicas().stream() - .map(DriverNode::getPublicAddress) - .map(InetAddress::getHostAddress) - .sorted() - .distinct() - .collect(Collectors.toList()); - return Arrays.asList(tokenRange, lastRepairedAt, replicas); - } -} diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/TableReferenceCompleter.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/TableReferenceCompleter.java deleted file mode 100644 index 75d6510e1..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/TableReferenceCompleter.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2019 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi.commands; - -import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairScheduler; -import com.ericsson.bss.cassandra.ecchronos.core.repair.ScheduledRepairJobView; -import org.apache.karaf.shell.api.action.lifecycle.Reference; -import org.apache.karaf.shell.api.action.lifecycle.Service; -import org.apache.karaf.shell.api.console.CommandLine; -import org.apache.karaf.shell.api.console.Completer; -import org.apache.karaf.shell.api.console.Session; -import org.apache.karaf.shell.support.completers.StringsCompleter; - -import java.util.List; - -@Service -public class TableReferenceCompleter implements Completer -{ - @Reference - private RepairScheduler myRepairSchedulerService; - - @Override - public final int complete(final Session session, final CommandLine commandLine, final List candidates) - { - StringsCompleter delegate = new StringsCompleter(); - try - { - myRepairSchedulerService.getCurrentRepairJobs() - .stream() - .map(ScheduledRepairJobView::getTableReference) - .forEach(tableReference -> delegate.getStrings().add(tableReference.toString())); - } - catch (Exception e) // NOPMD - { - // Ignore - } - return delegate.complete(session, commandLine, candidates); - } -} diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/package-info.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/package-info.java deleted file mode 100644 index 7bad77a1b..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/package-info.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2019 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. - */ - -/** - * - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi.commands; diff --git a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/package-info.java b/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/package-info.java deleted file mode 100644 index 2c6170fd1..000000000 --- a/core.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/package-info.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2020 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. - */ - -/** - * - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi; diff --git a/core.osgi/src/test/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/TestPrintUtils.java b/core.osgi/src/test/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/TestPrintUtils.java deleted file mode 100644 index 227e7495e..000000000 --- a/core.osgi/src/test/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/TestPrintUtils.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2019 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi.commands; - -import java.util.TimeZone; - -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public class TestPrintUtils -{ - @Test - public void testDurationToHumanReadable() - { - assertThat(PrintUtils.durationToHumanReadable(293387000)).isEqualTo("3d 9h 29m 47s"); - assertThat(PrintUtils.durationToHumanReadable(691200000)).isEqualTo("8d"); - assertThat(PrintUtils.durationToHumanReadable(300000)).isEqualTo("5m"); - } - - @Test - public void testEpochToHumanReadable() - { - TimeZone.setDefault(TimeZone.getTimeZone("UTC")); - assertThat(PrintUtils.epochToHumanReadable(0)).isEqualTo("1970-01-01 00:00:00"); - assertThat(PrintUtils.epochToHumanReadable(1573720152000L)).isEqualTo("2019-11-14 08:29:12"); - } - - @Test - public void testToPercentage() - { - assertThat(PrintUtils.toPercentage(0.1)).isEqualTo("10%"); - assertThat(PrintUtils.toPercentage(0.344)).isEqualTo("34%"); - assertThat(PrintUtils.toPercentage(0.345)).isEqualTo("35%"); - } -} diff --git a/core.osgi/src/test/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/TestRepairConfigCommand.java b/core.osgi/src/test/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/TestRepairConfigCommand.java deleted file mode 100644 index 2397e1455..000000000 --- a/core.osgi/src/test/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/TestRepairConfigCommand.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2019 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi.commands; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.time.Duration; -import java.util.UUID; - -import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairConfiguration; -import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairOptions; -import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairScheduler; -import com.ericsson.bss.cassandra.ecchronos.core.repair.ScheduledRepairJobView; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.RepairStateSnapshot; -import com.ericsson.bss.cassandra.ecchronos.core.utils.TableReference; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -import static com.ericsson.bss.cassandra.ecchronos.core.osgi.commands.TestRepairStatusCommand.createTableRef; -import static java.util.Arrays.asList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@RunWith (MockitoJUnitRunner.class) -public class TestRepairConfigCommand -{ - private static final long time1 = Duration.ofHours(6).toMillis(); - private static final long time2 = Duration.ofDays(3).plusHours(2).plusMinutes(33).plusSeconds(44).toMillis(); - private static final long time3 = Duration.ofDays(7).toMillis(); - - @Mock - RepairScheduler schedulerMock; - - @Mock - private static RepairStateSnapshot repairStateSnapshotMock; - - @Test - public void testRepairConfigSortedByTableName() - { - // Given - ScheduledRepairJobView job1 = mockRepairJob("ks1.tbl1", time1, 0.1, time3, time2); - ScheduledRepairJobView job2 = mockRepairJob("ks2.tbl1", time2, 0.2, time1, time3); - ScheduledRepairJobView job3 = mockRepairJob("ks1.tbl2", time3, 0.3, time2, time1); - - when(schedulerMock.getCurrentRepairJobs()).thenReturn(asList(job1, job2, job3)); - - RepairConfigCommand command = new RepairConfigCommand(schedulerMock); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - PrintStream out = new PrintStream(os); - // When - command.printConfig(out); - // Then - String expected = - "Table name │ Interval │ Parallelism │ Unwind ratio │ Warning time │ Error time\n" + - "───────────┼───────────────┼─────────────┼──────────────┼───────────────┼──────────────\n" + - "ks1.tbl1 │ 6h │ PARALLEL │ 10% │ 7d │ 3d 2h 33m 44s\n" + - "ks1.tbl2 │ 7d │ PARALLEL │ 30% │ 3d 2h 33m 44s │ 6h\n" + - "ks2.tbl1 │ 3d 2h 33m 44s │ PARALLEL │ 20% │ 6h │ 7d\n"; - assertThat(os.toString()).isEqualTo(expected); - } - - private static ScheduledRepairJobView mockRepairJob(String table, long repairInterval, double unwindRatio, long warningTime, long errorTime) - { - TableReference tableReference = createTableRef(table); - - RepairConfiguration repairConfiguration = mock(RepairConfiguration.class); - when(repairConfiguration.getRepairIntervalInMs()).thenReturn(repairInterval); - when(repairConfiguration.getRepairParallelism()).thenReturn(RepairOptions.RepairParallelism.PARALLEL); - when(repairConfiguration.getRepairUnwindRatio()).thenReturn(unwindRatio); - when(repairConfiguration.getRepairWarningTimeInMs()).thenReturn(warningTime); - when(repairConfiguration.getRepairErrorTimeInMs()).thenReturn(errorTime); - - return new ScheduledRepairJobView(UUID.randomUUID(), tableReference, repairConfiguration, repairStateSnapshotMock, ScheduledRepairJobView.Status.ON_TIME, 0, 0); - } -} diff --git a/core.osgi/src/test/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/TestRepairStatusCommand.java b/core.osgi/src/test/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/TestRepairStatusCommand.java deleted file mode 100644 index 600c3d9ec..000000000 --- a/core.osgi/src/test/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/TestRepairStatusCommand.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright 2019 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi.commands; - -import com.ericsson.bss.cassandra.ecchronos.core.osgi.commands.RepairStatusCommand.SortBy; -import com.ericsson.bss.cassandra.ecchronos.core.repair.ScheduledRepairJobView; -import com.ericsson.bss.cassandra.ecchronos.core.repair.types.Schedule; -import com.ericsson.bss.cassandra.ecchronos.core.repair.types.ScheduleConfig; -import com.ericsson.bss.cassandra.ecchronos.core.utils.TableReference; -import junitparams.JUnitParamsRunner; -import junitparams.Parameters; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.time.Instant; -import java.util.Comparator; -import java.util.List; -import java.util.TimeZone; -import java.util.UUID; - -import static java.util.Arrays.asList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@RunWith(JUnitParamsRunner.class) -public class TestRepairStatusCommand -{ - private static final Schedule SCHEDULE1 = new Schedule(UUID.randomUUID(), "ks", "tbl3", - ScheduledRepairJobView.Status.ON_TIME, 0.234, toMillis("1970-01-01T00:00:00Z"), - toMillis("2019-12-31T23:59:00Z"), new ScheduleConfig()); - private static final Schedule SCHEDULE2 = new Schedule(UUID.randomUUID(), "ks", "tbl2", - ScheduledRepairJobView.Status.COMPLETED, 0.0, toMillis("2019-12-24T12:34:00Z"), - toMillis("2019-12-29T00:34:00Z"), new ScheduleConfig()); - private static final Schedule SCHEDULE3 = new Schedule(UUID.randomUUID(), "ks", "tbl1", - ScheduledRepairJobView.Status.LATE, 1.0, toMillis("2019-11-12T12:34:00Z"), toMillis("2019-12-29T12:34:00Z"), - new ScheduleConfig()); - private static final Schedule SCHEDULE4 = new Schedule(UUID.randomUUID(), "ks", "tbl4", - ScheduledRepairJobView.Status.OVERDUE, 0.456, toMillis("2029-11-12T23:59:00Z"), - toMillis("2030-11-19T00:00:00Z"), new ScheduleConfig()); - private static final List SCHEDULES = asList(SCHEDULE1, SCHEDULE2, SCHEDULE3, SCHEDULE4); - - @BeforeClass - public static void setup() - { - TimeZone.setDefault(TimeZone.getTimeZone("UTC")); - } - - @Test - @Parameters(method = "comparatorParameters") - public void testThatComparatorSortsCorrectly(SortBy sortBy, boolean reverse, List expected) - { - // Given - RepairStatusCommand command = new RepairStatusCommand(); - command.sortBy = sortBy; - command.reverse = reverse; - List schedules = asList(SCHEDULE1, SCHEDULE2, SCHEDULE3, SCHEDULE4); - // When - Comparator comparator = command.getScheduleComparator(); - schedules.sort(comparator); - // Then - assertThat(schedules).isEqualTo(expected); - } - - public Object[][] comparatorParameters() - { - return new Object[][]{ - {SortBy.TABLE_NAME, false, asList(SCHEDULE3, SCHEDULE2, SCHEDULE1, SCHEDULE4)}, - {SortBy.TABLE_NAME, true, asList(SCHEDULE4, SCHEDULE1, SCHEDULE2, SCHEDULE3)}, - {SortBy.STATUS, false, asList(SCHEDULE2, SCHEDULE1, SCHEDULE3, SCHEDULE4)}, - {SortBy.STATUS, true, asList(SCHEDULE4, SCHEDULE3, SCHEDULE1, SCHEDULE2)}, - {SortBy.REPAIRED_RATIO, false, asList(SCHEDULE2, SCHEDULE1, SCHEDULE4, SCHEDULE3)}, - {SortBy.REPAIRED_RATIO, true, asList(SCHEDULE3, SCHEDULE4, SCHEDULE1, SCHEDULE2)}, - {SortBy.REPAIRED_AT, false, asList(SCHEDULE1, SCHEDULE3, SCHEDULE2, SCHEDULE4)}, - {SortBy.REPAIRED_AT, true, asList(SCHEDULE4, SCHEDULE2, SCHEDULE3, SCHEDULE1)}, - {SortBy.NEXT_REPAIR, false, asList(SCHEDULE2, SCHEDULE3, SCHEDULE1, SCHEDULE4)}, - {SortBy.NEXT_REPAIR, true, asList(SCHEDULE4, SCHEDULE1, SCHEDULE3, SCHEDULE2)}, - }; - } - - @Test - public void testPrintTableAllTablesSortedByNameWithFormattedschedule() - { - // Given - RepairStatusCommand command = new RepairStatusCommand(); - command.sortBy = SortBy.TABLE_NAME; - command.showAll = true; - // When - String schedule = executePrintTable(command); - // Then - String expected = - "Table name │ Status │ Repaired ratio │ Repaired at │ Next repair\n" + - "───────────┼───────────┼────────────────┼─────────────────────┼────────────────────\n" + - "ks.tbl1 │ LATE │ 100% │ 2019-11-12 12:34:00 │ 2019-12-29 12:34:00\n" + - "ks.tbl2 │ COMPLETED │ 0% │ 2019-12-24 12:34:00 │ 2019-12-29 00:34:00\n" + - "ks.tbl3 │ ON_TIME │ 23% │ 1970-01-01 00:00:00 │ 2019-12-31 23:59:00\n" + - "ks.tbl4 │ OVERDUE │ 46% │ 2029-11-12 23:59:00 │ 2030-11-19 00:00:00\n"; - assertThat(schedule).isEqualTo(expected); - } - - @Test - public void testPrintTableSortedByStatusWithFormattedschedule() - { - // Given - RepairStatusCommand command = new RepairStatusCommand(); - command.sortBy = SortBy.STATUS; - // When - String schedule = executePrintTable(command); - // Then - String expected = - "Table name │ Status │ Repaired ratio │ Repaired at │ Next repair\n" + - "───────────┼─────────┼────────────────┼─────────────────────┼────────────────────\n" + - "ks.tbl3 │ ON_TIME │ 23% │ 1970-01-01 00:00:00 │ 2019-12-31 23:59:00\n" + - "ks.tbl1 │ LATE │ 100% │ 2019-11-12 12:34:00 │ 2019-12-29 12:34:00\n" + - "ks.tbl4 │ OVERDUE │ 46% │ 2029-11-12 23:59:00 │ 2030-11-19 00:00:00\n"; - assertThat(schedule).isEqualTo(expected); - } - - @Test - public void testPrintTableAllTablesSortedByRepairedAtReversedLimitedAndNoFormat() - { - // Given - RepairStatusCommand command = new RepairStatusCommand(); - command.sortBy = SortBy.REPAIRED_AT; - command.reverse = true; - command.noFormat = true; - command.limit = 2; - // When - String schedule = executePrintTable(command); - // Then - String expected = - "ks.tbl4 \tOVERDUE\t46% \t2029-11-12 23:59:00\t2030-11-19 00:00:00\n" + - "ks.tbl1 \tLATE \t100% \t2019-11-12 12:34:00\t2019-12-29 12:34:00\n"; - assertThat(schedule).isEqualTo(expected); - } - - @Test - public void testPrintTableWithSummaryOnlyFlag() - { - // Given - RepairStatusCommand command = new RepairStatusCommand(); - command.summaryOnly = true; - // When - String schedule = executePrintTable(command); - // Then - assertThat(schedule).isEmpty(); - } - - @Test - public void testPrintSummary() - { - // Given - RepairStatusCommand command = new RepairStatusCommand(); - List schedules = asList(SCHEDULE2, SCHEDULE2); - // When - String formattedschedule = executePrintSummary(command, schedules); - command.noFormat = true; - String plainschedule = executePrintSummary(command, schedules); - // Then - assertThat(formattedschedule).isEqualTo("Summary: 2 completed, 0 on time\n"); - assertThat(plainschedule).isEqualTo("Summary: 2 completed, 0 on time\n"); - } - - @Test - public void testPrintSummaryWithWarnings() - { - // Given - RepairStatusCommand command = new RepairStatusCommand(); - List schedules = asList(SCHEDULE1, SCHEDULE3, SCHEDULE4, SCHEDULE3, SCHEDULE3, SCHEDULE4); - // When - String formattedschedule = executePrintSummary(command, schedules); - command.noFormat = true; - String plainschedule = executePrintSummary(command, schedules); - // Then - assertThat(formattedschedule).isEqualTo("Summary: 0 completed, 1 on time, \u001B[33m3 late\u001B[39m, \u001B[31m2 overdue\u001B[39m\n"); - assertThat(plainschedule).isEqualTo("Summary: 0 completed, 1 on time, 3 late, 2 overdue\n"); - } - - static TableReference createTableRef(String table) - { - String[] tableSplit = table.split("\\."); - TableReference tableReference = mock(TableReference.class); - when(tableReference.getKeyspace()).thenReturn(tableSplit[0]); - when(tableReference.getTable()).thenReturn(tableSplit[1]); - return tableReference; - } - - private static long toMillis(String date) - { - return Instant.parse(date).toEpochMilli(); - } - - private String executePrintTable(RepairStatusCommand command) - { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - PrintStream out = new PrintStream(os); - command.printTable(out, SCHEDULES); - return os.toString(); - } - - private String executePrintSummary(RepairStatusCommand command, List schedules) - { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - PrintStream out = new PrintStream(os); - command.printSummary(out, schedules); - return os.toString(); - } -} diff --git a/core.osgi/src/test/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/TestRepairTableStatusCommand.java b/core.osgi/src/test/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/TestRepairTableStatusCommand.java deleted file mode 100644 index f6d69e326..000000000 --- a/core.osgi/src/test/java/com/ericsson/bss/cassandra/ecchronos/core/osgi/commands/TestRepairTableStatusCommand.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright 2019 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. - */ -package com.ericsson.bss.cassandra.ecchronos.core.osgi.commands; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.time.Instant; -import java.util.Comparator; -import java.util.List; -import java.util.TimeZone; -import java.util.UUID; -import java.util.stream.Stream; - -import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairScheduler; -import com.ericsson.bss.cassandra.ecchronos.core.repair.ScheduledRepairJobView; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.RepairStateSnapshot; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.VnodeRepairState; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.VnodeRepairStates; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.VnodeRepairStatesImpl; -import com.ericsson.bss.cassandra.ecchronos.core.utils.LongTokenRange; -import com.ericsson.bss.cassandra.ecchronos.core.utils.DriverNode; -import com.ericsson.bss.cassandra.ecchronos.core.utils.TableReference; -import com.google.common.collect.ImmutableSet; - -import junitparams.JUnitParamsRunner; -import junitparams.Parameters; - -import org.apache.karaf.shell.support.CommandException; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import static com.ericsson.bss.cassandra.ecchronos.core.osgi.commands.TestRepairStatusCommand.createTableRef; -import static java.util.Arrays.asList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@RunWith(JUnitParamsRunner.class) -public class TestRepairTableStatusCommand -{ - private static final VnodeRepairState state1 = new VnodeRepairState(new LongTokenRange(5, 6), mockNode("127.0.0.1", "127.0.0.2"), toMillis("2019-12-24T14:57:00Z")); - private static final VnodeRepairState state2 = new VnodeRepairState(new LongTokenRange(1, 2), mockNode("127.0.0.1", "127.0.0.3"), toMillis("2019-11-12T00:26:59Z")); - private static final VnodeRepairState state3 = new VnodeRepairState(new LongTokenRange(3, 4), mockNode("127.0.0.2", "127.0.0.3"), toMillis("1970-01-01T00:00:00Z")); - - private static final VnodeRepairStates states = createRepairStates(state1, state2, state3); - - @BeforeClass - public static void setup() - { - TimeZone.setDefault(TimeZone.getTimeZone("UTC")); - } - - @Test - public void testThatGetVnodeRepairStatesFindsMatch() throws CommandException - { - // Given - RepairTableStatusCommand command = mockCommand("KS1.TBL1"); - // When - VnodeRepairStates vnodeRepairStates = command.getVnodeRepairStates(); - // Then - assertThat(vnodeRepairStates).isSameAs(states); - } - - @Test - public void testThatGetVnodeRepairStatesThrowsWhenTableDoesNotExist() - { - // Given - RepairTableStatusCommand command = mockCommand("NonExisting.Table"); - // When looking for a non existing table - Then an exception should be thrown - assertThatExceptionOfType(CommandException.class) - .isThrownBy(command::getVnodeRepairStates) - .withMessage("Table reference 'NonExisting.Table' was not found. Format must be .
"); - } - - @Test - @Parameters(method = "comparatorParameters") - public void testThatComparatorSortsCorrectly(String sortBy, boolean reverse, List expected) - { - // Given - RepairTableStatusCommand command = mockCommand(sortBy, reverse, 0); - List jobs = asList(state1, state2, state3); - // When - Comparator comparator = command.getRepairStateComparator(); - jobs.sort(comparator); - // Then - assertThat(jobs).isEqualTo(expected); - } - - public Object[][] comparatorParameters() - { - return new Object[][]{ - {"RANGE", false, asList(state2, state3, state1)}, - {"RANGE", true, asList(state1, state3, state2)}, - {"REPAIRED_AT", false, asList(state3, state2, state1)}, - {"REPAIRED_AT", true, asList(state1, state2, state3)}, - {"DEFAULT", false, asList(state2, state3, state1)}, - }; - } - - @Test - public void testTableStatusSortedByRange() - { - // Given - RepairTableStatusCommand command = mockCommand("RANGE", false, 4); - Comparator comparator = command.getRepairStateComparator(); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - PrintStream out = new PrintStream(os); - // When - command.printTableRanges(out, states, comparator); - // Then - String expected = - "Range │ Last repaired at │ Replicas\n" + - "──────┼─────────────────────┼───────────────────────\n" + - "(1,2] │ 2019-11-12 00:26:59 │ [127.0.0.1, 127.0.0.3]\n" + - "(3,4] │ 1970-01-01 00:00:00 │ [127.0.0.2, 127.0.0.3]\n" + - "(5,6] │ 2019-12-24 14:57:00 │ [127.0.0.1, 127.0.0.2]\n"; - assertThat(os.toString()).isEqualTo(expected); - } - - @Test - public void testTableStatusSortedRepairedAtReversedAndLimited() - { - // Given - RepairTableStatusCommand command = mockCommand("REPAIRED_AT", true, 2); - Comparator comparator = command.getRepairStateComparator(); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - PrintStream out = new PrintStream(os); - // When - command.printTableRanges(out, states, comparator); - // Then - String expected = - "Range │ Last repaired at │ Replicas\n" + - "──────┼─────────────────────┼───────────────────────\n" + - "(5,6] │ 2019-12-24 14:57:00 │ [127.0.0.1, 127.0.0.2]\n" + - "(1,2] │ 2019-11-12 00:26:59 │ [127.0.0.1, 127.0.0.3]\n"; - assertThat(os.toString()).isEqualTo(expected); - } - - private static ImmutableSet mockNode(String... hosts) - { - ImmutableSet.Builder builder = ImmutableSet.builder(); - Stream.of(hosts) - .map(TestRepairTableStatusCommand::mockNode) - .forEach(builder::add); - return builder.build(); - } - - private static DriverNode mockNode(String hostName) - { - DriverNode host = mock(DriverNode.class); - try - { - when(host.getPublicAddress()).thenReturn(InetAddress.getByName(hostName)); - } - catch (UnknownHostException e) - { - throw new RuntimeException("Unable to mock node", e); - } - return host; - } - - private static VnodeRepairStates createRepairStates(VnodeRepairState... states) - { - return VnodeRepairStatesImpl.newBuilder(asList(states)).build(); - } - - private static ScheduledRepairJobView mockRepairJob(VnodeRepairStates vnodeRepairStates) - { - TableReference tableReference = createTableRef("ks1.tbl1"); - RepairStateSnapshot state = mock(RepairStateSnapshot.class); - when(state.getVnodeRepairStates()).thenReturn(vnodeRepairStates); - return new ScheduledRepairJobView(UUID.randomUUID(), tableReference, null, state, ScheduledRepairJobView.Status.ON_TIME, 0, 0); - } - - private RepairTableStatusCommand mockCommand(String tableRef) - { - return new RepairTableStatusCommand(mockScheduler(), tableRef, null, false, 0); - } - - private RepairTableStatusCommand mockCommand(String sortBy, boolean reverse, int limit) - { - return new RepairTableStatusCommand(mockScheduler(), "Table", sortBy, reverse, limit); - } - - private RepairScheduler mockScheduler() - { - ScheduledRepairJobView repairJobView = mockRepairJob(states); - RepairScheduler schedulerMock = mock(RepairScheduler.class); - when(schedulerMock.getCurrentRepairJobs()).thenReturn(asList(repairJobView)); - return schedulerMock; - } - - private static long toMillis(String date) - { - return Instant.parse(date).toEpochMilli(); - } -} diff --git a/docs/REPAIR_MONITORING.md b/docs/REPAIR_MONITORING.md index 653dbd8c6..7f30bad3f 100644 --- a/docs/REPAIR_MONITORING.md +++ b/docs/REPAIR_MONITORING.md @@ -3,8 +3,6 @@ Once ecChronos is up and running its progress can be monitored by [metrics](METRICS.md), status commands or via log files, see below depending on deployment. -## Standalone - The following commands (placed in the `bin` directory) are available: | Command | Description | @@ -17,15 +15,3 @@ The following commands (placed in the `bin` directory) are available: Logging is configured in `conf/logback.xml`. By default `ecc.log` and `ecc.debug.log` files will be produce. As the naming suggests - the debug-log contains more information but entries will be rotated out faster as the logs grow. - -## OSGI - -If running ecChronos inside a Karaf container the following console-commands are available: - -| Command | Description | -|-----------------------|---------------------------------------| -| `repair:status` | Repair status overview for all tables | -| `repair:table-status` | Detailed status for a given table | -| `repair:config` | Configuration for all tables | - -Logging is configured in the OSGI runtime environment. By default for Karaf, ecChronos will log to `karaf.log`. diff --git a/docs/TESTS.md b/docs/TESTS.md index f483fcf40..c02b09ef8 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -2,7 +2,7 @@ Make sure to add tests to the relevant phase(s) when possible. If mocks or a single Apache Cassandra instance is necessary it may be run as a unit test. -If multiple Apache Cassandra instances are necessary then test cases should be added to `standalone-integration` and/or `osgi-integration` tests. +If multiple Apache Cassandra instances are necessary then test cases should be added to the `standalone-integration` tests. If HTTP related functionality is changed then `ecchronos-binary` test cases should be changed. ## Running the tests @@ -30,10 +30,8 @@ The docker command must be runnable without *sudo* for the user running the test ### Integration tests -The integration tests tries to start ecChronos with a cluster of nodes and verfiy that repairs are run. -They are activated by using `-P osgi-integration-tests` or `-P standalone-integration-tests`. -It is possible to run either OSGi integration tests or the standalone tests without the other. -This can be done by running either `mvn clean install -P docker-integration-test,osgi-integration-tests` or `mvn clean install -P docker-integration-test,standalone-integration-tests`. +The integration tests tries to start ecChronos with a cluster of nodes and verify that repairs are run. +It is activated by using `-P standalone-integration-tests`. ### Acceptance tests @@ -73,17 +71,12 @@ Standalone integration tests mvn clean install -P local-standalone-integration-tests ``` -OSGi integration tests -``` -mvn clean install -P local-osgi-integration-tests -``` - All the above in one property. ``` mvn clean install -Dlocalprecommit.tests ``` -### Running acceptance tests towards local ecChronos&Cassandra +### Running acceptance tests towards local ecChronos & Cassandra For development, it's much faster to run behave tests without needing to do the ecChronos/Cassandra setup each time. Running behave tests manually is roughly 7x faster than running through `python-integration-tests`. @@ -207,4 +200,3 @@ The test cases needs to be run with the following system properties set: ### Break down into end to end tests The `standalone-integration` tests runs a setup similar to the standalone application to verify automated repairs. -The `osgi-integration` tests runs in a OSGi environment to verify that all services are available and verifies automated repairs. \ No newline at end of file diff --git a/karaf-feature/pom.xml b/karaf-feature/pom.xml deleted file mode 100644 index 49921bcfa..000000000 --- a/karaf-feature/pom.xml +++ /dev/null @@ -1,176 +0,0 @@ - - - - 4.0.0 - - com.ericsson.bss.cassandra.ecchronos - parent - 4.0.7-SNAPSHOT - - karaf-feature - feature - Utility module creating a feature file for OSGi - EcChronos Karaf Feature - - - - com.ericsson.bss.cassandra.ecchronos - fm - ${project.version} - - - - com.ericsson.bss.cassandra.ecchronos - connection - ${project.version} - - - - com.ericsson.bss.cassandra.ecchronos - core - ${project.version} - - - ch.qos.logback - logback-classic - - - ch.qos.logback - logback-core - - - - - - com.ericsson.bss.cassandra.ecchronos - core.osgi - ${project.version} - - - - - io.netty - netty-common - - - - io.netty - netty-transport - - - - io.netty - netty-resolver - - - - io.netty - netty-buffer - - - - io.netty - netty-handler - - - - io.netty - netty-codec - - - - - io.micrometer - micrometer-core - - - io.dropwizard.metrics - metrics-core - - - - - com.datastax.oss - java-driver-core - - - - com.datastax.oss - java-driver-query-builder - - - - com.google.guava - guava - - - - com.datastax.oss - native-protocol - - - - com.datastax.oss - java-driver-shaded-guava - - - - com.typesafe - config - - - - org.hdrhistogram - HdrHistogram - - - - com.fasterxml.jackson.core - jackson-core - - - - com.fasterxml.jackson.core - jackson-annotations - - - - com.fasterxml.jackson.core - jackson-databind - - - - jakarta.validation - jakarta.validation-api - - - - - - - org.apache.karaf.tooling - karaf-maven-plugin - true - - false - false - - - - - diff --git a/karaf-feature/src/main/feature/feature.xml b/karaf-feature/src/main/feature/feature.xml deleted file mode 100644 index 80e35c8bb..000000000 --- a/karaf-feature/src/main/feature/feature.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - wrap -
Utility module creating a feature file for OSGi
- mvn:com.ericsson.bss.cassandra.ecchronos/fm/${project.version} - mvn:com.ericsson.bss.cassandra.ecchronos/connection/${project.version} - mvn:com.ericsson.bss.cassandra.ecchronos/core/${project.version} - mvn:com.ericsson.bss.cassandra.ecchronos/core.osgi/${project.version} - mvn:io.netty/netty-common/${io.netty.version} - mvn:io.netty/netty-transport/${io.netty.version} - mvn:io.netty/netty-buffer/${io.netty.version} - mvn:io.netty/netty-handler/${io.netty.version} - mvn:io.netty/netty-codec/${io.netty.version} - mvn:io.netty/netty-resolver/${io.netty.version} - wrap:mvn:io.micrometer/micrometer-core/${io.micrometer.version} - mvn:io.dropwizard.metrics/metrics-core/${io.dropwizard.metrics.version} - mvn:com.datastax.oss/java-driver-core/${cassandra.driver.core.version} - mvn:com.datastax.oss/java-driver-query-builder/${cassandra.driver.core.version} - mvn:com.google.guava/guava/${guava.version} - mvn:com.datastax.oss/native-protocol/${cassandra.driver.protocol.version} - mvn:com.datastax.oss/java-driver-shaded-guava/${cassandra.driver.shaded.guava.version} - mvn:com.typesafe/config/${com.typesafe.config.version} - mvn:org.hdrhistogram/HdrHistogram/${org.hdrhistogram.version} - mvn:com.fasterxml.jackson.core/jackson-core/${com.fasterxml.jackson.version} - mvn:com.fasterxml.jackson.core/jackson-annotations/${com.fasterxml.jackson.version} - mvn:com.fasterxml.jackson.core/jackson-databind/${com.fasterxml.jackson.version} - mvn:jakarta.validation/jakarta.validation-api/${jakarta.validation-api.version} -
-
diff --git a/osgi-integration/pom.xml b/osgi-integration/pom.xml deleted file mode 100644 index 7ee1a5724..000000000 --- a/osgi-integration/pom.xml +++ /dev/null @@ -1,251 +0,0 @@ - - - - 4.0.0 - - parent - com.ericsson.bss.cassandra.ecchronos - 4.0.7-SNAPSHOT - - osgi-integration - Integration tests for an OSGi environment - EcChronos OSGi Integration - - - - - com.ericsson.bss.cassandra.ecchronos - karaf-feature - ${project.version} - test - features - xml - - - - com.ericsson.bss.cassandra.ecchronos - connection.impl - ${project.version} - test - - - - com.ericsson.bss.cassandra.ecchronos - fm.impl - ${project.version} - test - - - - - org.ops4j.pax.exam - pax-exam-container-karaf - test - - - - org.ops4j.pax.exam - pax-exam-cm - test - - - - org.ops4j.pax.exam - pax-exam-junit4 - test - - - - - org.apache.karaf - apache-karaf - test - zip - - - - org.apache.karaf.features - standard - test - features - xml - - - - org.apache.felix - org.apache.felix.scr - test - - - - javax.inject - javax.inject - test - - - - - org.junit.vintage - junit-vintage-engine - test - - - - org.awaitility - awaitility - test - - - - org.assertj - assertj-core - test - - - - - - - - precommit.tests - - - osgi-integration-tests - - - - org.apache.servicemix.tooling - depends-maven-plugin - - - generate-depends-file - - generate-depends-file - - - - - - - - maven-failsafe-plugin - - - - integration-test - verify - - - - - - - - io.fabric8 - docker-maven-plugin - - - - - - - - localprecommit.tests - - - local-osgi-integration-tests - - - - org.apache.servicemix.tooling - depends-maven-plugin - - - generate-depends-file - - generate-depends-file - - - - - - - - maven-failsafe-plugin - - - 127.0.0.1 - 7100 - 9042 - true - - - - - - integration-test - verify - - - - - - - - - - - - - org.apache.servicemix.tooling - depends-maven-plugin - - - generate-depends-file - - generate-depends-file - - - - - - - maven-compiler-plugin - - 1.8 - 1.8 - ${project.build.directory}/generated-sources/ - - - - - maven-deploy-plugin - - true - - - - - maven-install-plugin - - true - - - - - diff --git a/osgi-integration/src/test/java/com/ericsson/bss/cassandra/ecchronos/osgi/ITTableRepairJob.java b/osgi-integration/src/test/java/com/ericsson/bss/cassandra/ecchronos/osgi/ITTableRepairJob.java deleted file mode 100644 index 870348507..000000000 --- a/osgi-integration/src/test/java/com/ericsson/bss/cassandra/ecchronos/osgi/ITTableRepairJob.java +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Copyright 2018 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. - */ -package com.ericsson.bss.cassandra.ecchronos.osgi; - -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.CqlSessionBuilder; -import com.datastax.oss.driver.api.core.cql.AsyncResultSet; -import com.datastax.oss.driver.api.core.cql.SimpleStatement; -import com.datastax.oss.driver.api.core.metadata.Metadata; -import com.datastax.oss.driver.api.core.metadata.Node; -import com.datastax.oss.driver.api.core.metadata.token.TokenRange; -import com.datastax.oss.driver.api.core.uuid.Uuids; -import com.datastax.oss.driver.api.querybuilder.QueryBuilder; -import com.datastax.oss.driver.internal.core.metadata.token.Murmur3Token; -import com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures; -import com.ericsson.bss.cassandra.ecchronos.connection.NativeConnectionProvider; -import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairConfiguration; -import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairScheduler; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.RepairEntry; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.RepairHistoryProvider; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.RepairStatus; -import com.ericsson.bss.cassandra.ecchronos.core.utils.LongTokenRange; -import com.ericsson.bss.cassandra.ecchronos.core.utils.DriverNode; -import com.ericsson.bss.cassandra.ecchronos.core.utils.NodeResolver; -import com.ericsson.bss.cassandra.ecchronos.core.utils.TableReference; -import com.ericsson.bss.cassandra.ecchronos.core.utils.TableReferenceFactory; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.ops4j.pax.exam.Configuration; -import org.ops4j.pax.exam.Option; -import org.ops4j.pax.exam.OptionUtils; -import org.ops4j.pax.exam.cm.ConfigurationAdminOptions; -import org.ops4j.pax.exam.junit.PaxExam; -import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; -import org.ops4j.pax.exam.spi.reactors.PerClass; - -import javax.inject.Inject; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.time.Instant; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.OptionalLong; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.literal; -import static org.assertj.core.api.Assertions.assertThat; -import static org.awaitility.Awaitility.await; - -@RunWith(PaxExam.class) -@ExamReactorStrategy(PerClass.class) -public class ITTableRepairJob extends TestBase -{ - private static final String REPAIR_CONFIGURATION_PID = "com.ericsson.bss.cassandra.ecchronos.core.osgi.DefaultRepairConfigurationProviderComponent"; - private static final String SCHEDULE_MANAGER_PID = "com.ericsson.bss.cassandra.ecchronos.core.osgi.ScheduleManagerService"; - - private static final String CONFIGURATION_ENABLED = "enabled"; - private static final String CONFIGURATION_SCHEDULE_INTERVAL_IN_SECONDS = "scheduleIntervalInSeconds"; - - @Inject - NativeConnectionProvider myNativeConnectionProvider; - - @Inject - TableReferenceFactory myTableReferenceFactory; - - @Inject - RepairScheduler myRepairScheduler; - - @Inject - NodeResolver myNodeResolver; - - @Inject - RepairHistoryProvider myRepairHistoryProvider; - - private static CqlSession myAdminSession; - - private Metadata myMetadata; - private Node myLocalHost; - private DriverNode myLocalNode; - - private Set myRepairs = new HashSet<>(); - - private RepairConfiguration myRepairConfiguration; - - @Configuration - public Option[] configure() throws IOException - { - return OptionUtils.combine(basicOptions(), scheduleManagerOptions(), repairSchedulerOptions()); - } - - @BeforeClass - public static void setupAdminSession() - { - CqlSessionBuilder builder = CqlSession.builder() - .addContactPoint(new InetSocketAddress(CASSANDRA_HOST, Integer.parseInt(CASSANDRA_NATIVE_PORT))) - .withLocalDatacenter("datacenter1"); - if (IS_LOCAL == null) - { - builder.withAuthCredentials("cassandra", "cassandra"); - } - myAdminSession = builder.build(); - } - - @Before - public void init() - { - CqlSession session = myNativeConnectionProvider.getSession(); - myMetadata = session.getMetadata(); - myLocalHost = myNativeConnectionProvider.getLocalNode(); - - myLocalNode = myNodeResolver.fromUUID(myLocalHost.getHostId()).orElseThrow(IllegalStateException::new); - - myRepairConfiguration = RepairConfiguration.newBuilder() - .withRepairInterval(1, TimeUnit.HOURS) - .build(); - } - - @After - public void clean() - { - List> stages = new ArrayList<>(); - for (TableReference tableReference : myRepairs) - { - myRepairScheduler.removeConfiguration(tableReference); - - stages.add(myAdminSession.executeAsync( - QueryBuilder.deleteFrom("system_distributed", "repair_history") - .whereColumn("keyspace_name").isEqualTo(literal(tableReference.getKeyspace())) - .whereColumn("columnfamily_name").isEqualTo(literal(tableReference.getTable())) - .build())); - for (Node node : myMetadata.getNodes().values()) - { - stages.add(myAdminSession.executeAsync(QueryBuilder.deleteFrom("ecchronos", "repair_history") - .whereColumn("table_id").isEqualTo(literal(tableReference.getId())) - .whereColumn("node_id").isEqualTo(literal(node.getHostId())) - .build())); - } - } - - for (CompletionStage stage : stages) - { - CompletableFutures.getUninterruptibly(stage); - } - } - - @AfterClass - public static void shutdownAdminSession() - { - myAdminSession.close(); - } - - /** - * Create a table that is replicated and was repaired two hours ago. - * - * The repair factory should detect the new table automatically and schedule it to run. - */ - @Test - public void repairSingleTable() - { - long startTime = System.currentTimeMillis(); - - TableReference tableReference = myTableReferenceFactory.forTable("test", "table1"); - - injectRepairHistory(tableReference, System.currentTimeMillis() - TimeUnit.HOURS.toMillis(2)); - - schedule(tableReference); - - await().pollInterval(1, TimeUnit.SECONDS).atMost(90, TimeUnit.SECONDS) - .until(() -> isRepairedSince(tableReference, startTime)); - - verifyTableRepairedSince(tableReference, startTime); - } - - /** - * Create two tables that are replicated and was repaired two and four hours ago. - * - * The repair factory should detect the new tables automatically and schedule them to run. - */ - @Test - public void repairMultipleTables() - { - long startTime = System.currentTimeMillis(); - - TableReference tableReference = myTableReferenceFactory.forTable("test", "table1"); - TableReference tableReference2 = myTableReferenceFactory.forTable("test", "table2"); - - injectRepairHistory(tableReference, System.currentTimeMillis() - TimeUnit.HOURS.toMillis(2)); - injectRepairHistory(tableReference2, System.currentTimeMillis() - TimeUnit.HOURS.toMillis(4)); - - schedule(tableReference); - schedule(tableReference2); - - await().pollInterval(1, TimeUnit.SECONDS).atMost(90, TimeUnit.SECONDS) - .until(() -> isRepairedSince(tableReference, startTime)); - await().pollInterval(1, TimeUnit.SECONDS).atMost(90, TimeUnit.SECONDS) - .until(() -> isRepairedSince(tableReference2, startTime)); - - verifyTableRepairedSince(tableReference, startTime); - verifyTableRepairedSince(tableReference2, startTime); - } - - /** - * Create a table that is replicated and was fully repaired two hours ago. - * - * It was also partially repaired by another node. - * - * The repair factory should detect the table automatically and schedule it to run on the ranges that were not - * repaired. - */ - @Test - public void partialTableRepair() - { - long startTime = System.currentTimeMillis(); - long expectedRepairedInterval = startTime - TimeUnit.HOURS.toMillis(1); - - TableReference tableReference = myTableReferenceFactory.forTable("test", "table1"); - - injectRepairHistory(tableReference, System.currentTimeMillis() - TimeUnit.HOURS.toMillis(2)); - - Set expectedRepairedBefore = halfOfTokenRanges(tableReference); - injectRepairHistory(tableReference, System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(30), - expectedRepairedBefore); - - Set allTokenRanges = myMetadata.getTokenMap().get() - .getTokenRanges(tableReference.getKeyspace(), myLocalHost); - Set expectedRepairedRanges = Sets.difference(convertTokenRanges(allTokenRanges), - convertTokenRanges(expectedRepairedBefore)); - - schedule(tableReference); - - await().pollInterval(1, TimeUnit.SECONDS).atMost(90, TimeUnit.SECONDS) - .until(() -> isRepairedSince(tableReference, startTime, expectedRepairedRanges)); - - verifyTableRepairedSince(tableReference, expectedRepairedInterval); - } - - private void schedule(TableReference tableReference) - { - if (myRepairs.add(tableReference)) - { - myRepairScheduler.putConfiguration(tableReference, myRepairConfiguration); - } - } - - private void verifyTableRepairedSince(TableReference tableReference, long repairedSince) - { - OptionalLong repairedAt = lastRepairedSince(tableReference, repairedSince, - tokenRangesFor(tableReference.getKeyspace())); - assertThat(repairedAt).isPresent(); - } - - private boolean isRepairedSince(TableReference tableReference, long repairedSince) - { - return lastRepairedSince(tableReference, repairedSince).isPresent(); - } - - private boolean isRepairedSince(TableReference tableReference, long repairedSince, - Set expectedRepaired) - { - return lastRepairedSince(tableReference, repairedSince, expectedRepaired).isPresent(); - } - - private OptionalLong lastRepairedSince(TableReference tableReference, long repairedSince) - { - return lastRepairedSince(tableReference, repairedSince, tokenRangesFor(tableReference.getKeyspace())); - } - - private OptionalLong lastRepairedSince(TableReference tableReference, long repairedSince, - Set expectedRepaired) - { - Set expectedRepairedCopy = new HashSet<>(expectedRepaired); - Iterator repairEntryIterator = myRepairHistoryProvider.iterate(tableReference, - System.currentTimeMillis(), repairedSince, - repairEntry -> fullyRepaired(repairEntry) && expectedRepairedCopy.remove(repairEntry.getRange())); - - List repairEntries = Lists.newArrayList(repairEntryIterator); - - Set actuallyRepaired = repairEntries.stream() - .map(RepairEntry::getRange) - .collect(Collectors.toSet()); - - if (expectedRepaired.equals(actuallyRepaired)) - { - return repairEntries.stream().mapToLong(RepairEntry::getStartedAt).min(); - } - else - { - return OptionalLong.empty(); - } - } - - private Set tokenRangesFor(String keyspace) - { - return myMetadata.getTokenMap().get().getTokenRanges(keyspace, myLocalHost).stream() - .map(this::convertTokenRange) - .collect(Collectors.toSet()); - } - - private boolean fullyRepaired(RepairEntry repairEntry) - { - return repairEntry.getParticipants().size() == 3 && repairEntry.getStatus() == RepairStatus.SUCCESS; - } - - private void injectRepairHistory(TableReference tableReference, long timestampMax) - { - injectRepairHistory(tableReference, timestampMax, - myMetadata.getTokenMap().get().getTokenRanges(tableReference.getKeyspace(), myLocalHost)); - } - - private void injectRepairHistory(TableReference tableReference, long timestampMax, Set tokenRanges) - { - long timestamp = timestampMax - 1; - - for (TokenRange tokenRange : tokenRanges) - { - injectRepairHistory(tableReference, timestamp, tokenRange); - - timestamp--; - } - } - - private void injectRepairHistory(TableReference tableReference, long timestamp, TokenRange tokenRange) - { - long started_at = timestamp; - long finished_at = timestamp + 5; - - Set participants = myMetadata.getTokenMap().get().getReplicas(tableReference.getKeyspace(), tokenRange) - .stream() - .map(Node::getHostId) - .collect(Collectors.toSet()); - - SimpleStatement statement = QueryBuilder.insertInto("ecchronos", "repair_history") - .value("table_id", literal(tableReference.getId())) - .value("node_id", literal(myLocalNode.getId())) - .value("repair_id", literal(Uuids.startOf(started_at))) - .value("job_id", literal(tableReference.getId())) - .value("coordinator_id", literal(myLocalNode.getId())) - .value("range_begin", literal(Long.toString(((Murmur3Token) tokenRange.getStart()).getValue()))) - .value("range_end", literal(Long.toString(((Murmur3Token) tokenRange.getEnd()).getValue()))) - .value("participants", literal(participants)) - .value("status", literal("SUCCESS")) - .value("started_at", literal(Instant.ofEpochMilli(started_at))) - .value("finished_at", literal(Instant.ofEpochMilli(finished_at))).build(); - - myAdminSession.execute(statement); - } - - private Set halfOfTokenRanges(TableReference tableReference) - { - Set halfOfRanges = new HashSet<>(); - Set allTokenRanges = myMetadata.getTokenMap().get() - .getTokenRanges(tableReference.getKeyspace(), myLocalHost); - Iterator iterator = allTokenRanges.iterator(); - for (int i = 0; i < allTokenRanges.size() / 2 && iterator.hasNext(); i++) - { - halfOfRanges.add(iterator.next()); - } - - return halfOfRanges; - } - - private Set convertTokenRanges(Set tokenRanges) - { - return tokenRanges.stream().map(this::convertTokenRange).collect(Collectors.toSet()); - } - - private LongTokenRange convertTokenRange(TokenRange range) - { - // Assuming murmur3 partitioner - long start = ((Murmur3Token) range.getStart()).getValue(); - long end = ((Murmur3Token) range.getEnd()).getValue(); - return new LongTokenRange(start, end); - } - - private Option repairSchedulerOptions() - { - return ConfigurationAdminOptions.newConfiguration(REPAIR_CONFIGURATION_PID) - .put(CONFIGURATION_ENABLED, false) - .asOption(); - } - - private Option scheduleManagerOptions() - { - return ConfigurationAdminOptions.newConfiguration(SCHEDULE_MANAGER_PID) - .put(CONFIGURATION_SCHEDULE_INTERVAL_IN_SECONDS, 1L) - .asOption(); - } -} diff --git a/osgi-integration/src/test/java/com/ericsson/bss/cassandra/ecchronos/osgi/ITTestECChronos.java b/osgi-integration/src/test/java/com/ericsson/bss/cassandra/ecchronos/osgi/ITTestECChronos.java deleted file mode 100644 index a52149a8f..000000000 --- a/osgi-integration/src/test/java/com/ericsson/bss/cassandra/ecchronos/osgi/ITTestECChronos.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright 2018 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. - */ -package com.ericsson.bss.cassandra.ecchronos.osgi; - -import com.ericsson.bss.cassandra.ecchronos.connection.JmxConnectionProvider; -import com.ericsson.bss.cassandra.ecchronos.connection.NativeConnectionProvider; -import com.ericsson.bss.cassandra.ecchronos.core.HostStates; -import com.ericsson.bss.cassandra.ecchronos.core.JmxProxyFactory; -import com.ericsson.bss.cassandra.ecchronos.core.TableStorageStates; -import com.ericsson.bss.cassandra.ecchronos.core.metrics.TableRepairMetrics; -import com.ericsson.bss.cassandra.ecchronos.core.osgi.DefaultRepairConfigurationProviderComponent; -import com.ericsson.bss.cassandra.ecchronos.core.osgi.ReplicationStateService; -import com.ericsson.bss.cassandra.ecchronos.core.osgi.ScheduleManagerService; -import com.ericsson.bss.cassandra.ecchronos.core.osgi.TimeBasedRunPolicyService; -import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairScheduler; -import com.ericsson.bss.cassandra.ecchronos.core.repair.state.RepairStateFactory; -import com.ericsson.bss.cassandra.ecchronos.core.scheduling.LockFactory; -import com.ericsson.bss.cassandra.ecchronos.core.utils.NodeResolver; -import com.ericsson.bss.cassandra.ecchronos.core.utils.ReplicatedTableProvider; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.ops4j.pax.exam.Configuration; -import org.ops4j.pax.exam.Option; -import org.ops4j.pax.exam.junit.PaxExam; -import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; -import org.ops4j.pax.exam.spi.reactors.PerClass; -import org.osgi.framework.BundleContext; -import org.osgi.service.component.runtime.ServiceComponentRuntime; -import org.osgi.service.component.runtime.dto.ComponentDescriptionDTO; -import org.osgi.util.tracker.ServiceTracker; - -import javax.inject.Inject; -import java.io.IOException; -import java.util.concurrent.TimeUnit; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; - -@RunWith(PaxExam.class) -@ExamReactorStrategy(PerClass.class) -public class ITTestECChronos extends TestBase -{ - private static final String SCHEDULE_MANAGER_PID = "com.ericsson.bss.cassandra.ecchronos.core.osgi.ScheduleManagerService"; - - private static final String TIME_BASED_RUN_POLICY_PID = "com.ericsson.bss.cassandra.ecchronos.core.osgi.TimeBasedRunPolicyService"; - private static final String REPAIR_CONFIGURATION_PID = "com.ericsson.bss.cassandra.ecchronos.core.osgi.DefaultRepairConfigurationProviderComponent"; - private static final String REPLICATION_STATE_PID = "com.ericsson.bss.cassandra.ecchronos.core.osgi.ReplicationStateService"; - - @Inject - BundleContext myBundleContext; - - @Inject - ServiceComponentRuntime myScrService; - - @Configuration - public Option[] configure() throws IOException - { - return basicOptions(); - } - - @Before - public void verifyConfiguration() throws InterruptedException - { - checkNativeConnection(); - checkJmxConnection(); - } - - @Test - public void testGetLockFactoryService() throws InterruptedException - { - ServiceTracker serviceTracker = new ServiceTracker(myBundleContext, LockFactory.class, null); - serviceTracker.open(); - - LockFactory lockFactory = (LockFactory) serviceTracker.waitForService(TimeUnit.SECONDS.toMillis(10)); - serviceTracker.close(); - - assertThat(lockFactory).isNotNull(); - } - - @Test - public void testGetHostStatesService() throws InterruptedException - { - ServiceTracker serviceTracker = new ServiceTracker(myBundleContext, HostStates.class, null); - serviceTracker.open(); - - HostStates hostStates = (HostStates) serviceTracker.waitForService(TimeUnit.SECONDS.toMillis(10)); - serviceTracker.close(); - - assertThat(hostStates).isNotNull(); - } - - @Test - public void testGetJmxProxyFactoryService() throws InterruptedException - { - ServiceTracker serviceTracker = new ServiceTracker(myBundleContext, JmxProxyFactory.class, null); - serviceTracker.open(); - JmxProxyFactory jmxProxyFactory = (JmxProxyFactory) serviceTracker.waitForService(10000); - serviceTracker.close(); - - assertThat(jmxProxyFactory).isNotNull(); - } - - @Test - public void testGetReplicatedTableProviderService() throws InterruptedException - { - ServiceTracker serviceTracker = new ServiceTracker(myBundleContext, ReplicatedTableProvider.class, null); - serviceTracker.open(); - ReplicatedTableProvider replicatedTableProvider = (ReplicatedTableProvider) serviceTracker.waitForService(10000); - serviceTracker.close(); - - assertThat(replicatedTableProvider).isNotNull(); - } - - @Test - public void testGetTableStorageStatesService() throws InterruptedException - { - ServiceTracker serviceTracker = new ServiceTracker(myBundleContext, TableStorageStates.class, null); - serviceTracker.open(); - - TableStorageStates tableStorageStates = (TableStorageStates) serviceTracker.waitForService(TimeUnit.SECONDS.toMillis(10)); - serviceTracker.close(); - - assertThat(tableStorageStates).isNotNull(); - } - - @Test - public void testGetTableRepairMetricsService() throws InterruptedException - { - ServiceTracker serviceTracker = new ServiceTracker(myBundleContext, TableRepairMetrics.class, null); - serviceTracker.open(); - - TableRepairMetrics tableRepairMetrics = (TableRepairMetrics) serviceTracker.waitForService(TimeUnit.SECONDS.toMillis(10)); - serviceTracker.close(); - - assertThat(tableRepairMetrics).isNotNull(); - } - - @Test - public void testGetRepairStateFactoryService() throws InterruptedException - { - ServiceTracker serviceTracker = new ServiceTracker(myBundleContext, RepairStateFactory.class, null); - serviceTracker.open(); - - RepairStateFactory repairStateFactory = (RepairStateFactory) serviceTracker.waitForService(TimeUnit.SECONDS.toMillis(10)); - serviceTracker.close(); - - assertThat(repairStateFactory).isNotNull(); - } - - @Test - public void testGetRepairSchedulerService() throws InterruptedException - { - ServiceTracker serviceTracker = new ServiceTracker(myBundleContext, RepairScheduler.class, null); - serviceTracker.open(); - - RepairScheduler repairScheduler = (RepairScheduler) serviceTracker.waitForService(TimeUnit.SECONDS.toMillis(10)); - serviceTracker.close(); - - assertThat(repairScheduler).isNotNull(); - } - - @Test - public void testGetNodeResolverService() throws InterruptedException - { - ServiceTracker serviceTracker = new ServiceTracker(myBundleContext, NodeResolver.class, null); - serviceTracker.open(); - - NodeResolver nodeResolver = (NodeResolver) serviceTracker.waitForService(TimeUnit.SECONDS.toMillis(10)); - serviceTracker.close(); - - assertThat(nodeResolver).isNotNull(); - } - - @Test - public void testGetScheduleManagerComponent() - { - assertComponentIsActive(SCHEDULE_MANAGER_PID, ScheduleManagerService.class); - } - - @Test - public void testGetTimeBasedRunPolicyComponent() - { - assertComponentIsActive(TIME_BASED_RUN_POLICY_PID, TimeBasedRunPolicyService.class); - } - - @Test - public void testGetRepairConfigurationComponent() - { - assertComponentIsActive(REPAIR_CONFIGURATION_PID, DefaultRepairConfigurationProviderComponent.class); - } - - @Test - public void testGetReplicationStateComponent() - { - assertComponentIsActive(REPLICATION_STATE_PID, ReplicationStateService.class); - } - - private void assertComponentIsActive(String pid, Class clazz) - { - for (ComponentDescriptionDTO desc : myScrService.getComponentDescriptionDTOs()) - { - if (clazz.getCanonicalName().equals(desc.implementationClass)) - { - assertThat(desc.configurationPid).contains(pid); - assertThat(myScrService.isComponentEnabled(desc)).isTrue(); - - return; - } - } - fail(); - } - - private void checkNativeConnection() throws InterruptedException - { - ServiceTracker serviceTracker = new ServiceTracker(myBundleContext, NativeConnectionProvider.class, null); - serviceTracker.open(); - - NativeConnectionProvider nativeConnectionProvider = (NativeConnectionProvider) serviceTracker.waitForService(10000); - if (nativeConnectionProvider == null) - { - throw new IllegalStateException("Native Connection provider not started"); - } - serviceTracker.close(); - } - - private void checkJmxConnection() throws InterruptedException - { - ServiceTracker serviceTracker = new ServiceTracker(myBundleContext, JmxConnectionProvider.class, null); - serviceTracker.open(); - JmxConnectionProvider jmxConnectionProvider = (JmxConnectionProvider) serviceTracker.waitForService(10000); - if (jmxConnectionProvider == null) - { - throw new IllegalStateException("JMX Connection provider not started"); - } - serviceTracker.close(); - } -} diff --git a/osgi-integration/src/test/java/com/ericsson/bss/cassandra/ecchronos/osgi/TestBase.java b/osgi-integration/src/test/java/com/ericsson/bss/cassandra/ecchronos/osgi/TestBase.java deleted file mode 100644 index 581231f59..000000000 --- a/osgi-integration/src/test/java/com/ericsson/bss/cassandra/ecchronos/osgi/TestBase.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2018 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. - */ -package com.ericsson.bss.cassandra.ecchronos.osgi; - -import org.ops4j.pax.exam.Option; -import org.ops4j.pax.exam.cm.ConfigurationAdminOptions; -import org.ops4j.pax.exam.cm.ConfigurationOption; -import org.ops4j.pax.exam.karaf.options.LogLevelOption; -import org.ops4j.pax.exam.options.MavenUrlReference; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.nio.file.Files; - -import static org.ops4j.pax.exam.CoreOptions.*; -import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole; -import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut; -import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.features; -import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration; -import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder; -import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.logLevel; - -public class TestBase -{ - protected static final String CASSANDRA_HOST_PROPERTY = "it-cassandra.ip"; - protected static final String CASSANDRA_NATIVE_PORT_PROPERTY = "it-cassandra.native.port"; - protected static final String CASSANDRA_JMX_PORT_PROPERTY = "it-cassandra.jmx.port"; - - protected static final String CASSANDRA_HOST = System.getProperty(CASSANDRA_HOST_PROPERTY); - protected static final String CASSANDRA_NATIVE_PORT = System.getProperty(CASSANDRA_NATIVE_PORT_PROPERTY); - protected static final String CASSANDRA_JMX_PORT = System.getProperty(CASSANDRA_JMX_PORT_PROPERTY); - protected static final String IS_LOCAL = System.getProperty("it-local-cassandra"); - - protected static final String REPAIR_METRICS_PID = "com.ericsson.bss.cassandra.ecchronos.core.osgi.TableRepairMetricsService"; - - protected static final String NATIVE_CONNECTION_PID = "com.ericsson.bss.cassandra.ecchronos.connection.impl.OSGiLocalNativeConnectionProvider"; - protected static final String JMX_CONNECTION_PID = "com.ericsson.bss.cassandra.ecchronos.connection.impl.OSGiLocalJmxConnectionProvider"; - - protected static final String CONFIGURATION_NATIVE_HOST = "localHost"; - protected static final String CONFIGURATION_NATIVE_PORT = "nativePort"; - protected static final String CONFIGURATION_JMX_HOST = "jmxHost"; - protected static final String CONFIGURATION_JMX_PORT = "jmxPort"; - - protected static final String CONFIGURATION_CREDENTIALS_FILE = "credentialsFile"; - - protected static final String CONFIGURATION_STATISTICS_DIRECTORY = "metricsDirectory"; - - private static final File topDirectory = new File("target", "exam"); - - public Option[] basicOptions() throws IOException - { - MavenUrlReference karafArtifactUrl = maven() - .groupId("org.apache.karaf") - .artifactId("apache-karaf") - .versionAsInProject() - .type("zip"); - - MavenUrlReference karafStandardUrl = maven() - .groupId("org.apache.karaf.features") - .artifactId("standard") - .versionAsInProject() - .classifier("features") - .type("xml"); - - MavenUrlReference ecChronosKarafFeaturesMvnUrl = maven() - .groupId("com.ericsson.bss.cassandra.ecchronos") - .artifactId("karaf-feature") - .type("xml") - .classifier("features") - .versionAsInProject(); - - return options( - karafDistributionConfiguration() - .frameworkUrl(karafArtifactUrl) - .unpackDirectory(topDirectory) - .useDeployFolder(false), - logLevel(LogLevelOption.LogLevel.INFO), - features(karafStandardUrl, "scr", "standard"), - editConfigurationFilePut("etc/org.apache.karaf.shell.cfg", "sshHost", "localhost"), - editConfigurationFilePut("etc/org.apache.karaf.shell.cfg", "sshPort", "8888"), - keepRuntimeFolder(), - configureConsole().ignoreLocalConsole(), - configureConsole().startRemoteShell(), - features(ecChronosKarafFeaturesMvnUrl, "karaf-feature"), - mavenBundle("com.ericsson.bss.cassandra.ecchronos", "connection.impl").versionAsInProject(), - mavenBundle("com.ericsson.bss.cassandra.ecchronos", "fm.impl").versionAsInProject(), - mavenBundle("org.assertj", "assertj-core").versionAsInProject(), - mavenBundle("org.awaitility", "awaitility").versionAsInProject(), - nativeConnectionOptions(), - jmxConnectionOptions(), - metricsOptions(), - junitBundles(), - propagateSystemProperties(CASSANDRA_HOST_PROPERTY, CASSANDRA_NATIVE_PORT_PROPERTY) - ); - } - - protected Option nativeConnectionOptions() - { - ConfigurationOption configurationOption = ConfigurationAdminOptions.newConfiguration(NATIVE_CONNECTION_PID) - .put(CONFIGURATION_NATIVE_HOST, CASSANDRA_HOST) - .put(CONFIGURATION_NATIVE_PORT, CASSANDRA_NATIVE_PORT); - - if (IS_LOCAL == null) - { - URL url = TestBase.class.getClassLoader().getResource("credentials.properties"); - - if (url != null) - { - configurationOption = configurationOption.put(CONFIGURATION_CREDENTIALS_FILE, url.getPath()); - } - } - - return configurationOption.asOption(); - } - - protected Option jmxConnectionOptions() - { - return ConfigurationAdminOptions.newConfiguration(JMX_CONNECTION_PID) - .put(CONFIGURATION_JMX_HOST, CASSANDRA_HOST) - .put(CONFIGURATION_JMX_PORT, CASSANDRA_JMX_PORT) - .asOption(); - } - - protected Option metricsOptions() throws IOException - { - File metricsDirectory = new File(topDirectory, "metrics").getAbsoluteFile(); - - if (!metricsDirectory.exists()) - { - Files.createDirectories(metricsDirectory.toPath()); - } - - return ConfigurationAdminOptions.newConfiguration(REPAIR_METRICS_PID) - .put(CONFIGURATION_STATISTICS_DIRECTORY, metricsDirectory.getAbsolutePath()) - .asOption(); - } -} diff --git a/osgi-integration/src/test/resources/credentials.properties b/osgi-integration/src/test/resources/credentials.properties deleted file mode 100644 index 321cc7192..000000000 --- a/osgi-integration/src/test/resources/credentials.properties +++ /dev/null @@ -1,2 +0,0 @@ -username=eccuser -password=eccpassword diff --git a/pom.xml b/pom.xml index 8a4635ea1..fd48092dd 100644 --- a/pom.xml +++ b/pom.xml @@ -39,17 +39,13 @@ fm core - core.osgi connection connection.impl fm.impl rest - rest.osgi application cassandra-test-image ecchronos-binary - karaf-feature - osgi-integration standalone-integration @@ -80,7 +76,6 @@ 4.13.1 1.8.4 - 4.3.8 2.1.14 2.4.7 1 @@ -111,7 +106,6 @@ 3.0 0.35.0 1.2 - 4.2.1 0.8.4 3.0.0 1.19 @@ -432,13 +426,6 @@ - - org.ops4j.pax.exam - pax-exam-container-karaf - ${pax-exam.version} - test - - org.ops4j.pax.exam pax-exam-cm @@ -453,29 +440,6 @@ test - - org.apache.karaf - apache-karaf - ${apache.karaf.version} - test - zip - - - - org.apache.karaf.features - standard - ${apache.karaf.version} - test - features - xml - - - - org.apache.karaf.shell - org.apache.karaf.shell.core - ${apache.karaf.version} - - org.apache.felix org.apache.felix.scr @@ -581,12 +545,6 @@ - - org.apache.karaf.tooling - karaf-maven-plugin - ${org.apache.karaf.tooling.karaf-maven-plugin.version} - - org.apache.felix maven-bundle-plugin diff --git a/rest.osgi/pom.xml b/rest.osgi/pom.xml deleted file mode 100644 index f1f1817f6..000000000 --- a/rest.osgi/pom.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - 4.0.0 - - - com.ericsson.bss.cassandra.ecchronos - parent - 4.0.7-SNAPSHOT - - bundle - rest.osgi - OSGi service wrappers for the REST classes - EcChronos REST OSGi - - - - - com.ericsson.bss.cassandra.ecchronos - rest - ${project.version} - - - - - org.osgi - org.osgi.service.component.annotations - provided - - - - org.osgi - org.osgi.service.metatype.annotations - provided - - - - - - - org.apache.felix - maven-bundle-plugin - - true - META-INF - - * - com.ericsson.bss.cassandra.ecchronos.rest.osgi.* - - - - - - diff --git a/rest.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/rest/osgi/RepairManagementRESTComponent.java b/rest.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/rest/osgi/RepairManagementRESTComponent.java deleted file mode 100644 index 023725283..000000000 --- a/rest.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/rest/osgi/RepairManagementRESTComponent.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2019 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. - */ -package com.ericsson.bss.cassandra.ecchronos.rest.osgi; - -import com.ericsson.bss.cassandra.ecchronos.core.repair.OnDemandRepairScheduler; -import com.ericsson.bss.cassandra.ecchronos.core.repair.RepairScheduler; -import com.ericsson.bss.cassandra.ecchronos.core.repair.types.OnDemandRepair; -import com.ericsson.bss.cassandra.ecchronos.core.repair.types.RepairInfo; -import com.ericsson.bss.cassandra.ecchronos.core.repair.types.Schedule; -import com.ericsson.bss.cassandra.ecchronos.core.utils.RepairStatsProvider; -import com.ericsson.bss.cassandra.ecchronos.core.utils.ReplicatedTableProvider; -import com.ericsson.bss.cassandra.ecchronos.core.utils.TableReferenceFactory; -import com.ericsson.bss.cassandra.ecchronos.rest.RepairManagementREST; -import com.ericsson.bss.cassandra.ecchronos.rest.RepairManagementRESTImpl; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; -import org.springframework.http.ResponseEntity; - -import java.time.Duration; -import java.util.List; - -/** - * OSGi component wrapping {@link RepairManagementREST} bound with OSGi services. - */ -@Component -public class RepairManagementRESTComponent implements RepairManagementREST -{ - @Reference (service = RepairScheduler.class, - cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile RepairScheduler myRepairScheduler; - - @Reference (service = OnDemandRepairScheduler.class, - cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile OnDemandRepairScheduler myOnDemandRepairScheduler; - - @Reference(service = TableReferenceFactory.class, - cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile TableReferenceFactory myTableReferenceFactory; - - @Reference(service = ReplicatedTableProvider.class, - cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile ReplicatedTableProvider myReplicatedTableProvider; - - @Reference(service = RepairStatsProvider.class, cardinality = ReferenceCardinality.MANDATORY, - policy = ReferencePolicy.STATIC) - private volatile RepairStatsProvider myRepairStatsProvider; - - private volatile RepairManagementRESTImpl myDelegateRESTImpl; - - @Activate - public final synchronized void activate() - { - myDelegateRESTImpl = new RepairManagementRESTImpl(myRepairScheduler, myOnDemandRepairScheduler, - myTableReferenceFactory, myReplicatedTableProvider, myRepairStatsProvider); - } - - @Override - public final ResponseEntity> getRepairs(final String keyspace, - final String table, - final String hostId) - { - return myDelegateRESTImpl.getRepairs(keyspace, table, hostId); - } - - @Override - public final ResponseEntity> getRepairs(final String id, final String hostId) - { - return myDelegateRESTImpl.getRepairs(id, hostId); - } - - @Override - public final ResponseEntity> getSchedules(final String keyspace, final String table) - { - return myDelegateRESTImpl.getSchedules(keyspace, table); - } - - @Override - public final ResponseEntity getSchedules(final String id, final boolean full) - { - return myDelegateRESTImpl.getSchedules(id, full); - } - - @Override - public final ResponseEntity> triggerRepair(final String keyspace, - final String table, - final boolean isLocal) - { - return myDelegateRESTImpl.triggerRepair(keyspace, table, isLocal); - } - - @Override - public final ResponseEntity getRepairInfo(final String keyspace, - final String table, - final Long since, - final Duration duration, - final boolean isLocal) - { - return myDelegateRESTImpl.getRepairInfo(keyspace, table, since, duration, isLocal); - } -} diff --git a/rest.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/rest/osgi/package-info.java b/rest.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/rest/osgi/package-info.java deleted file mode 100644 index 4473f468c..000000000 --- a/rest.osgi/src/main/java/com/ericsson/bss/cassandra/ecchronos/rest/osgi/package-info.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2019 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. - */ - -/** - * - */ -package com.ericsson.bss.cassandra.ecchronos.rest.osgi; From 758de82f4103a0ae5a9e2fd83fb64aaafdb781e6 Mon Sep 17 00:00:00 2001 From: Johan Andersson W <96044147+jwaeab@users.noreply.github.com> Date: Wed, 25 Sep 2024 06:38:56 +0200 Subject: [PATCH 2/2] Removes OSGI/Karaf support Closes #657 --- CHANGES.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 4ea081222..76e34a4df 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,9 @@ # Changes +## Version 4.0.7 + +* Removes OSGI/Karaf support - Issue #657 + ## Version 4.0.6 * Separate serial consistency configuration from remoteRouting functionality - Issue #633