Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

提供SPI机制通过实现WallProviderCreator来自定义扩展WallProvider #5682 #5772

Merged
merged 2 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 42 additions & 6 deletions core/src/main/java/com/alibaba/druid/wall/WallFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,25 @@ public synchronized void init(DataSourceProxy dataSource) {
dbTypeName = JdbcUtils.getDbType(dataSource.getUrl(), null);
}

DbType dbType = DbType.of(this.dbTypeName);
provider = initWallProvider(dataSource, dbTypeName, config);
this.config = provider.getConfig();
provider.setName(dataSource.getName());
this.inited = true;
}

protected WallProvider initWallProvider(DataSourceProxy dataSource, String dbTypeName, WallConfig config) {
return initWallProviderInternal(dataSource, dbTypeName, config);
}

static WallProvider initWallProviderInternal(DataSourceProxy dataSource, String dbTypeName, WallConfig config) {
WallProvider provider = null;
DbType dbType = DbType.of(dbTypeName);
if (dbType == null) {
throw new IllegalStateException("dbType not support : " + this.dbTypeName + ", url " + dataSource.getUrl());
provider = initWallProviderWithSPI(dataSource, config, dbType);
if (provider == null) {
throw new IllegalStateException("dbType not support : " + dbTypeName + ", url " + dataSource.getUrl());
}
return provider;
}
switch (dbType) {
case mysql:
Expand Down Expand Up @@ -176,12 +192,32 @@ public synchronized void init(DataSourceProxy dataSource) {
provider = new ClickhouseWallProvider(config);
break;
default:
throw new IllegalStateException("dbType not support : " + dbType + ", url " + dataSource.getUrl());
provider = initWallProviderWithSPI(dataSource, config, dbType);
if (provider == null) {
throw new IllegalStateException("dbType not support : " + dbType + ", url " + dataSource.getUrl());
}
}
return provider;
}

provider.setName(dataSource.getName());

this.inited = true;
static WallProvider initWallProviderWithSPI(DataSourceProxy dataSource, WallConfig config, DbType dbType) {
List<WallProviderCreator> wallProviderCreatorList = new ArrayList<>();
ServiceLoader<WallProviderCreator> providerCreators = ServiceLoader.load(WallProviderCreator.class);
providerCreators.forEach((wallProviderCreator) -> {
wallProviderCreatorList.add(wallProviderCreator);
});
//sort wallProviderCreatorList
Collections.sort(wallProviderCreatorList, (o1, o2) -> {
return Integer.compare(o1.getOrder(), o2.getOrder());
});
for (WallProviderCreator providerCreator : providerCreators) {
WallProvider wallProvider = providerCreator.createWallConfig(dataSource, config, dbType);
if (wallProvider != null) {
LOG.debug("use wallProvider " + wallProvider.getClass().getName() + " from " + providerCreator.getClass().getName());
return wallProvider;
}
}
return null;
}

public String getDbType() {
Expand Down
23 changes: 23 additions & 0 deletions core/src/main/java/com/alibaba/druid/wall/WallProviderCreator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.alibaba.druid.wall;

import com.alibaba.druid.DbType;
import com.alibaba.druid.proxy.jdbc.DataSourceProxy;

/**
* @author lizongbo
* @since 1.2.22
*/
public interface WallProviderCreator {
/**
* @param dataSource mabye exists wall config
* @param config maybe null
* @param dbType maybe null
* @return
*/
WallProvider createWallConfig(DataSourceProxy dataSource, WallConfig config, DbType dbType);

default int getOrder() {
return 0;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.alibaba.druid.bvt.filter.wall;

import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.sql.visitor.ExportParameterVisitor;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallProvider;
import com.alibaba.druid.wall.WallVisitor;

public class NoMatchDbWallProvider extends WallProvider {
public NoMatchDbWallProvider(WallConfig config) {
super(config);
}

public NoMatchDbWallProvider(WallConfig config, DbType dbType) {
super(config, dbType);
}

@Override
public SQLStatementParser createParser(String sql) {
return null;
}

@Override
public WallVisitor createWallVisitor() {
return null;
}

@Override
public ExportParameterVisitor createExportParameterVisitor() {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.alibaba.druid.bvt.filter.wall;

import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.sql.visitor.ExportParameterVisitor;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallProvider;
import com.alibaba.druid.wall.WallVisitor;

public class NullWallProvider extends WallProvider {
public NullWallProvider(WallConfig config) {
super(config);
}

public NullWallProvider(WallConfig config, DbType dbType) {
super(config, dbType);
}

@Override
public SQLStatementParser createParser(String sql) {
return null;
}

@Override
public WallVisitor createWallVisitor() {
return null;
}

@Override
public ExportParameterVisitor createExportParameterVisitor() {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.alibaba.druid.bvt.filter.wall;

import com.alibaba.druid.DbType;
import com.alibaba.druid.proxy.jdbc.DataSourceProxy;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.sql.visitor.ExportParameterVisitor;
import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallFilter;
import com.alibaba.druid.wall.WallProvider;
import com.alibaba.druid.wall.WallProviderCreator;
import com.alibaba.druid.wall.WallVisitor;

public class Test01WallProviderCreator implements WallProviderCreator {

private static final Log LOG = LogFactory.getLog(Test01WallProviderCreator.class);
@Override
public WallProvider createWallConfig(DataSourceProxy dataSource, WallConfig config, DbType dbType) {
if (dbType == null) {
NullWallProvider nullWallProvider= new NullWallProvider(config);
LOG.warn("dbType is null so return NullWallProvider|"+nullWallProvider);
return nullWallProvider;
}
return null;
}

@Override
public int getOrder() {
return 200;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.alibaba.druid.bvt.filter.wall;

import com.alibaba.druid.DbType;
import com.alibaba.druid.proxy.jdbc.DataSourceProxy;
import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallProvider;
import com.alibaba.druid.wall.WallProviderCreator;
import com.alibaba.druid.wall.spi.MySqlWallProvider;

public class Test02WallProviderCreator implements WallProviderCreator {

private static final Log LOG = LogFactory.getLog(Test02WallProviderCreator.class);

@Override
public WallProvider createWallConfig(DataSourceProxy dataSource, WallConfig config, DbType dbType) {
LOG.warn("dbType is nomatch so return NoMatchDbWallProvider" + config + "|" + dbType);
if (config == null) {
config = new WallConfig(MySqlWallProvider.DEFAULT_CONFIG_DIR);
}
return new NoMatchDbWallProvider(config, dbType);
}

@Override
public int getOrder() {
return 100;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.alibaba.druid.bvt.filter.wall;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.wall.WallFilter;

import junit.framework.TestCase;

public class WallFilterConfigSpiForNoMatchDbTypeTest extends TestCase {

private DruidDataSource dataSource;
private WallFilter wallFilter;

protected void setUp() throws Exception {
dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.alibaba.druid.mock.MockDriver");
dataSource.setUrl("jdbc:derby:memory:spring-test;create=true");
dataSource.setFilters("wall");
dataSource.init();

wallFilter = (WallFilter) dataSource.getProxyFilters().get(0);
}

protected void tearDown() throws Exception {
dataSource.close();
}

public void test_wallFilter() throws Exception {
System.out.println("wallFilter= " + wallFilter);
System.out.println("wallFilter.getConfig()= " + wallFilter.getConfig());
assertNotNull(wallFilter.getConfig());
System.out.println("wallFilter.getConfig()= " + wallFilter.getProvider().getClass());
assertTrue(wallFilter.getProvider() instanceof NoMatchDbWallProvider);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.alibaba.druid.bvt.filter.wall;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.wall.WallFilter;

import junit.framework.TestCase;

public class WallFilterConfigSpiForNullDbTypeTest extends TestCase {

private DruidDataSource dataSource;
private WallFilter wallFilter;

protected void setUp() throws Exception {
dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.alibaba.druid.mock.MockDriver");
dataSource.setUrl("jdbc:nodb:mem:wall_test;");
dataSource.setFilters("wall");
dataSource.init();

wallFilter = (WallFilter) dataSource.getProxyFilters().get(0);
}

protected void tearDown() throws Exception {
dataSource.close();
}

public void test_wallFilter() throws Exception {
System.out.println("wallFilter= " + wallFilter);
System.out.println("wallFilter.getConfig()= " + wallFilter.getConfig());
System.out.println("wallFilter.getConfig()= " + wallFilter.getProvider().getClass());
assertNull(wallFilter.getConfig());
assertTrue(wallFilter.getProvider() instanceof NullWallProvider);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
com.alibaba.druid.bvt.filter.wall.Test01WallProviderCreator
com.alibaba.druid.bvt.filter.wall.Test02WallProviderCreator
Loading