mirror of
https://github.com/dromara/hertzbeat.git
synced 2026-09-17 09:40:58 +00:00
build: remove orphan mysql r2dbc e2e module
This commit is contained in:
@@ -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>
|
||||
-233
@@ -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) {
|
||||
}
|
||||
}
|
||||
-61
@@ -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) {
|
||||
}
|
||||
}
|
||||
-41
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user