build: remove orphan mysql r2dbc e2e module

This commit is contained in:
Logic
2026-08-26 17:37:08 +08:00
parent 2c5754302c
commit 60a682a223
5 changed files with 0 additions and 460 deletions
@@ -1,124 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.hertzbeat</groupId>
<artifactId>hertzbeat-e2e</artifactId>
<version>2.0-SNAPSHOT</version>
</parent>
<artifactId>hertzbeat-collector-mysql-r2dbc-e2e</artifactId>
<properties>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mysql.r2dbc.reactor.bom.version>2024.0.3</mysql.r2dbc.reactor.bom.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-bom</artifactId>
<version>${mysql.r2dbc.reactor.bom.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.hertzbeat</groupId>
<artifactId>hertzbeat-startup</artifactId>
<version>${hertzbeat.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.hertzbeat</groupId>
<artifactId>hertzbeat-collector-common-e2e</artifactId>
<version>${hertzbeat.version}</version>
<scope>test</scope>
<type>test-jar</type>
</dependency>
<dependency>
<groupId>org.apache.hertzbeat</groupId>
<artifactId>hertzbeat-collector-basic</artifactId>
<version>${hertzbeat.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.hertzbeat</groupId>
<artifactId>hertzbeat-collector-common</artifactId>
<version>${hertzbeat.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.hertzbeat</groupId>
<artifactId>hertzbeat-collector-collector</artifactId>
<version>${hertzbeat.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor.netty</groupId>
<artifactId>reactor-netty-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers-mysql</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<!-- Force Reactor Netty onto the portable NIO path in this E2E so startup's WebFlux stack
cannot pull the test onto a macOS-native transport variant. -->
<reactor.netty.native>false</reactor.netty.native>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</project>
@@ -1,233 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.collector.collect.mysql;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.hertzbeat.collector.collect.AbstractCollectE2eTest;
import org.apache.hertzbeat.collector.collect.database.JdbcCommonCollect;
import org.apache.hertzbeat.collector.collect.database.mysql.MysqlCollectorProperties;
import org.apache.hertzbeat.collector.collect.database.mysql.MysqlJdbcDriverAvailability;
import org.apache.hertzbeat.collector.collect.database.mysql.MysqlR2dbcJdbcQueryExecutor;
import org.apache.hertzbeat.collector.mysql.r2dbc.MysqlR2dbcConnectionFactoryProvider;
import org.apache.hertzbeat.collector.mysql.r2dbc.MysqlR2dbcQueryExecutor;
import org.apache.hertzbeat.collector.mysql.r2dbc.ResultSetMapper;
import org.apache.hertzbeat.collector.mysql.r2dbc.SqlGuard;
import org.apache.hertzbeat.collector.util.CollectUtil;
import org.apache.hertzbeat.common.entity.job.Configmap;
import org.apache.hertzbeat.common.entity.job.Job;
import org.apache.hertzbeat.common.entity.job.Metrics;
import org.apache.hertzbeat.common.entity.job.protocol.JdbcProtocol;
import org.apache.hertzbeat.common.entity.job.protocol.Protocol;
import org.apache.hertzbeat.common.entity.message.CollectRep;
import org.junit.jupiter.api.Assertions;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.utility.DockerImageName;
/**
* Shared MySQL-compatible E2E support for the collector-side R2DBC adapter.
*/
abstract class AbstractMysqlR2dbcCollectE2eTest extends AbstractCollectE2eTest {
protected static final String TEST_DATABASE = "hzb";
protected static final String TEST_USERNAME = "test";
protected static final String TEST_PASSWORD = "test123";
protected static final String ROOT_PASSWORD = "root123";
protected GenericContainer<?> container;
private MysqlR2dbcJdbcQueryExecutor jdbcQueryExecutor;
protected void setUpTarget(DatabaseTarget target) throws Exception {
super.setUp();
collect = new JdbcCommonCollect();
metrics = new Metrics();
container = createContainer(target);
container.start();
awaitTcpLoginReady();
initMonitoringData();
MysqlCollectorProperties properties = new MysqlCollectorProperties();
properties.setQueryEngine(MysqlCollectorProperties.QueryEngine.R2DBC);
jdbcQueryExecutor = new MysqlR2dbcJdbcQueryExecutor(
properties,
new MysqlR2dbcQueryExecutor(
new MysqlR2dbcConnectionFactoryProvider(),
new ResultSetMapper(),
new SqlGuard()),
new MysqlJdbcDriverAvailability());
jdbcQueryExecutor.afterPropertiesSet();
}
protected void tearDownTarget() throws Exception {
if (jdbcQueryExecutor != null) {
jdbcQueryExecutor.destroy();
jdbcQueryExecutor = null;
}
if (container != null) {
container.stop();
container = null;
}
}
protected void assertMysqlJdbcDriverAbsent() {
Assertions.assertThrows(ClassNotFoundException.class, () -> Class.forName("com.mysql.cj.jdbc.Driver"));
}
protected void collectMysqlTemplate(Set<String> metricFilter) throws Exception {
Job mysqlJob = appService.getAppDefine("mysql");
List<Map<String, Configmap>> configmapFromPreCollectData = new LinkedList<>();
for (Metrics metricsDef : mysqlJob.getMetrics()) {
if (metricFilter != null && !metricFilter.contains(metricsDef.getName())) {
continue;
}
metricsDef = CollectUtil.replaceCryPlaceholderToMetrics(metricsDef,
configmapFromPreCollectData.isEmpty() ? new HashMap<>() : configmapFromPreCollectData.getFirst());
String metricName = metricsDef.getName();
if ("process_state".equals(metricName)) {
startBackgroundSleepQuery();
}
if ("slow_sql".equals(metricName)) {
generateSlowQuery();
}
CollectRep.MetricsData metricsData = validateMetricsCollection(metricsDef, metricName, true);
configmapFromPreCollectData = CollectUtil.getConfigmapFromPreCollectData(metricsData);
}
}
@Override
protected CollectRep.MetricsData.Builder collectMetrics(Metrics metricsDef) {
JdbcProtocol jdbcProtocol = (JdbcProtocol) buildProtocol(metricsDef);
metrics.setJdbc(jdbcProtocol);
CollectRep.MetricsData.Builder metricsData = CollectRep.MetricsData.newBuilder();
metricsData.setApp("mysql");
return collectMetricsData(metrics, metricsDef, metricsData);
}
@Override
protected Protocol buildProtocol(Metrics metricsDef) {
JdbcProtocol jdbcProtocol = metricsDef.getJdbc();
jdbcProtocol.setHost(container.getHost());
jdbcProtocol.setPort(String.valueOf(container.getMappedPort(3306)));
jdbcProtocol.setUsername(TEST_USERNAME);
jdbcProtocol.setPassword(TEST_PASSWORD);
jdbcProtocol.setDatabase(TEST_DATABASE);
jdbcProtocol.setTimeout("8000");
jdbcProtocol.setReuseConnection("false");
jdbcProtocol.setUrl(null);
jdbcProtocol.setSshTunnel(null);
return jdbcProtocol;
}
private GenericContainer<?> createContainer(DatabaseTarget target) {
GenericContainer<?> mysql = new GenericContainer<>(target.image())
.withExposedPorts(3306)
.waitingFor(Wait.forListeningPort());
if (target.mariaDb()) {
return mysql.withEnv("MARIADB_DATABASE", TEST_DATABASE)
.withEnv("MARIADB_USER", TEST_USERNAME)
.withEnv("MARIADB_PASSWORD", TEST_PASSWORD)
.withEnv("MARIADB_ROOT_PASSWORD", ROOT_PASSWORD);
}
return mysql.withEnv("MYSQL_DATABASE", TEST_DATABASE)
.withEnv("MYSQL_USER", TEST_USERNAME)
.withEnv("MYSQL_PASSWORD", TEST_PASSWORD)
.withEnv("MYSQL_ROOT_PASSWORD", ROOT_PASSWORD);
}
private void initMonitoringData() throws Exception {
execRoot("GRANT SELECT ON mysql.* TO '" + TEST_USERNAME + "'@'%';"
+ " GRANT PROCESS ON *.* TO '" + TEST_USERNAME + "'@'%';"
+ " SET GLOBAL log_output='TABLE';"
+ " SET GLOBAL slow_query_log='ON';"
+ " SET GLOBAL long_query_time=0;"
+ " FLUSH PRIVILEGES;");
generateSlowQuery();
}
private void generateSlowQuery() throws Exception {
execUser(TEST_DATABASE, "SELECT SLEEP(0.2);");
Thread.sleep(300);
}
private void startBackgroundSleepQuery() throws Exception {
String command = String.join(" ",
"CLIENT=$(command -v mysql || command -v mariadb)",
"&&",
"nohup sh -lc",
"'$CLIENT --protocol=TCP -h127.0.0.1 -P3306",
"-u" + TEST_USERNAME,
"-p" + TEST_PASSWORD,
TEST_DATABASE,
"-e",
"\"SELECT SLEEP(15)\" >/tmp/process-state.log 2>&1'",
">/dev/null 2>&1 &");
container.execInContainer("sh", "-lc", command);
Thread.sleep(500);
}
private void awaitTcpLoginReady() throws Exception {
long deadline = System.currentTimeMillis() + 30_000L;
while (System.currentTimeMillis() < deadline) {
try {
var result = container.execInContainer("sh", "-lc",
mysqlCliCommand(TEST_USERNAME, TEST_PASSWORD, TEST_DATABASE, "SELECT 1"));
if (result.getExitCode() == 0) {
return;
}
} catch (Exception ignored) {
// Wait for the MySQL entrypoint to finish bootstrapping and switch to the final TCP listener.
}
Thread.sleep(1000);
}
throw new IllegalStateException("Timed out waiting for MySQL-compatible TCP login to become ready");
}
private void execRoot(String sql) throws Exception {
var result = container.execInContainer("sh", "-lc", mysqlCliCommand("root", ROOT_PASSWORD, "mysql", sql));
if (result.getExitCode() != 0) {
throw new IllegalStateException("root mysql command failed: " + result.getStderr());
}
}
private void execUser(String database, String sql) throws Exception {
var result = container.execInContainer("sh", "-lc", mysqlCliCommand(TEST_USERNAME, TEST_PASSWORD, database, sql));
if (result.getExitCode() != 0) {
throw new IllegalStateException("user mysql command failed: " + result.getStderr());
}
}
private String mysqlCliCommand(String username, String password, String database, String sql) {
return String.join(" ",
"CLIENT=$(command -v mysql || command -v mariadb)",
"&&",
"$CLIENT --protocol=TCP -h127.0.0.1 -P3306",
"-u" + username,
"-p" + password,
database,
"-e",
"\"" + sql.replace("\"", "\\\"") + "\"");
}
protected record DatabaseTarget(String name, DockerImageName image, boolean mariaDb) {
}
}
@@ -1,61 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.collector.collect.mysql;
import java.util.Set;
import java.util.stream.Stream;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import org.testcontainers.utility.DockerImageName;
/**
* Compatibility E2E coverage for the collector-side MySQL R2DBC adapter.
*/
class MysqlR2dbcCollectCompatibilityE2eTest extends AbstractMysqlR2dbcCollectE2eTest {
private static final Set<String> MARIADB_REPRESENTATIVE_METRICS =
Set.of("basic", "process_state", "slow_sql");
@TestFactory
Stream<DynamicTest> shouldCollectMysqlTemplateAcrossCompatibilityMatrixWithoutMysqlJdbcDriver() {
return Stream.of(
new MatrixTarget(
new DatabaseTarget("mysql-5.7.44", DockerImageName.parse("mysql:5.7.44"), false),
null),
new MatrixTarget(
new DatabaseTarget("mysql-8.0.36", DockerImageName.parse("mysql:8.0.36"), false),
null),
new MatrixTarget(
new DatabaseTarget("mariadb-11.4", DockerImageName.parse("mariadb:11.4"), true),
MARIADB_REPRESENTATIVE_METRICS))
.map(target -> DynamicTest.dynamicTest(target.databaseTarget().name(), () -> verifyTarget(target)));
}
private void verifyTarget(MatrixTarget target) throws Exception {
setUpTarget(target.databaseTarget());
try {
assertMysqlJdbcDriverAbsent();
collectMysqlTemplate(target.metricFilter());
} finally {
tearDownTarget();
}
}
private record MatrixTarget(DatabaseTarget databaseTarget, Set<String> metricFilter) {
}
}
@@ -1,41 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hertzbeat.collector.collect.mysql;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.testcontainers.utility.DockerImageName;
/**
* E2E test for collector-side MySQL monitoring through the R2DBC query adapter.
*/
@Slf4j
class MysqlR2dbcCollectE2eTest extends AbstractMysqlR2dbcCollectE2eTest {
@Test
void shouldCollectMysqlTemplateWithoutMysqlJdbcDriver() throws Exception {
DatabaseTarget target = new DatabaseTarget("mysql-8.0.36", DockerImageName.parse("mysql:8.0.36"), false);
setUpTarget(target);
try {
assertMysqlJdbcDriverAbsent();
collectMysqlTemplate(null);
} finally {
tearDownTarget();
}
}
}
-1
View File
@@ -31,7 +31,6 @@
<module>hertzbeat-collector-common-e2e</module>
<module>hertzbeat-collector-kafka-e2e</module>
<module>hertzbeat-collector-basic-e2e</module>
<module>hertzbeat-collector-mysql-r2dbc-e2e</module>
<module>hertzbeat-observability-e2e</module>
</modules>