[FLINK-35638][OceanBase][test] Refactor OceanBase test cases and remove dependency on host network (#3439)
parent
c5396fbf29
commit
cbb33bb870
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* 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.flink.cdc.connectors.oceanbase;
|
||||||
|
|
||||||
|
import org.apache.flink.cdc.connectors.oceanbase.testutils.LogProxyContainer;
|
||||||
|
import org.apache.flink.cdc.connectors.oceanbase.testutils.OceanBaseContainer;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.testcontainers.containers.output.Slf4jLogConsumer;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
/** Utils to help test. */
|
||||||
|
@SuppressWarnings("resource")
|
||||||
|
public class OceanBaseTestUtils {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(OceanBaseTestUtils.class);
|
||||||
|
|
||||||
|
private static final String LATEST_VERSION = "latest";
|
||||||
|
private static final String CDC_TEST_OB_VERSION = "4.2.1.6-106000012024042515";
|
||||||
|
|
||||||
|
private static final String SYS_PASSWORD = "123456";
|
||||||
|
private static final String TEST_PASSWORD = "654321";
|
||||||
|
|
||||||
|
public static OceanBaseContainer createOceanBaseContainerForCDC() {
|
||||||
|
return createOceanBaseContainer(CDC_TEST_OB_VERSION, "mini")
|
||||||
|
.withSysPassword(SYS_PASSWORD)
|
||||||
|
.withStartupTimeout(Duration.ofMinutes(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OceanBaseContainer createOceanBaseContainerForJdbc() {
|
||||||
|
return createOceanBaseContainer(LATEST_VERSION, "slim")
|
||||||
|
.withStartupTimeout(Duration.ofMinutes(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OceanBaseContainer createOceanBaseContainer(String version, String mode) {
|
||||||
|
return new OceanBaseContainer(version)
|
||||||
|
.withMode(mode)
|
||||||
|
.withTenantPassword(TEST_PASSWORD)
|
||||||
|
.withEnv("OB_DATAFILE_SIZE", "2G")
|
||||||
|
.withEnv("OB_LOG_DISK_SIZE", "4G")
|
||||||
|
.withLogConsumer(new Slf4jLogConsumer(LOG));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LogProxyContainer createLogProxyContainer() {
|
||||||
|
return new LogProxyContainer(LATEST_VERSION)
|
||||||
|
.withSysPassword(SYS_PASSWORD)
|
||||||
|
.withStartupTimeout(Duration.ofMinutes(1))
|
||||||
|
.withLogConsumer(new Slf4jLogConsumer(LOG));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* 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.flink.cdc.connectors.oceanbase.testutils;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.testcontainers.containers.GenericContainer;
|
||||||
|
import org.testcontainers.containers.wait.strategy.Wait;
|
||||||
|
import org.testcontainers.utility.DockerImageName;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/** OceanBase Log Proxy container. */
|
||||||
|
public class LogProxyContainer extends GenericContainer<LogProxyContainer> {
|
||||||
|
|
||||||
|
private static final String IMAGE = "oceanbase/oblogproxy-ce";
|
||||||
|
|
||||||
|
private static final int PORT = 2983;
|
||||||
|
private static final String ROOT_USER = "root";
|
||||||
|
|
||||||
|
private String sysPassword;
|
||||||
|
|
||||||
|
public LogProxyContainer(String version) {
|
||||||
|
super(DockerImageName.parse(IMAGE + ":" + version));
|
||||||
|
addExposedPorts(PORT);
|
||||||
|
setWaitStrategy(Wait.forLogMessage(".*boot success!.*", 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
addEnv("OB_SYS_USERNAME", ROOT_USER);
|
||||||
|
addEnv("OB_SYS_PASSWORD", sysPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull Set<Integer> getLivenessCheckPortNumbers() {
|
||||||
|
return Collections.singleton(this.getMappedPort(PORT));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return getMappedPort(PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LogProxyContainer withSysPassword(String sysPassword) {
|
||||||
|
this.sysPassword = sysPassword;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* 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.flink.cdc.connectors.oceanbase.testutils;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/** OceanBase CDC metadata. */
|
||||||
|
public interface OceanBaseCdcMetadata extends Serializable {
|
||||||
|
|
||||||
|
String getCompatibleMode();
|
||||||
|
|
||||||
|
String getHostname();
|
||||||
|
|
||||||
|
int getPort();
|
||||||
|
|
||||||
|
String getUsername();
|
||||||
|
|
||||||
|
String getPassword();
|
||||||
|
|
||||||
|
String getDriverClass();
|
||||||
|
|
||||||
|
String getDatabase();
|
||||||
|
|
||||||
|
String getJdbcUrl();
|
||||||
|
|
||||||
|
String getTenantName();
|
||||||
|
|
||||||
|
String getLogProxyHost();
|
||||||
|
|
||||||
|
int getLogProxyPort();
|
||||||
|
|
||||||
|
default String getConfigUrl() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
default String getRsList() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* 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.flink.cdc.connectors.oceanbase.testutils;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.testcontainers.containers.JdbcDatabaseContainer;
|
||||||
|
import org.testcontainers.containers.wait.strategy.Wait;
|
||||||
|
import org.testcontainers.utility.DockerImageName;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/** OceanBase container. */
|
||||||
|
public class OceanBaseContainer extends JdbcDatabaseContainer<OceanBaseContainer> {
|
||||||
|
|
||||||
|
private static final String IMAGE = "oceanbase/oceanbase-ce";
|
||||||
|
|
||||||
|
private static final int SQL_PORT = 2881;
|
||||||
|
private static final int RPC_PORT = 2882;
|
||||||
|
private static final String ROOT_USER = "root";
|
||||||
|
private static final String TEST_DATABASE = "test";
|
||||||
|
private static final String DEFAULT_TENANT = "test";
|
||||||
|
private static final String DEFAULT_PASSWORD = "";
|
||||||
|
|
||||||
|
private String mode = "mini";
|
||||||
|
private String tenantName = DEFAULT_TENANT;
|
||||||
|
private String sysPassword = DEFAULT_PASSWORD;
|
||||||
|
private String tenantPassword = DEFAULT_PASSWORD;
|
||||||
|
|
||||||
|
public OceanBaseContainer(String version) {
|
||||||
|
super(DockerImageName.parse(IMAGE + ":" + version));
|
||||||
|
addExposedPorts(SQL_PORT, RPC_PORT);
|
||||||
|
setWaitStrategy(Wait.forLogMessage(".*boot success!.*", 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
addEnv("MODE", mode);
|
||||||
|
addEnv("OB_CLUSTER_NAME", "flink-cdc-ci");
|
||||||
|
if (!DEFAULT_PASSWORD.equals(sysPassword)) {
|
||||||
|
addEnv("OB_SYS_PASSWORD", sysPassword);
|
||||||
|
}
|
||||||
|
if (!DEFAULT_TENANT.equals(tenantName)) {
|
||||||
|
addEnv("OB_TENANT_NAME", tenantName);
|
||||||
|
}
|
||||||
|
if (!DEFAULT_PASSWORD.equals(tenantPassword)) {
|
||||||
|
addEnv("OB_TENANT_PASSWORD", tenantPassword);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void waitUntilContainerStarted() {
|
||||||
|
this.getWaitStrategy().waitUntilReady(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull Set<Integer> getLivenessCheckPortNumbers() {
|
||||||
|
return Collections.singleton(this.getMappedPort(SQL_PORT));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDriverClassName() {
|
||||||
|
return "com.mysql.cj.jdbc.Driver";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getJdbcUrl(String databaseName) {
|
||||||
|
return "jdbc:mysql://"
|
||||||
|
+ getHost()
|
||||||
|
+ ":"
|
||||||
|
+ getDatabasePort()
|
||||||
|
+ "/"
|
||||||
|
+ databaseName
|
||||||
|
+ "?useSSL=false";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getJdbcUrl() {
|
||||||
|
return getJdbcUrl("");
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDatabasePort() {
|
||||||
|
return getMappedPort(SQL_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTenantName() {
|
||||||
|
return tenantName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDatabaseName() {
|
||||||
|
return TEST_DATABASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsername() {
|
||||||
|
return ROOT_USER + "@" + tenantName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPassword() {
|
||||||
|
return tenantPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getTestQueryString() {
|
||||||
|
return "SELECT 1";
|
||||||
|
}
|
||||||
|
|
||||||
|
public OceanBaseContainer withMode(String mode) {
|
||||||
|
this.mode = mode;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OceanBaseContainer withTenantName(String tenantName) {
|
||||||
|
this.tenantName = tenantName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OceanBaseContainer withSysPassword(String sysPassword) {
|
||||||
|
this.sysPassword = sysPassword;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OceanBaseContainer withTenantPassword(String tenantPassword) {
|
||||||
|
this.tenantPassword = tenantPassword;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* 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.flink.cdc.connectors.oceanbase.testutils;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
/** OceanBase CDC MySQL mode metadata. */
|
||||||
|
public class OceanBaseMySQLCdcMetadata implements OceanBaseCdcMetadata {
|
||||||
|
|
||||||
|
private final OceanBaseContainer obServerContainer;
|
||||||
|
private final LogProxyContainer logProxyContainer;
|
||||||
|
|
||||||
|
private String rsList;
|
||||||
|
|
||||||
|
public OceanBaseMySQLCdcMetadata(
|
||||||
|
OceanBaseContainer obServerContainer, LogProxyContainer logProxyContainer) {
|
||||||
|
this.obServerContainer = obServerContainer;
|
||||||
|
this.logProxyContainer = logProxyContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCompatibleMode() {
|
||||||
|
return "mysql";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getHostname() {
|
||||||
|
return obServerContainer.getHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPort() {
|
||||||
|
return obServerContainer.getDatabasePort();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsername() {
|
||||||
|
return obServerContainer.getUsername();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPassword() {
|
||||||
|
return obServerContainer.getPassword();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDriverClass() {
|
||||||
|
return obServerContainer.getDriverClassName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDatabase() {
|
||||||
|
return obServerContainer.getDatabaseName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getJdbcUrl() {
|
||||||
|
return "jdbc:mysql://" + getHostname() + ":" + getPort() + "/?useSSL=false";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTenantName() {
|
||||||
|
return obServerContainer.getTenantName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLogProxyHost() {
|
||||||
|
return logProxyContainer.getHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLogProxyPort() {
|
||||||
|
return logProxyContainer.getPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRsList() {
|
||||||
|
if (rsList == null) {
|
||||||
|
try (Connection connection =
|
||||||
|
DriverManager.getConnection(
|
||||||
|
getJdbcUrl(), getUsername(), getPassword());
|
||||||
|
Statement statement = connection.createStatement()) {
|
||||||
|
ResultSet rs = statement.executeQuery("SHOW PARAMETERS LIKE 'rootservice_list'");
|
||||||
|
rsList = rs.next() ? rs.getString("VALUE") : null;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException("Failed to query rs list", e);
|
||||||
|
}
|
||||||
|
if (rsList == null) {
|
||||||
|
throw new RuntimeException("Got empty rs list");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rsList;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* 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.flink.cdc.connectors.oceanbase.testutils;
|
||||||
|
|
||||||
|
/** OceanBase CDC Oracle mode metadata. */
|
||||||
|
public class OceanBaseOracleCdcMetadata implements OceanBaseCdcMetadata {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCompatibleMode() {
|
||||||
|
return "oracle";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getHostname() {
|
||||||
|
return System.getenv("host");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPort() {
|
||||||
|
return Integer.parseInt(System.getenv("port"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsername() {
|
||||||
|
return System.getenv("username");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPassword() {
|
||||||
|
return System.getenv("password");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDatabase() {
|
||||||
|
return System.getenv("schema");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDriverClass() {
|
||||||
|
return "com.oceanbase.jdbc.Driver";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getJdbcUrl() {
|
||||||
|
return "jdbc:oceanbase://" + getHostname() + ":" + getPort() + "/" + getDatabase();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTenantName() {
|
||||||
|
return System.getenv("tenant");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLogProxyHost() {
|
||||||
|
return System.getenv("log_proxy_host");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLogProxyPort() {
|
||||||
|
return Integer.parseInt(System.getenv("log_proxy_port"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getConfigUrl() {
|
||||||
|
return System.getenv("config_url");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* 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.flink.cdc.connectors.oceanbase.testutils;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and populate a unique instance of an OceanBase database for each run of JUnit test. A user
|
||||||
|
* of class needs to provide a logical name for Debezium and database name. It is expected that
|
||||||
|
* there is an init file in <code>src/test/resources/ddl/<database_name>.sql</code>. The
|
||||||
|
* database name is enriched with a unique suffix that guarantees complete isolation between runs
|
||||||
|
* <code>
|
||||||
|
* <database_name>_<suffix></code>
|
||||||
|
*
|
||||||
|
* <p>This class is inspired from Debezium project.
|
||||||
|
*/
|
||||||
|
public class UniqueDatabase {
|
||||||
|
|
||||||
|
private static final String[] CREATE_DATABASE_DDL =
|
||||||
|
new String[] {"CREATE DATABASE `$DBNAME$`;", "USE `$DBNAME$`;"};
|
||||||
|
private static final String DROP_DATABASE_DDL = "DROP DATABASE IF EXISTS `$DBNAME$`;";
|
||||||
|
private static final Pattern COMMENT_PATTERN = Pattern.compile("^(.*)--.*$");
|
||||||
|
|
||||||
|
private final OceanBaseContainer container;
|
||||||
|
private final String databaseName;
|
||||||
|
private final String templateName;
|
||||||
|
|
||||||
|
public UniqueDatabase(OceanBaseContainer container, String databaseName) {
|
||||||
|
this(container, databaseName, Integer.toUnsignedString(new Random().nextInt(), 36));
|
||||||
|
}
|
||||||
|
|
||||||
|
private UniqueDatabase(
|
||||||
|
OceanBaseContainer container, String databaseName, final String identifier) {
|
||||||
|
this.container = container;
|
||||||
|
this.databaseName = databaseName + "_" + identifier;
|
||||||
|
this.templateName = databaseName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHost() {
|
||||||
|
return container.getHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDatabasePort() {
|
||||||
|
return container.getDatabasePort();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDatabaseName() {
|
||||||
|
return databaseName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return container.getUsername();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return container.getPassword();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return Fully qualified table name <code><databaseName>.<tableName></code> */
|
||||||
|
public String qualifiedTableName(final String tableName) {
|
||||||
|
return String.format("%s.%s", databaseName, tableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Creates the database and populates it with initialization SQL script. */
|
||||||
|
public void createAndInitialize() {
|
||||||
|
final String ddlFile = String.format("ddl/%s.sql", templateName);
|
||||||
|
final URL ddlTestFile = UniqueDatabase.class.getClassLoader().getResource(ddlFile);
|
||||||
|
assertNotNull("Cannot locate " + ddlFile, ddlTestFile);
|
||||||
|
try {
|
||||||
|
try (Connection connection =
|
||||||
|
DriverManager.getConnection(
|
||||||
|
container.getJdbcUrl(), getUsername(), getPassword());
|
||||||
|
Statement statement = connection.createStatement()) {
|
||||||
|
final List<String> statements =
|
||||||
|
Arrays.stream(
|
||||||
|
Stream.concat(
|
||||||
|
Arrays.stream(CREATE_DATABASE_DDL),
|
||||||
|
Files.readAllLines(
|
||||||
|
Paths.get(ddlTestFile.toURI()))
|
||||||
|
.stream())
|
||||||
|
.map(String::trim)
|
||||||
|
.filter(x -> !x.startsWith("--") && !x.isEmpty())
|
||||||
|
.map(
|
||||||
|
x -> {
|
||||||
|
final Matcher m =
|
||||||
|
COMMENT_PATTERN.matcher(x);
|
||||||
|
return m.matches() ? m.group(1) : x;
|
||||||
|
})
|
||||||
|
.map(this::convertSQL)
|
||||||
|
.collect(Collectors.joining("\n"))
|
||||||
|
.split(";"))
|
||||||
|
.map(x -> x.replace("$$", ";"))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
for (String stmt : statements) {
|
||||||
|
statement.execute(stmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Drop the database if it is existing. */
|
||||||
|
public void dropDatabase() {
|
||||||
|
try {
|
||||||
|
try (Connection connection =
|
||||||
|
DriverManager.getConnection(
|
||||||
|
container.getJdbcUrl(), getUsername(), getPassword());
|
||||||
|
Statement statement = connection.createStatement()) {
|
||||||
|
final String dropDatabaseStatement = convertSQL(DROP_DATABASE_DDL);
|
||||||
|
statement.execute(dropDatabaseStatement);
|
||||||
|
}
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Connection getJdbcConnection() throws SQLException {
|
||||||
|
return DriverManager.getConnection(
|
||||||
|
container.getJdbcUrl(databaseName), getUsername(), getPassword());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String convertSQL(final String sql) {
|
||||||
|
return sql.replace("$DBNAME$", databaseName);
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +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.
|
|
||||||
|
|
||||||
-- Set the root user password of test tenant
|
|
||||||
ALTER USER root IDENTIFIED BY '123456';
|
|
@ -1,16 +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.
|
|
||||||
|
|
||||||
ALTER USER root IDENTIFIED BY '7654321';
|
|
Loading…
Reference in New Issue