提交 33a08cc1 编写于 作者: H haocao

Removed yaml relative datasource.

上级 34a6bb0d
...@@ -19,14 +19,20 @@ package io.shardingjdbc.core.api; ...@@ -19,14 +19,20 @@ package io.shardingjdbc.core.api;
import io.shardingjdbc.core.api.config.MasterSlaveRuleConfiguration; import io.shardingjdbc.core.api.config.MasterSlaveRuleConfiguration;
import io.shardingjdbc.core.jdbc.core.datasource.MasterSlaveDataSource; import io.shardingjdbc.core.jdbc.core.datasource.MasterSlaveDataSource;
import io.shardingjdbc.core.yaml.masterslave.YamlMasterSlaveDataSource; import io.shardingjdbc.core.yaml.masterslave.YamlMasterSlaveRuleConfiguration;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
import javax.sql.DataSource; import javax.sql.DataSource;
import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Collections;
import java.util.Map; import java.util.Map;
/** /**
...@@ -62,7 +68,8 @@ public final class MasterSlaveDataSourceFactory { ...@@ -62,7 +68,8 @@ public final class MasterSlaveDataSourceFactory {
* @throws IOException IO exception * @throws IOException IO exception
*/ */
public static DataSource createDataSource(final File yamlFile) throws SQLException, IOException { public static DataSource createDataSource(final File yamlFile) throws SQLException, IOException {
return new YamlMasterSlaveDataSource(yamlFile); YamlMasterSlaveRuleConfiguration config = unmarshal(yamlFile);
return new MasterSlaveDataSource(config.getMasterSlaveRule(Collections.<String, DataSource>emptyMap()));
} }
/** /**
...@@ -77,7 +84,8 @@ public final class MasterSlaveDataSourceFactory { ...@@ -77,7 +84,8 @@ public final class MasterSlaveDataSourceFactory {
* @throws IOException IO exception * @throws IOException IO exception
*/ */
public static DataSource createDataSource(final Map<String, DataSource> dataSourceMap, final File yamlFile) throws SQLException, IOException { public static DataSource createDataSource(final Map<String, DataSource> dataSourceMap, final File yamlFile) throws SQLException, IOException {
return new YamlMasterSlaveDataSource(dataSourceMap, yamlFile); YamlMasterSlaveRuleConfiguration config = unmarshal(yamlFile);
return new MasterSlaveDataSource(config.getMasterSlaveRule(dataSourceMap));
} }
/** /**
...@@ -91,7 +99,8 @@ public final class MasterSlaveDataSourceFactory { ...@@ -91,7 +99,8 @@ public final class MasterSlaveDataSourceFactory {
* @throws IOException IO exception * @throws IOException IO exception
*/ */
public static DataSource createDataSource(final byte[] yamlByteArray) throws SQLException, IOException { public static DataSource createDataSource(final byte[] yamlByteArray) throws SQLException, IOException {
return new YamlMasterSlaveDataSource(yamlByteArray); YamlMasterSlaveRuleConfiguration config = unmarshal(yamlByteArray);
return new MasterSlaveDataSource(config.getMasterSlaveRule(Collections.<String, DataSource>emptyMap()));
} }
/** /**
...@@ -106,6 +115,20 @@ public final class MasterSlaveDataSourceFactory { ...@@ -106,6 +115,20 @@ public final class MasterSlaveDataSourceFactory {
* @throws IOException IO exception * @throws IOException IO exception
*/ */
public static DataSource createDataSource(final Map<String, DataSource> dataSourceMap, final byte[] yamlByteArray) throws SQLException, IOException { public static DataSource createDataSource(final Map<String, DataSource> dataSourceMap, final byte[] yamlByteArray) throws SQLException, IOException {
return new YamlMasterSlaveDataSource(dataSourceMap, yamlByteArray); YamlMasterSlaveRuleConfiguration config = unmarshal(yamlByteArray);
return new MasterSlaveDataSource(config.getMasterSlaveRule(dataSourceMap));
}
private static YamlMasterSlaveRuleConfiguration unmarshal(final File yamlFile) throws IOException {
try (
FileInputStream fileInputStream = new FileInputStream(yamlFile);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8")
) {
return new Yaml(new Constructor(YamlMasterSlaveRuleConfiguration.class)).loadAs(inputStreamReader, YamlMasterSlaveRuleConfiguration.class);
}
}
private static YamlMasterSlaveRuleConfiguration unmarshal(final byte[] yamlByteArray) throws IOException {
return new Yaml(new Constructor(YamlMasterSlaveRuleConfiguration.class)).loadAs(new ByteArrayInputStream(yamlByteArray), YamlMasterSlaveRuleConfiguration.class);
} }
} }
...@@ -19,14 +19,20 @@ package io.shardingjdbc.core.api; ...@@ -19,14 +19,20 @@ package io.shardingjdbc.core.api;
import io.shardingjdbc.core.api.config.ShardingRuleConfiguration; import io.shardingjdbc.core.api.config.ShardingRuleConfiguration;
import io.shardingjdbc.core.jdbc.core.datasource.ShardingDataSource; import io.shardingjdbc.core.jdbc.core.datasource.ShardingDataSource;
import io.shardingjdbc.core.yaml.sharding.YamlShardingDataSource; import io.shardingjdbc.core.yaml.sharding.YamlShardingRuleConfiguration;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
import javax.sql.DataSource; import javax.sql.DataSource;
import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
...@@ -72,7 +78,8 @@ public final class ShardingDataSourceFactory { ...@@ -72,7 +78,8 @@ public final class ShardingDataSourceFactory {
* @throws IOException IO exception * @throws IOException IO exception
*/ */
public static DataSource createDataSource(final File yamlFile) throws SQLException, IOException { public static DataSource createDataSource(final File yamlFile) throws SQLException, IOException {
return new YamlShardingDataSource(yamlFile); YamlShardingRuleConfiguration config = unmarshal(yamlFile);
return new ShardingDataSource(config.getShardingRule(Collections.<String, DataSource>emptyMap()), config.getProps());
} }
/** /**
...@@ -85,7 +92,8 @@ public final class ShardingDataSourceFactory { ...@@ -85,7 +92,8 @@ public final class ShardingDataSourceFactory {
* @throws SQLException IO exception * @throws SQLException IO exception
*/ */
public static DataSource createDataSource(final Map<String, DataSource> dataSourceMap, final File yamlFile) throws SQLException, IOException { public static DataSource createDataSource(final Map<String, DataSource> dataSourceMap, final File yamlFile) throws SQLException, IOException {
return new YamlShardingDataSource(dataSourceMap, yamlFile); YamlShardingRuleConfiguration config = unmarshal(yamlFile);
return new ShardingDataSource(config.getShardingRule(dataSourceMap), config.getProps());
} }
/** /**
...@@ -97,7 +105,8 @@ public final class ShardingDataSourceFactory { ...@@ -97,7 +105,8 @@ public final class ShardingDataSourceFactory {
* @throws SQLException IO exception * @throws SQLException IO exception
*/ */
public static DataSource createDataSource(final byte[] yamlByteArray) throws SQLException, IOException { public static DataSource createDataSource(final byte[] yamlByteArray) throws SQLException, IOException {
return new YamlShardingDataSource(yamlByteArray); YamlShardingRuleConfiguration config = unmarshal(yamlByteArray);
return new ShardingDataSource(config.getShardingRule(Collections.<String, DataSource>emptyMap()), config.getProps());
} }
/** /**
...@@ -110,6 +119,20 @@ public final class ShardingDataSourceFactory { ...@@ -110,6 +119,20 @@ public final class ShardingDataSourceFactory {
* @throws SQLException IO exception * @throws SQLException IO exception
*/ */
public static DataSource createDataSource(final Map<String, DataSource> dataSourceMap, final byte[] yamlByteArray) throws SQLException, IOException { public static DataSource createDataSource(final Map<String, DataSource> dataSourceMap, final byte[] yamlByteArray) throws SQLException, IOException {
return new YamlShardingDataSource(dataSourceMap, yamlByteArray); YamlShardingRuleConfiguration config = unmarshal(yamlByteArray);
return new ShardingDataSource(config.getShardingRule(dataSourceMap), config.getProps());
}
private static YamlShardingRuleConfiguration unmarshal(final File yamlFile) throws IOException {
try (
FileInputStream fileInputStream = new FileInputStream(yamlFile);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8")
) {
return new Yaml(new Constructor(YamlShardingRuleConfiguration.class)).loadAs(inputStreamReader, YamlShardingRuleConfiguration.class);
}
}
private static YamlShardingRuleConfiguration unmarshal(final byte[] yamlByteArray) throws IOException {
return new Yaml(new Constructor(YamlShardingRuleConfiguration.class)).loadAs(new ByteArrayInputStream(yamlByteArray), YamlShardingRuleConfiguration.class);
} }
} }
/*
* Copyright 1999-2015 dangdang.com.
* <p>
* 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.
* </p>
*/
package io.shardingjdbc.core.yaml.masterslave;
import io.shardingjdbc.core.jdbc.core.datasource.MasterSlaveDataSource;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
import javax.sql.DataSource;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Map;
/**
* Master-slave datasource for yaml.
*
* @author caohao
*/
public class YamlMasterSlaveDataSource extends MasterSlaveDataSource {
public YamlMasterSlaveDataSource(final File yamlFile) throws IOException, SQLException {
super(unmarshal(yamlFile).getMasterSlaveRule(Collections.<String, DataSource>emptyMap()));
}
public YamlMasterSlaveDataSource(final Map<String, DataSource> dataSourceMap, final File yamlFile) throws IOException, SQLException {
super(unmarshal(yamlFile).getMasterSlaveRule(dataSourceMap));
}
public YamlMasterSlaveDataSource(final byte[] yamlByteArray) throws IOException, SQLException {
super(unmarshal(yamlByteArray).getMasterSlaveRule(Collections.<String, DataSource>emptyMap()));
}
public YamlMasterSlaveDataSource(final Map<String, DataSource> dataSourceMap, final byte[] yamlByteArray) throws IOException, SQLException {
super(unmarshal(yamlByteArray).getMasterSlaveRule(dataSourceMap));
}
private static YamlMasterSlaveRuleConfiguration unmarshal(final File yamlFile) throws IOException {
try (
FileInputStream fileInputStream = new FileInputStream(yamlFile);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8")
) {
return new Yaml(new Constructor(YamlMasterSlaveRuleConfiguration.class)).loadAs(inputStreamReader, YamlMasterSlaveRuleConfiguration.class);
}
}
private static YamlMasterSlaveRuleConfiguration unmarshal(final byte[] yamlByteArray) throws IOException {
return new Yaml(new Constructor(YamlMasterSlaveRuleConfiguration.class)).loadAs(new ByteArrayInputStream(yamlByteArray), YamlMasterSlaveRuleConfiguration.class);
}
}
/*
* Copyright 1999-2015 dangdang.com.
* <p>
* 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.
* </p>
*/
package io.shardingjdbc.core.yaml.sharding;
import io.shardingjdbc.core.jdbc.core.datasource.ShardingDataSource;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
import javax.sql.DataSource;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Map;
/**
* Sharding datasource for yaml.
*
* @author zhangliang
*/
public class YamlShardingDataSource extends ShardingDataSource {
public YamlShardingDataSource(final File yamlFile) throws IOException, SQLException {
super(unmarshal(yamlFile).getShardingRule(Collections.<String, DataSource>emptyMap()), unmarshal(yamlFile).getProps());
}
public YamlShardingDataSource(final Map<String, DataSource> dataSourceMap, final File yamlFile) throws IOException, SQLException {
super(unmarshal(yamlFile).getShardingRule(dataSourceMap), unmarshal(yamlFile).getProps());
}
public YamlShardingDataSource(final byte[] yamlByteArray) throws IOException, SQLException {
super(unmarshal(yamlByteArray).getShardingRule(Collections.<String, DataSource>emptyMap()), unmarshal(yamlByteArray).getProps());
}
public YamlShardingDataSource(final Map<String, DataSource> dataSourceMap, final byte[] yamlByteArray) throws IOException, SQLException {
super(unmarshal(yamlByteArray).getShardingRule(dataSourceMap), unmarshal(yamlByteArray).getProps());
}
private static YamlShardingRuleConfiguration unmarshal(final File yamlFile) throws IOException {
try (
FileInputStream fileInputStream = new FileInputStream(yamlFile);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8")
) {
return new Yaml(new Constructor(YamlShardingRuleConfiguration.class)).loadAs(inputStreamReader, YamlShardingRuleConfiguration.class);
}
}
private static YamlShardingRuleConfiguration unmarshal(final byte[] yamlByteArray) throws IOException {
return new Yaml(new Constructor(YamlShardingRuleConfiguration.class)).loadAs(new ByteArrayInputStream(yamlByteArray), YamlShardingRuleConfiguration.class);
}
}
...@@ -20,6 +20,7 @@ package io.shardingjdbc.core.yaml.masterslave; ...@@ -20,6 +20,7 @@ package io.shardingjdbc.core.yaml.masterslave;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import io.shardingjdbc.core.api.MasterSlaveDataSourceFactory;
import io.shardingjdbc.core.yaml.AbstractYamlDataSourceTest; import io.shardingjdbc.core.yaml.AbstractYamlDataSourceTest;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.junit.Test; import org.junit.Test;
...@@ -57,9 +58,9 @@ public class YamlMasterSlaveIntegrateTest extends AbstractYamlDataSourceTest { ...@@ -57,9 +58,9 @@ public class YamlMasterSlaveIntegrateTest extends AbstractYamlDataSourceTest {
File yamlFile = new File(YamlMasterSlaveIntegrateTest.class.getResource(filePath).toURI()); File yamlFile = new File(YamlMasterSlaveIntegrateTest.class.getResource(filePath).toURI());
DataSource dataSource; DataSource dataSource;
if (hasDataSource) { if (hasDataSource) {
dataSource = new YamlMasterSlaveDataSource(yamlFile); dataSource = MasterSlaveDataSourceFactory.createDataSource(yamlFile);
} else { } else {
dataSource = new YamlMasterSlaveDataSource(Maps.asMap(Sets.newHashSet("db_master", "db_slave_0", "db_slave_1"), new Function<String, DataSource>() { dataSource = MasterSlaveDataSourceFactory.createDataSource(Maps.asMap(Sets.newHashSet("db_master", "db_slave_0", "db_slave_1"), new Function<String, DataSource>() {
@Override @Override
public DataSource apply(final String key) { public DataSource apply(final String key) {
return createDataSource(key); return createDataSource(key);
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
package io.shardingjdbc.core.yaml.sharding; package io.shardingjdbc.core.yaml.sharding;
import io.shardingjdbc.core.api.ShardingDataSourceFactory;
import io.shardingjdbc.core.exception.ShardingJdbcException; import io.shardingjdbc.core.exception.ShardingJdbcException;
import io.shardingjdbc.core.jdbc.core.ShardingContext; import io.shardingjdbc.core.jdbc.core.ShardingContext;
import io.shardingjdbc.core.jdbc.core.datasource.ShardingDataSource; import io.shardingjdbc.core.jdbc.core.datasource.ShardingDataSource;
...@@ -75,14 +76,14 @@ public class YamlShardingDataSourceTest { ...@@ -75,14 +76,14 @@ public class YamlShardingDataSourceTest {
} }
private ShardingRule getShardingRule(final String fileName) throws NoSuchFieldException, IllegalAccessException, URISyntaxException, IOException, SQLException { private ShardingRule getShardingRule(final String fileName) throws NoSuchFieldException, IllegalAccessException, URISyntaxException, IOException, SQLException {
return getShardingRule(new YamlShardingDataSource(new File(getClass().getResource(fileName).toURI()))); return getShardingRule(ShardingDataSourceFactory.createDataSource(new File(getClass().getResource(fileName).toURI())));
} }
private ShardingRule getShardingRule(final Map<String, DataSource> dataSourceMap, final String fileName) throws ReflectiveOperationException, URISyntaxException, IOException, SQLException { private ShardingRule getShardingRule(final Map<String, DataSource> dataSourceMap, final String fileName) throws ReflectiveOperationException, URISyntaxException, IOException, SQLException {
return getShardingRule(new YamlShardingDataSource(dataSourceMap, new File(getClass().getResource(fileName).toURI()))); return getShardingRule(ShardingDataSourceFactory.createDataSource(dataSourceMap, new File(getClass().getResource(fileName).toURI())));
} }
private ShardingRule getShardingRule(final ShardingDataSource shardingDataSource) throws NoSuchFieldException, IllegalAccessException { private ShardingRule getShardingRule(final DataSource shardingDataSource) throws NoSuchFieldException, IllegalAccessException {
Field field = ShardingDataSource.class.getDeclaredField("shardingContext"); Field field = ShardingDataSource.class.getDeclaredField("shardingContext");
field.setAccessible(true); field.setAccessible(true);
ShardingContext shardingContext = (ShardingContext) field.get(shardingDataSource); ShardingContext shardingContext = (ShardingContext) field.get(shardingDataSource);
......
...@@ -20,6 +20,7 @@ package io.shardingjdbc.core.yaml.sharding; ...@@ -20,6 +20,7 @@ package io.shardingjdbc.core.yaml.sharding;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import io.shardingjdbc.core.api.ShardingDataSourceFactory;
import io.shardingjdbc.core.yaml.AbstractYamlDataSourceTest; import io.shardingjdbc.core.yaml.AbstractYamlDataSourceTest;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.junit.Test; import org.junit.Test;
...@@ -59,9 +60,9 @@ public class YamlShardingIntegrateTest extends AbstractYamlDataSourceTest { ...@@ -59,9 +60,9 @@ public class YamlShardingIntegrateTest extends AbstractYamlDataSourceTest {
File yamlFile = new File(YamlShardingIntegrateTest.class.getResource(filePath).toURI()); File yamlFile = new File(YamlShardingIntegrateTest.class.getResource(filePath).toURI());
DataSource dataSource; DataSource dataSource;
if (hasDataSource) { if (hasDataSource) {
dataSource = new YamlShardingDataSource(yamlFile); dataSource = ShardingDataSourceFactory.createDataSource(yamlFile);
} else { } else {
dataSource = new YamlShardingDataSource(Maps.asMap(Sets.newHashSet("db0", "db1"), new Function<String, DataSource>() { dataSource = ShardingDataSourceFactory.createDataSource(Maps.asMap(Sets.newHashSet("db0", "db1"), new Function<String, DataSource>() {
@Override @Override
public DataSource apply(final String key) { public DataSource apply(final String key) {
return createDataSource(key); return createDataSource(key);
......
...@@ -20,6 +20,7 @@ package io.shardingjdbc.core.yaml.sharding; ...@@ -20,6 +20,7 @@ package io.shardingjdbc.core.yaml.sharding;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import io.shardingjdbc.core.api.ShardingDataSourceFactory;
import io.shardingjdbc.core.yaml.AbstractYamlDataSourceTest; import io.shardingjdbc.core.yaml.AbstractYamlDataSourceTest;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.junit.Test; import org.junit.Test;
...@@ -61,7 +62,7 @@ public class YamlShardingWithMasterSlaveIntegrateTest extends AbstractYamlDataSo ...@@ -61,7 +62,7 @@ public class YamlShardingWithMasterSlaveIntegrateTest extends AbstractYamlDataSo
File yamlFile = new File(YamlShardingWithMasterSlaveIntegrateTest.class.getResource(filePath).toURI()); File yamlFile = new File(YamlShardingWithMasterSlaveIntegrateTest.class.getResource(filePath).toURI());
DataSource dataSource; DataSource dataSource;
if (hasDataSource) { if (hasDataSource) {
dataSource = new YamlShardingDataSource(yamlFile); dataSource = ShardingDataSourceFactory.createDataSource(yamlFile);
} else { } else {
Map<String, DataSource> dataSourceMap = Maps.asMap(Sets.newHashSet("db0_master", "db0_slave", "db1_master", "db1_slave"), new Function<String, DataSource>() { Map<String, DataSource> dataSourceMap = Maps.asMap(Sets.newHashSet("db0_master", "db0_slave", "db1_master", "db1_slave"), new Function<String, DataSource>() {
@Override @Override
...@@ -73,7 +74,7 @@ public class YamlShardingWithMasterSlaveIntegrateTest extends AbstractYamlDataSo ...@@ -73,7 +74,7 @@ public class YamlShardingWithMasterSlaveIntegrateTest extends AbstractYamlDataSo
for (Map.Entry<String, DataSource> each : dataSourceMap.entrySet()) { for (Map.Entry<String, DataSource> each : dataSourceMap.entrySet()) {
result.put(each.getKey(), each.getValue()); result.put(each.getKey(), each.getValue());
} }
dataSource = new YamlShardingDataSource(result, yamlFile); dataSource = ShardingDataSourceFactory.createDataSource(result, yamlFile);
} }
try (Connection conn = dataSource.getConnection(); try (Connection conn = dataSource.getConnection();
Statement stm = conn.createStatement()) { Statement stm = conn.createStatement()) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册