Add MySQL DataBase (#6968)
This commit is contained in:
parent
76ac84344c
commit
3c0508d2da
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.configuration;
|
||||
|
||||
import com.alibaba.nacos.auth.util.AuthPropertyUtil;
|
||||
import org.springframework.context.annotation.Condition;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
|
||||
/**
|
||||
* Judge whether to user ExternalStorage by condition.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
public class ConditionOnExternalStorage implements Condition {
|
||||
|
||||
@Override
|
||||
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
|
||||
return !AuthPropertyUtil.isEmbeddedStorage();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.constant;
|
||||
|
||||
/**
|
||||
* PropertiesConstant.
|
||||
*
|
||||
* @author lixiaoshuang
|
||||
*/
|
||||
public class PropertiesConstant {
|
||||
|
||||
public static final String NOTIFY_CONNECT_TIMEOUT = "notifyConnectTimeout";
|
||||
|
||||
public static final String NOTIFY_SOCKET_TIMEOUT = "notifySocketTimeout";
|
||||
|
||||
public static final String IS_HEALTH_CHECK = "isHealthCheck";
|
||||
|
||||
public static final String MAX_HEALTH_CHECK_FAIL_COUNT = "maxHealthCheckFailCount";
|
||||
|
||||
public static final String MAX_CONTENT = "maxContent";
|
||||
|
||||
public static final String IS_MANAGE_CAPACITY = "isManageCapacity";
|
||||
|
||||
public static final String IS_CAPACITY_LIMIT_CHECK = "isCapacityLimitCheck";
|
||||
|
||||
public static final String DEFAULT_CLUSTER_QUOTA = "defaultClusterQuota";
|
||||
|
||||
public static final String DEFAULT_GROUP_QUOTA = "defaultGroupQuota";
|
||||
|
||||
public static final String DEFAULT_TENANT_QUOTA = "defaultTenantQuota";
|
||||
|
||||
public static final String DEFAULT_MAX_SIZE = "defaultMaxSize";
|
||||
|
||||
public static final String DEFAULT_MAX_AGGR_COUNT = "defaultMaxAggrCount";
|
||||
|
||||
public static final String DEFAULT_MAX_AGGR_SIZE = "defaultMaxAggrSize";
|
||||
|
||||
public static final String CORRECT_USAGE_DELAY = "correctUsageDelay";
|
||||
|
||||
public static final String INITIAL_EXPANSION_PERCENT = "initialExpansionPercent";
|
||||
|
||||
public static final String SPRING_DATASOURCE_PLATFORM = "spring.datasource.platform";
|
||||
|
||||
public static final String MYSQL = "mysql";
|
||||
|
||||
public static final String EMBEDDED_STORAGE = "embeddedStorage";
|
||||
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.persist;
|
||||
|
||||
import com.alibaba.nacos.auth.configuration.ConditionOnExternalStorage;
|
||||
import com.alibaba.nacos.auth.model.Page;
|
||||
import com.alibaba.nacos.auth.model.PermissionInfo;
|
||||
import com.alibaba.nacos.auth.persist.repository.PaginationHelper;
|
||||
import com.alibaba.nacos.auth.persist.repository.externel.ExternalStoragePersistServiceImpl;
|
||||
import com.alibaba.nacos.auth.util.LogUtil;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.jdbc.CannotGetJdbcConnectionException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Implemetation of ExternalPermissionPersistServiceImpl.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
@Conditional(value = ConditionOnExternalStorage.class)
|
||||
@Component
|
||||
public class ExternalPermissionPersistServiceImpl implements PermissionPersistService {
|
||||
|
||||
public static final PermissionRowMapper PERMISSION_ROW_MAPPER = new PermissionRowMapper();
|
||||
|
||||
@Autowired
|
||||
private ExternalStoragePersistServiceImpl persistService;
|
||||
|
||||
private JdbcTemplate jt;
|
||||
|
||||
@PostConstruct
|
||||
protected void init() {
|
||||
jt = persistService.getJdbcTemplate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<PermissionInfo> getPermissions(String role, int pageNo, int pageSize) {
|
||||
PaginationHelper<PermissionInfo> helper = persistService.createPaginationHelper();
|
||||
|
||||
String sqlCountRows = "SELECT count(*) FROM permissions WHERE ";
|
||||
String sqlFetchRows = "SELECT role,resource,action FROM permissions WHERE ";
|
||||
|
||||
String where = " role= ? ";
|
||||
List<String> params = new ArrayList<>();
|
||||
if (StringUtils.isNotBlank(role)) {
|
||||
params = Collections.singletonList(role);
|
||||
} else {
|
||||
where = " 1=1 ";
|
||||
}
|
||||
|
||||
try {
|
||||
Page<PermissionInfo> pageInfo = helper
|
||||
.fetchPage(sqlCountRows + where, sqlFetchRows + where, params.toArray(), pageNo,
|
||||
pageSize, PERMISSION_ROW_MAPPER);
|
||||
|
||||
if (pageInfo == null) {
|
||||
pageInfo = new Page<>();
|
||||
pageInfo.setTotalCount(0);
|
||||
pageInfo.setPageItems(new ArrayList<>());
|
||||
}
|
||||
|
||||
return pageInfo;
|
||||
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.FATAL_LOG.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class PermissionRowMapper implements RowMapper<PermissionInfo> {
|
||||
|
||||
@Override
|
||||
public PermissionInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||
PermissionInfo info = new PermissionInfo();
|
||||
info.setResource(rs.getString("resource"));
|
||||
info.setAction(rs.getString("action"));
|
||||
info.setRole(rs.getString("role"));
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.persist;
|
||||
|
||||
import com.alibaba.nacos.auth.configuration.ConditionOnExternalStorage;
|
||||
import com.alibaba.nacos.auth.model.Page;
|
||||
import com.alibaba.nacos.auth.persist.repository.PaginationHelper;
|
||||
import com.alibaba.nacos.auth.persist.repository.externel.ExternalStoragePersistServiceImpl;
|
||||
import com.alibaba.nacos.auth.roles.RoleInfo;
|
||||
import com.alibaba.nacos.auth.util.LogUtil;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.jdbc.CannotGetJdbcConnectionException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Implemetation of ExternalRolePersistServiceImpl.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
@Conditional(value = ConditionOnExternalStorage.class)
|
||||
@Component
|
||||
public class ExternalRolePersistServiceImpl implements RolePersistService {
|
||||
|
||||
public static final RoleInfoRowMapper ROLE_INFO_ROW_MAPPER = new RoleInfoRowMapper();
|
||||
|
||||
@Autowired
|
||||
private ExternalStoragePersistServiceImpl persistService;
|
||||
|
||||
private JdbcTemplate jt;
|
||||
|
||||
@PostConstruct
|
||||
protected void init() {
|
||||
jt = persistService.getJdbcTemplate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<RoleInfo> getRolesByUserName(String username, int pageNo, int pageSize) {
|
||||
|
||||
PaginationHelper<RoleInfo> helper = persistService.createPaginationHelper();
|
||||
|
||||
String sqlCountRows = "SELECT count(*) FROM roles WHERE ";
|
||||
|
||||
String sqlFetchRows = "SELECT role,username FROM roles WHERE ";
|
||||
|
||||
String where = " username= ? ";
|
||||
List<String> params = new ArrayList<>();
|
||||
if (StringUtils.isNotBlank(username)) {
|
||||
params = Collections.singletonList(username);
|
||||
} else {
|
||||
where = " 1=1 ";
|
||||
}
|
||||
|
||||
try {
|
||||
return helper.fetchPage(sqlCountRows + where, sqlFetchRows + where, params.toArray(), pageNo, pageSize,
|
||||
ROLE_INFO_ROW_MAPPER);
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.FATAL_LOG.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class RoleInfoRowMapper implements RowMapper<RoleInfo> {
|
||||
|
||||
@Override
|
||||
public RoleInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||
RoleInfo roleInfo = new RoleInfo();
|
||||
roleInfo.setRole(rs.getString("role"));
|
||||
roleInfo.setUsername(rs.getString("username"));
|
||||
return roleInfo;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.persist;
|
||||
|
||||
import com.alibaba.nacos.auth.configuration.ConditionOnExternalStorage;
|
||||
import com.alibaba.nacos.auth.model.Page;
|
||||
import com.alibaba.nacos.auth.persist.repository.PaginationHelper;
|
||||
import com.alibaba.nacos.auth.persist.repository.externel.ExternalStoragePersistServiceImpl;
|
||||
import com.alibaba.nacos.auth.users.User;
|
||||
import com.alibaba.nacos.auth.util.LogUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.jdbc.CannotGetJdbcConnectionException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Implemetation of ExternalUserPersistServiceImpl.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
@Conditional(value = ConditionOnExternalStorage.class)
|
||||
@Component
|
||||
public class ExternalUserPersistServiceImpl implements UserPersistService {
|
||||
|
||||
public static final RowMapper<User> USER_ROW_MAPPER = new UserRowMapper();
|
||||
|
||||
@Autowired
|
||||
private ExternalStoragePersistServiceImpl persistService;
|
||||
|
||||
private JdbcTemplate jt;
|
||||
|
||||
@PostConstruct
|
||||
protected void init() {
|
||||
jt = persistService.getJdbcTemplate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute create user operation.
|
||||
*
|
||||
* @param username username string value.
|
||||
* @param password password string value.
|
||||
*/
|
||||
@Override
|
||||
public void createUser(String username, String password) {
|
||||
String sql = "INSERT INTO users (username, password, enabled) VALUES (?, ?, ?)";
|
||||
|
||||
try {
|
||||
jt.update(sql, username, password, true);
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.FATAL_LOG.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute find user by username operation.
|
||||
*
|
||||
* @param username username string value.
|
||||
* @return User model.
|
||||
*/
|
||||
@Override
|
||||
public User findUserByUsername(String username) {
|
||||
String sql = "SELECT username,password FROM users WHERE username=? ";
|
||||
try {
|
||||
return this.jt.queryForObject(sql, new Object[] {username}, USER_ROW_MAPPER);
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.FATAL_LOG.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
} catch (EmptyResultDataAccessException e) {
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
LogUtil.FATAL_LOG.error("[db-other-error]" + e.getMessage(), e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<User> getUsers(int pageNo, int pageSize) {
|
||||
|
||||
PaginationHelper<User> helper = persistService.createPaginationHelper();
|
||||
|
||||
String sqlCountRows = "SELECT count(*) FROM users WHERE ";
|
||||
|
||||
String sqlFetchRows = "SELECT username,password FROM users WHERE ";
|
||||
|
||||
String where = " 1=1 ";
|
||||
|
||||
try {
|
||||
Page<User> pageInfo = helper
|
||||
.fetchPage(sqlCountRows + where, sqlFetchRows + where, new ArrayList<String>().toArray(), pageNo,
|
||||
pageSize, USER_ROW_MAPPER);
|
||||
if (pageInfo == null) {
|
||||
pageInfo = new Page<>();
|
||||
pageInfo.setTotalCount(0);
|
||||
pageInfo.setPageItems(new ArrayList<>());
|
||||
}
|
||||
return pageInfo;
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
LogUtil.FATAL_LOG.error("[db-error] " + e.toString(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class UserRowMapper implements RowMapper<User> {
|
||||
|
||||
@Override
|
||||
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||
User user = new User();
|
||||
user.setUsername(rs.getString("username"));
|
||||
user.setPassword(rs.getString("password"));
|
||||
return user;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.persist.datasource;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.springframework.boot.context.properties.bind.Bindable;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* DataSource pool properties.
|
||||
*
|
||||
* <p>Nacos server use HikariCP as the datasource pool. So the basic pool properties will based on {@link
|
||||
* HikariDataSource}.
|
||||
*
|
||||
* @author xiweng.yy
|
||||
*/
|
||||
public class DataSourcePoolProperties {
|
||||
|
||||
public static final long DEFAULT_CONNECTION_TIMEOUT = TimeUnit.SECONDS.toMillis(30L);
|
||||
|
||||
public static final long DEFAULT_VALIDATION_TIMEOUT = TimeUnit.SECONDS.toMillis(10L);
|
||||
|
||||
public static final int DEFAULT_MAX_POOL_SIZE = 20;
|
||||
|
||||
public static final int DEFAULT_MINIMUM_IDLE = 2;
|
||||
|
||||
private final HikariDataSource dataSource;
|
||||
|
||||
private DataSourcePoolProperties() {
|
||||
dataSource = new HikariDataSource();
|
||||
dataSource.setConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT);
|
||||
dataSource.setValidationTimeout(DEFAULT_VALIDATION_TIMEOUT);
|
||||
dataSource.setMaximumPoolSize(DEFAULT_MAX_POOL_SIZE);
|
||||
dataSource.setMinimumIdle(DEFAULT_MINIMUM_IDLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build new Hikari config.
|
||||
*
|
||||
* @return new hikari config
|
||||
*/
|
||||
public static DataSourcePoolProperties build(Environment environment) {
|
||||
DataSourcePoolProperties result = new DataSourcePoolProperties();
|
||||
Binder.get(environment).bind("db.pool.config", Bindable.ofInstance(result.getDataSource()));
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setDriverClassName(final String driverClassName) {
|
||||
dataSource.setDriverClassName(driverClassName);
|
||||
}
|
||||
|
||||
public void setJdbcUrl(final String jdbcUrl) {
|
||||
dataSource.setJdbcUrl(jdbcUrl);
|
||||
}
|
||||
|
||||
public void setUsername(final String username) {
|
||||
dataSource.setUsername(username);
|
||||
}
|
||||
|
||||
public void setPassword(final String password) {
|
||||
dataSource.setPassword(password);
|
||||
}
|
||||
|
||||
public HikariDataSource getDataSource() {
|
||||
return dataSource;
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.persist.datasource;
|
||||
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Datasource interface.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public interface DataSourceService {
|
||||
|
||||
/**
|
||||
* Initialize the relevant resource information.
|
||||
*
|
||||
* @throws Exception exception.
|
||||
*/
|
||||
void init() throws Exception;
|
||||
|
||||
/**
|
||||
* Reload.
|
||||
*
|
||||
* @throws IOException exception.
|
||||
*/
|
||||
void reload() throws IOException;
|
||||
|
||||
/**
|
||||
* Check master db.
|
||||
*
|
||||
* @return is master.
|
||||
*/
|
||||
boolean checkMasterWritable();
|
||||
|
||||
/**
|
||||
* Get jdbc template.
|
||||
*
|
||||
* @return JdbcTemplate.
|
||||
*/
|
||||
JdbcTemplate getJdbcTemplate();
|
||||
|
||||
/**
|
||||
* Get transaction template.
|
||||
*
|
||||
* @return TransactionTemplate.
|
||||
*/
|
||||
TransactionTemplate getTransactionTemplate();
|
||||
|
||||
/**
|
||||
* Get current db url.
|
||||
*
|
||||
* @return database url
|
||||
*/
|
||||
String getCurrentDbUrl();
|
||||
|
||||
/**
|
||||
* Get heath information.
|
||||
*
|
||||
* @return heath info.
|
||||
*/
|
||||
String getHealth();
|
||||
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.persist.datasource;
|
||||
|
||||
import com.alibaba.nacos.auth.util.AuthPropertyUtil;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Datasource adapter.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
@Component
|
||||
public class DynamicDataSource {
|
||||
|
||||
private DataSourceService localDataSourceService = null;
|
||||
|
||||
private DataSourceService basicDataSourceService = null;
|
||||
|
||||
private static final DynamicDataSource INSTANCE = new DynamicDataSource();
|
||||
|
||||
public static DynamicDataSource getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public synchronized DataSourceService getDataSource() {
|
||||
try {
|
||||
|
||||
// Embedded storage is used by default in stand-alone mode
|
||||
// In cluster mode, external databases are used by default
|
||||
|
||||
if (AuthPropertyUtil.isEmbeddedStorage()) {
|
||||
if (localDataSourceService == null) {
|
||||
localDataSourceService = new LocalDataSourceServiceImpl();
|
||||
localDataSourceService.init();
|
||||
}
|
||||
return localDataSourceService;
|
||||
} else {
|
||||
if (basicDataSourceService == null) {
|
||||
basicDataSourceService = new ExternalDataSourceServiceImpl();
|
||||
basicDataSourceService.init();
|
||||
}
|
||||
return basicDataSourceService;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.persist.datasource;
|
||||
|
||||
import com.alibaba.nacos.auth.util.Preconditions;
|
||||
|
||||
import com.alibaba.nacos.common.utils.CollectionUtils;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.springframework.boot.context.properties.bind.Bindable;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.alibaba.nacos.common.utils.CollectionUtils.getOrDefault;
|
||||
|
||||
/**
|
||||
* Properties of external DataSource.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class ExternalDataSourceProperties {
|
||||
|
||||
private static final String JDBC_DRIVER_NAME = "com.mysql.cj.jdbc.Driver";
|
||||
|
||||
private static final String TEST_QUERY = "SELECT 1";
|
||||
|
||||
private Integer num;
|
||||
|
||||
private List<String> url = new ArrayList<>();
|
||||
|
||||
private List<String> user = new ArrayList<>();
|
||||
|
||||
private List<String> password = new ArrayList<>();
|
||||
|
||||
public void setNum(Integer num) {
|
||||
this.num = num;
|
||||
}
|
||||
|
||||
public void setUrl(List<String> url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public void setUser(List<String> user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public void setPassword(List<String> password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build serveral HikariDataSource.
|
||||
*
|
||||
* @param environment {@link Environment}
|
||||
* @param callback Callback function when constructing data source
|
||||
* @return List of {@link HikariDataSource}
|
||||
*/
|
||||
List<HikariDataSource> build(Environment environment, Callback<HikariDataSource> callback) {
|
||||
List<HikariDataSource> dataSources = new ArrayList<>();
|
||||
Binder.get(environment).bind("db", Bindable.ofInstance(this));
|
||||
Preconditions.checkArgument(Objects.nonNull(num), "db.num is null");
|
||||
Preconditions.checkArgument(CollectionUtils.isNotEmpty(user), "db.user or db.user.[index] is null");
|
||||
Preconditions.checkArgument(CollectionUtils.isNotEmpty(password), "db.password or db.password.[index] is null");
|
||||
for (int index = 0; index < num; index++) {
|
||||
int currentSize = index + 1;
|
||||
Preconditions.checkArgument(url.size() >= currentSize, "db.url.%s is null", index);
|
||||
DataSourcePoolProperties poolProperties = DataSourcePoolProperties.build(environment);
|
||||
poolProperties.setDriverClassName(JDBC_DRIVER_NAME);
|
||||
poolProperties.setJdbcUrl(url.get(index).trim());
|
||||
poolProperties.setUsername(getOrDefault(user, index, user.get(0)).trim());
|
||||
poolProperties.setPassword(getOrDefault(password, index, password.get(0)).trim());
|
||||
HikariDataSource ds = poolProperties.getDataSource();
|
||||
ds.setConnectionTestQuery(TEST_QUERY);
|
||||
ds.setIdleTimeout(TimeUnit.MINUTES.toMillis(10L));
|
||||
ds.setConnectionTimeout(TimeUnit.SECONDS.toMillis(3L));
|
||||
dataSources.add(ds);
|
||||
callback.accept(ds);
|
||||
}
|
||||
Preconditions.checkArgument(CollectionUtils.isNotEmpty(dataSources), "no datasource available");
|
||||
return dataSources;
|
||||
}
|
||||
|
||||
interface Callback<D> {
|
||||
|
||||
/**
|
||||
* Perform custom logic.
|
||||
*
|
||||
* @param datasource dataSource.
|
||||
*/
|
||||
void accept(D datasource);
|
||||
}
|
||||
}
|
@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.persist.datasource;
|
||||
|
||||
import com.alibaba.nacos.auth.util.AuthPropertyUtil;
|
||||
import com.alibaba.nacos.common.utils.ConvertUtils;
|
||||
import com.alibaba.nacos.common.utils.InternetAddressUtil;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.sys.env.EnvUtil;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.CannotGetJdbcConnectionException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import static com.alibaba.nacos.auth.util.LogUtil.DEFAULT_LOG;
|
||||
import static com.alibaba.nacos.auth.util.LogUtil.FATAL_LOG;
|
||||
|
||||
/**
|
||||
* Base data source.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class ExternalDataSourceServiceImpl implements DataSourceService {
|
||||
|
||||
/**
|
||||
* JDBC execute timeout value, unit:second.
|
||||
*/
|
||||
private int queryTimeout = 3;
|
||||
|
||||
private static final int TRANSACTION_QUERY_TIMEOUT = 5;
|
||||
|
||||
private static final int DB_MASTER_SELECT_THRESHOLD = 1;
|
||||
|
||||
private static final String DB_LOAD_ERROR_MSG = "[db-load-error]load jdbc.properties error";
|
||||
|
||||
private List<HikariDataSource> dataSourceList = new ArrayList<>();
|
||||
|
||||
private JdbcTemplate jt;
|
||||
|
||||
private DataSourceTransactionManager tm;
|
||||
|
||||
private TransactionTemplate tjt;
|
||||
|
||||
private JdbcTemplate testMasterJT;
|
||||
|
||||
private JdbcTemplate testMasterWritableJT;
|
||||
|
||||
private volatile List<JdbcTemplate> testJtList;
|
||||
|
||||
private volatile List<Boolean> isHealthList;
|
||||
|
||||
private volatile int masterIndex;
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
queryTimeout = ConvertUtils.toInt(System.getProperty("QUERYTIMEOUT"), 3);
|
||||
jt = new JdbcTemplate();
|
||||
// Set the maximum number of records to prevent memory expansion
|
||||
jt.setMaxRows(50000);
|
||||
jt.setQueryTimeout(queryTimeout);
|
||||
|
||||
testMasterJT = new JdbcTemplate();
|
||||
testMasterJT.setQueryTimeout(queryTimeout);
|
||||
|
||||
testMasterWritableJT = new JdbcTemplate();
|
||||
// Prevent the login interface from being too long because the main library is not available
|
||||
testMasterWritableJT.setQueryTimeout(1);
|
||||
|
||||
// Database health check
|
||||
|
||||
testJtList = new ArrayList<JdbcTemplate>();
|
||||
isHealthList = new ArrayList<Boolean>();
|
||||
|
||||
tm = new DataSourceTransactionManager();
|
||||
tjt = new TransactionTemplate(tm);
|
||||
|
||||
// Transaction timeout needs to be distinguished from ordinary operations.
|
||||
tjt.setTimeout(TRANSACTION_QUERY_TIMEOUT);
|
||||
if (AuthPropertyUtil.isUseExternalDB()) {
|
||||
try {
|
||||
reload();
|
||||
} catch (IOException e) {
|
||||
FATAL_LOG.error("[ExternalDataSourceService] dats source reload error", e);
|
||||
throw new RuntimeException(DB_LOAD_ERROR_MSG);
|
||||
}
|
||||
/*
|
||||
if (this.dataSourceList.size() > DB_MASTER_SELECT_THRESHOLD) {
|
||||
ConfigExecutor.scheduleConfigTask(new SelectMasterTask(), 10, 10, TimeUnit.SECONDS);
|
||||
}
|
||||
ConfigExecutor.scheduleConfigTask(new CheckDbHealthTask(), 10, 10, TimeUnit.SECONDS);
|
||||
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void reload() throws IOException {
|
||||
try {
|
||||
dataSourceList = new ExternalDataSourceProperties()
|
||||
.build(EnvUtil.getEnvironment(), (dataSource) -> {
|
||||
JdbcTemplate jdbcTemplate = new JdbcTemplate();
|
||||
jdbcTemplate.setQueryTimeout(queryTimeout);
|
||||
jdbcTemplate.setDataSource(dataSource);
|
||||
testJtList.add(jdbcTemplate);
|
||||
isHealthList.add(Boolean.TRUE);
|
||||
});
|
||||
new SelectMasterTask().run();
|
||||
//new CheckDbHealthTask().run();
|
||||
} catch (RuntimeException e) {
|
||||
FATAL_LOG.error(DB_LOAD_ERROR_MSG, e);
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkMasterWritable() {
|
||||
|
||||
testMasterWritableJT.setDataSource(jt.getDataSource());
|
||||
// Prevent the login interface from being too long because the main library is not available
|
||||
testMasterWritableJT.setQueryTimeout(1);
|
||||
String sql = " SELECT @@read_only ";
|
||||
|
||||
try {
|
||||
Integer result = testMasterWritableJT.queryForObject(sql, Integer.class);
|
||||
if (result == null) {
|
||||
return false;
|
||||
} else {
|
||||
return result == 0;
|
||||
}
|
||||
} catch (CannotGetJdbcConnectionException e) {
|
||||
FATAL_LOG.error("[db-error] " + e.toString(), e);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcTemplate getJdbcTemplate() {
|
||||
return this.jt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionTemplate getTransactionTemplate() {
|
||||
return this.tjt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentDbUrl() {
|
||||
DataSource ds = this.jt.getDataSource();
|
||||
if (ds == null) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
HikariDataSource bds = (HikariDataSource) ds;
|
||||
return bds.getJdbcUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHealth() {
|
||||
for (int i = 0; i < isHealthList.size(); i++) {
|
||||
if (!isHealthList.get(i)) {
|
||||
if (i == masterIndex) {
|
||||
// The master is unhealthy.
|
||||
return "DOWN:" + InternetAddressUtil.getIPFromString(dataSourceList.get(i).getJdbcUrl());
|
||||
} else {
|
||||
// The slave is unhealthy.
|
||||
return "WARN:" + InternetAddressUtil.getIPFromString(dataSourceList.get(i).getJdbcUrl());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "UP";
|
||||
}
|
||||
|
||||
class SelectMasterTask implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (DEFAULT_LOG.isDebugEnabled()) {
|
||||
DEFAULT_LOG.debug("check master db.");
|
||||
}
|
||||
boolean isFound = false;
|
||||
|
||||
int index = -1;
|
||||
for (HikariDataSource ds : dataSourceList) {
|
||||
index++;
|
||||
testMasterJT.setDataSource(ds);
|
||||
testMasterJT.setQueryTimeout(queryTimeout);
|
||||
try {
|
||||
testMasterJT.update("DELETE FROM config_info WHERE data_id='com.alibaba.nacos.testMasterDB'");
|
||||
if (jt.getDataSource() != ds) {
|
||||
FATAL_LOG.warn("[master-db] {}", ds.getJdbcUrl());
|
||||
}
|
||||
jt.setDataSource(ds);
|
||||
tm.setDataSource(ds);
|
||||
isFound = true;
|
||||
masterIndex = index;
|
||||
break;
|
||||
} catch (DataAccessException e) { // read only
|
||||
FATAL_LOG.warn("[master-db] master db access error", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isFound) {
|
||||
FATAL_LOG.error("[master-db] master db not found.");
|
||||
//MetricsMonitor.getDbException().increment();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
|
||||
class CheckDbHealthTask implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (DEFAULT_LOG.isDebugEnabled()) {
|
||||
DEFAULT_LOG.debug("check db health.");
|
||||
}
|
||||
String sql = "SELECT * FROM config_info_beta WHERE id = 1";
|
||||
|
||||
for (int i = 0; i < testJtList.size(); i++) {
|
||||
JdbcTemplate jdbcTemplate = testJtList.get(i);
|
||||
try {
|
||||
jdbcTemplate.query(sql, CONFIG_INFO4BETA_ROW_MAPPER);
|
||||
isHealthList.set(i, Boolean.TRUE);
|
||||
} catch (DataAccessException e) {
|
||||
if (i == masterIndex) {
|
||||
FATAL_LOG.error("[db-error] master db {} down.",
|
||||
InternetAddressUtil.getIPFromString(dataSourceList.get(i).getJdbcUrl()));
|
||||
} else {
|
||||
FATAL_LOG.error("[db-error] slave db {} down.",
|
||||
InternetAddressUtil.getIPFromString(dataSourceList.get(i).getJdbcUrl()));
|
||||
}
|
||||
isHealthList.set(i, Boolean.FALSE);
|
||||
|
||||
MetricsMonitor.getDbException().increment();
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.persist.datasource;
|
||||
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException;
|
||||
import com.alibaba.nacos.auth.util.AuthPropertyUtil;
|
||||
import com.alibaba.nacos.auth.util.LogUtil;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.sys.env.EnvUtil;
|
||||
import com.alibaba.nacos.sys.utils.DiskUtils;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.sql.DataSource;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Paths;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* local data source.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class LocalDataSourceServiceImpl implements DataSourceService {
|
||||
|
||||
private final String jdbcDriverName = "org.apache.derby.jdbc.EmbeddedDriver";
|
||||
|
||||
private final String userName = "nacos";
|
||||
|
||||
private final String password = "nacos";
|
||||
|
||||
private final String derbyBaseDir = "data" + File.separator + "derby-data";
|
||||
|
||||
private final String derbyShutdownErrMsg = "Derby system shutdown.";
|
||||
|
||||
private volatile JdbcTemplate jt;
|
||||
|
||||
private volatile TransactionTemplate tjt;
|
||||
|
||||
private boolean initialize = false;
|
||||
|
||||
private boolean jdbcTemplateInit = false;
|
||||
|
||||
private String healthStatus = "UP";
|
||||
|
||||
private static final String ENCODE = "UTF-8";
|
||||
|
||||
@PostConstruct
|
||||
@Override
|
||||
public synchronized void init() throws Exception {
|
||||
if (AuthPropertyUtil.isUseExternalDB()) {
|
||||
return;
|
||||
}
|
||||
if (!initialize) {
|
||||
LogUtil.DEFAULT_LOG.info("use local db service for init");
|
||||
final String jdbcUrl =
|
||||
"jdbc:derby:" + Paths.get(EnvUtil.getNacosHome(), derbyBaseDir).toString()
|
||||
+ ";create=true";
|
||||
initialize(jdbcUrl);
|
||||
initialize = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void reload() {
|
||||
DataSource ds = jt.getDataSource();
|
||||
if (ds == null) {
|
||||
throw new RuntimeException("datasource is null");
|
||||
}
|
||||
try {
|
||||
execute(ds.getConnection(), "META-INF/schema.sql");
|
||||
} catch (Exception e) {
|
||||
if (LogUtil.DEFAULT_LOG.isErrorEnabled()) {
|
||||
LogUtil.DEFAULT_LOG.error(e.getMessage(), e);
|
||||
}
|
||||
throw new NacosRuntimeException(NacosException.SERVER_ERROR, "load schema.sql error.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public DataSource getDatasource() {
|
||||
return jt.getDataSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean and reopen Derby.
|
||||
*
|
||||
* @throws Exception exception.
|
||||
*/
|
||||
public void cleanAndReopenDerby() throws Exception {
|
||||
doDerbyClean();
|
||||
final String jdbcUrl =
|
||||
"jdbc:derby:" + Paths.get(EnvUtil.getNacosHome(), derbyBaseDir).toString() + ";create=true";
|
||||
initialize(jdbcUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore derby.
|
||||
*
|
||||
* @param jdbcUrl jdbcUrl string value.
|
||||
* @param callable callable.
|
||||
* @throws Exception exception.
|
||||
*/
|
||||
public void restoreDerby(String jdbcUrl, Callable<Void> callable) throws Exception {
|
||||
doDerbyClean();
|
||||
callable.call();
|
||||
initialize(jdbcUrl);
|
||||
}
|
||||
|
||||
private void doDerbyClean() throws Exception {
|
||||
LogUtil.DEFAULT_LOG.warn("use local db service for reopenDerby");
|
||||
try {
|
||||
DriverManager.getConnection("jdbc:derby:;shutdown=true");
|
||||
} catch (Exception e) {
|
||||
// An error is thrown when the Derby shutdown is executed, which should be ignored
|
||||
if (!StringUtils.containsIgnoreCase(e.getMessage(), derbyShutdownErrMsg)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
DiskUtils.deleteDirectory(Paths.get(EnvUtil.getNacosHome(), derbyBaseDir).toString());
|
||||
}
|
||||
|
||||
private synchronized void initialize(String jdbcUrl) {
|
||||
DataSourcePoolProperties poolProperties = DataSourcePoolProperties.build(EnvUtil.getEnvironment());
|
||||
poolProperties.setDriverClassName(jdbcDriverName);
|
||||
poolProperties.setJdbcUrl(jdbcUrl);
|
||||
poolProperties.setUsername(userName);
|
||||
poolProperties.setPassword(password);
|
||||
HikariDataSource ds = poolProperties.getDataSource();
|
||||
DataSourceTransactionManager tm = new DataSourceTransactionManager();
|
||||
tm.setDataSource(ds);
|
||||
if (jdbcTemplateInit) {
|
||||
jt.setDataSource(ds);
|
||||
tjt.setTransactionManager(tm);
|
||||
} else {
|
||||
jt = new JdbcTemplate();
|
||||
jt.setMaxRows(50000);
|
||||
jt.setQueryTimeout(5000);
|
||||
jt.setDataSource(ds);
|
||||
tjt = new TransactionTemplate(tm);
|
||||
tjt.setTimeout(5000);
|
||||
jdbcTemplateInit = true;
|
||||
}
|
||||
reload();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkMasterWritable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcTemplate getJdbcTemplate() {
|
||||
return jt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionTemplate getTransactionTemplate() {
|
||||
return tjt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentDbUrl() {
|
||||
return "jdbc:derby:" + EnvUtil.getNacosHome() + File.separator + derbyBaseDir + ";create=true";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHealth() {
|
||||
return healthStatus;
|
||||
}
|
||||
|
||||
public void setHealthStatus(String healthStatus) {
|
||||
this.healthStatus = healthStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load sql.
|
||||
*
|
||||
* @param sqlFile sql.
|
||||
* @return sqls.
|
||||
* @throws Exception Exception.
|
||||
*/
|
||||
private List<String> loadSql(String sqlFile) throws Exception {
|
||||
List<String> sqlList = new ArrayList<String>();
|
||||
InputStream sqlFileIn = null;
|
||||
try {
|
||||
File file = new File(
|
||||
EnvUtil.getNacosHome() + File.separator + "conf" + File.separator + "schema.sql");
|
||||
if (StringUtils.isBlank(EnvUtil.getNacosHome()) || !file.exists()) {
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
URL url = classLoader.getResource(sqlFile);
|
||||
sqlFileIn = url.openStream();
|
||||
} else {
|
||||
sqlFileIn = new FileInputStream(file);
|
||||
}
|
||||
|
||||
StringBuilder sqlSb = new StringBuilder();
|
||||
byte[] buff = new byte[1024];
|
||||
int byteRead = 0;
|
||||
while ((byteRead = sqlFileIn.read(buff)) != -1) {
|
||||
sqlSb.append(new String(buff, 0, byteRead, ENCODE));
|
||||
}
|
||||
|
||||
String[] sqlArr = sqlSb.toString().split(";");
|
||||
for (int i = 0; i < sqlArr.length; i++) {
|
||||
String sql = sqlArr[i].replaceAll("--.*", "").trim();
|
||||
if (StringUtils.isNotEmpty(sql)) {
|
||||
sqlList.add(sql);
|
||||
}
|
||||
}
|
||||
return sqlList;
|
||||
} catch (Exception ex) {
|
||||
throw new Exception(ex.getMessage());
|
||||
} finally {
|
||||
IoUtils.closeQuietly(sqlFileIn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute sql.
|
||||
*
|
||||
* @param conn connect.
|
||||
* @param sqlFile sql.
|
||||
* @throws Exception Exception.
|
||||
*/
|
||||
private void execute(Connection conn, String sqlFile) throws Exception {
|
||||
try (Statement stmt = conn.createStatement()) {
|
||||
List<String> sqlList = loadSql(sqlFile);
|
||||
for (String sql : sqlList) {
|
||||
try {
|
||||
stmt.execute(sql);
|
||||
} catch (Exception e) {
|
||||
LogUtil.DEFAULT_LOG.warn(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.persist.repository;
|
||||
|
||||
import com.alibaba.nacos.auth.model.Page;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
|
||||
|
||||
/**
|
||||
* Pagination Utils interface.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
@SuppressWarnings("PMD.AbstractMethodOrInterfaceMethodMustUseJavadocRule")
|
||||
public interface PaginationHelper<E> {
|
||||
|
||||
Page<E> fetchPage(final String sqlCountRows, final String sqlFetchRows, final Object[] args, final int pageNo,
|
||||
final int pageSize, final RowMapper<E> rowMapper);
|
||||
|
||||
Page<E> fetchPage(final String sqlCountRows, final String sqlFetchRows, final Object[] args, final int pageNo,
|
||||
final int pageSize, final Long lastMaxId, final RowMapper<E> rowMapper);
|
||||
|
||||
Page<E> fetchPageLimit(final String sqlCountRows, final String sqlFetchRows, final Object[] args, final int pageNo,
|
||||
final int pageSize, final RowMapper<E> rowMapper);
|
||||
|
||||
Page<E> fetchPageLimit(final String sqlCountRows, final Object[] args1, final String sqlFetchRows,
|
||||
final Object[] args2, final int pageNo, final int pageSize, final RowMapper<E> rowMapper);
|
||||
|
||||
Page<E> fetchPageLimit(final String sqlFetchRows, final Object[] args, final int pageNo, final int pageSize,
|
||||
final RowMapper<E> rowMapper);
|
||||
|
||||
}
|
@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.persist.repository.externel;
|
||||
|
||||
import com.alibaba.nacos.auth.model.Page;
|
||||
import com.alibaba.nacos.auth.persist.repository.PaginationHelper;
|
||||
import com.alibaba.nacos.auth.util.AuthPropertyUtil;
|
||||
import com.alibaba.nacos.sys.env.EnvUtil;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* External Storage Pagination utils.
|
||||
*
|
||||
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
|
||||
*/
|
||||
|
||||
class ExternalStoragePaginationHelperImpl<E> implements PaginationHelper {
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
|
||||
public ExternalStoragePaginationHelperImpl(JdbcTemplate jdbcTemplate) {
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take paging.
|
||||
*
|
||||
* @param sqlCountRows query total SQL
|
||||
* @param sqlFetchRows query data sql
|
||||
* @param args query parameters
|
||||
* @param pageNo page number
|
||||
* @param pageSize page size
|
||||
* @param rowMapper {@link RowMapper}
|
||||
* @return Paginated data {@code <E>}
|
||||
*/
|
||||
@Override
|
||||
public Page<E> fetchPage(final String sqlCountRows, final String sqlFetchRows, final Object[] args,
|
||||
final int pageNo, final int pageSize, final RowMapper rowMapper) {
|
||||
return fetchPage(sqlCountRows, sqlFetchRows, args, pageNo, pageSize, null, rowMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<E> fetchPage(final String sqlCountRows, final String sqlFetchRows, final Object[] args,
|
||||
final int pageNo, final int pageSize, final Long lastMaxId, final RowMapper rowMapper) {
|
||||
if (pageNo <= 0 || pageSize <= 0) {
|
||||
throw new IllegalArgumentException("pageNo and pageSize must be greater than zero");
|
||||
}
|
||||
|
||||
// Query the total number of current records.
|
||||
Integer rowCountInt = jdbcTemplate.queryForObject(sqlCountRows, args, Integer.class);
|
||||
if (rowCountInt == null) {
|
||||
throw new IllegalArgumentException("fetchPageLimit error");
|
||||
}
|
||||
|
||||
// Compute pages count
|
||||
int pageCount = rowCountInt / pageSize;
|
||||
if (rowCountInt > pageSize * pageCount) {
|
||||
pageCount++;
|
||||
}
|
||||
|
||||
// Create Page object
|
||||
final Page<E> page = new Page<E>();
|
||||
page.setPageNumber(pageNo);
|
||||
page.setPagesAvailable(pageCount);
|
||||
page.setTotalCount(rowCountInt);
|
||||
|
||||
if (pageNo > pageCount) {
|
||||
return page;
|
||||
}
|
||||
|
||||
final int startRow = (pageNo - 1) * pageSize;
|
||||
String selectSql = "";
|
||||
if (isDerby()) {
|
||||
selectSql = sqlFetchRows + " OFFSET " + startRow + " ROWS FETCH NEXT " + pageSize + " ROWS ONLY";
|
||||
} else if (lastMaxId != null) {
|
||||
selectSql = sqlFetchRows + " AND id > " + lastMaxId + " ORDER BY id ASC" + " LIMIT " + 0 + "," + pageSize;
|
||||
} else {
|
||||
selectSql = sqlFetchRows + " LIMIT " + startRow + "," + pageSize;
|
||||
}
|
||||
|
||||
List<E> result = jdbcTemplate.query(selectSql, args, rowMapper);
|
||||
for (E item : result) {
|
||||
page.getPageItems().add(item);
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<E> fetchPageLimit(final String sqlCountRows, final String sqlFetchRows, final Object[] args,
|
||||
final int pageNo, final int pageSize, final RowMapper rowMapper) {
|
||||
if (pageNo <= 0 || pageSize <= 0) {
|
||||
throw new IllegalArgumentException("pageNo and pageSize must be greater than zero");
|
||||
}
|
||||
// Query the total number of current records
|
||||
Integer rowCountInt = jdbcTemplate.queryForObject(sqlCountRows, Integer.class);
|
||||
if (rowCountInt == null) {
|
||||
throw new IllegalArgumentException("fetchPageLimit error");
|
||||
}
|
||||
|
||||
// Compute pages count
|
||||
int pageCount = rowCountInt / pageSize;
|
||||
if (rowCountInt > pageSize * pageCount) {
|
||||
pageCount++;
|
||||
}
|
||||
|
||||
// Create Page object
|
||||
final Page<E> page = new Page<E>();
|
||||
page.setPageNumber(pageNo);
|
||||
page.setPagesAvailable(pageCount);
|
||||
page.setTotalCount(rowCountInt);
|
||||
|
||||
if (pageNo > pageCount) {
|
||||
return page;
|
||||
}
|
||||
|
||||
String selectSql = sqlFetchRows;
|
||||
if (isDerby()) {
|
||||
selectSql = selectSql.replaceAll("(?i)LIMIT \\?,\\?", "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY");
|
||||
}
|
||||
|
||||
List<E> result = jdbcTemplate.query(selectSql, args, rowMapper);
|
||||
for (E item : result) {
|
||||
page.getPageItems().add(item);
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<E> fetchPageLimit(final String sqlCountRows, final Object[] args1, final String sqlFetchRows,
|
||||
final Object[] args2, final int pageNo, final int pageSize, final RowMapper rowMapper) {
|
||||
if (pageNo <= 0 || pageSize <= 0) {
|
||||
throw new IllegalArgumentException("pageNo and pageSize must be greater than zero");
|
||||
}
|
||||
// Query the total number of current records
|
||||
Integer rowCountInt = jdbcTemplate.queryForObject(sqlCountRows, args1, Integer.class);
|
||||
if (rowCountInt == null) {
|
||||
throw new IllegalArgumentException("fetchPageLimit error");
|
||||
}
|
||||
|
||||
// Compute pages count
|
||||
int pageCount = rowCountInt / pageSize;
|
||||
if (rowCountInt > pageSize * pageCount) {
|
||||
pageCount++;
|
||||
}
|
||||
|
||||
// Create Page object
|
||||
final Page<E> page = new Page<E>();
|
||||
page.setPageNumber(pageNo);
|
||||
page.setPagesAvailable(pageCount);
|
||||
page.setTotalCount(rowCountInt);
|
||||
|
||||
if (pageNo > pageCount) {
|
||||
return page;
|
||||
}
|
||||
|
||||
String selectSql = sqlFetchRows;
|
||||
if (isDerby()) {
|
||||
selectSql = selectSql.replaceAll("(?i)LIMIT \\?,\\?", "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY");
|
||||
}
|
||||
|
||||
List<E> result = jdbcTemplate.query(selectSql, args2, rowMapper);
|
||||
for (E item : result) {
|
||||
page.getPageItems().add(item);
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<E> fetchPageLimit(final String sqlFetchRows, final Object[] args, final int pageNo, final int pageSize,
|
||||
final RowMapper rowMapper) {
|
||||
if (pageNo <= 0 || pageSize <= 0) {
|
||||
throw new IllegalArgumentException("pageNo and pageSize must be greater than zero");
|
||||
}
|
||||
// Create Page object
|
||||
final Page<E> page = new Page<E>();
|
||||
|
||||
String selectSql = sqlFetchRows;
|
||||
if (isDerby()) {
|
||||
selectSql = selectSql.replaceAll("(?i)LIMIT \\?,\\?", "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY");
|
||||
}
|
||||
|
||||
List<E> result = jdbcTemplate.query(selectSql, args, rowMapper);
|
||||
for (E item : result) {
|
||||
page.getPageItems().add(item);
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
private boolean isDerby() {
|
||||
return (EnvUtil.getStandaloneMode() && !AuthPropertyUtil.isUseExternalDB()) || AuthPropertyUtil
|
||||
.isEmbeddedStorage();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.persist.repository.externel;
|
||||
|
||||
import com.alibaba.nacos.auth.configuration.ConditionOnExternalStorage;
|
||||
import com.alibaba.nacos.auth.persist.datasource.DataSourceService;
|
||||
import com.alibaba.nacos.auth.persist.datasource.DynamicDataSource;
|
||||
import com.alibaba.nacos.auth.persist.repository.PaginationHelper;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
@SuppressWarnings(value = {"PMD.MethodReturnWrapperTypeRule", "checkstyle:linelength"})
|
||||
@Conditional(value = ConditionOnExternalStorage.class)
|
||||
@Component
|
||||
public class ExternalStoragePersistServiceImpl {
|
||||
|
||||
private DataSourceService dataSourceService;
|
||||
|
||||
protected JdbcTemplate jt;
|
||||
|
||||
/**
|
||||
* init datasource.
|
||||
*/
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
dataSourceService = DynamicDataSource.getInstance().getDataSource();
|
||||
|
||||
jt = getJdbcTemplate();
|
||||
}
|
||||
|
||||
/**
|
||||
* For unit testing.
|
||||
*/
|
||||
public JdbcTemplate getJdbcTemplate() {
|
||||
return this.dataSourceService.getJdbcTemplate();
|
||||
}
|
||||
|
||||
public <E> PaginationHelper<E> createPaginationHelper() {
|
||||
return new ExternalStoragePaginationHelperImpl<E>(jt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,338 @@
|
||||
/*
|
||||
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.util;
|
||||
|
||||
import com.alibaba.nacos.auth.constant.PropertiesConstant;
|
||||
import com.alibaba.nacos.sys.env.EnvUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
/**
|
||||
* Properties util.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class AuthPropertyUtil implements ApplicationContextInitializer<ConfigurableApplicationContext> {
|
||||
|
||||
private static final Logger LOGGER = LogUtil.DEFAULT_LOG;
|
||||
|
||||
private static int notifyConnectTimeout = 100;
|
||||
|
||||
private static int notifySocketTimeout = 200;
|
||||
|
||||
private static int maxHealthCheckFailCount = 12;
|
||||
|
||||
private static boolean isHealthCheck = true;
|
||||
|
||||
private static int maxContent = 10 * 1024 * 1024;
|
||||
|
||||
/**
|
||||
* Whether to enable capacity management.
|
||||
*/
|
||||
private static boolean isManageCapacity = true;
|
||||
|
||||
/**
|
||||
* Whether to enable the limit check function of capacity management, including the upper limit of configuration
|
||||
* number, configuration content size limit, etc.
|
||||
*/
|
||||
private static boolean isCapacityLimitCheck = false;
|
||||
|
||||
/**
|
||||
* The default cluster capacity limit.
|
||||
*/
|
||||
private static int defaultClusterQuota = 100000;
|
||||
|
||||
/**
|
||||
* the default capacity limit per Group.
|
||||
*/
|
||||
private static int defaultGroupQuota = 200;
|
||||
|
||||
/**
|
||||
* The default capacity limit per Tenant.
|
||||
*/
|
||||
private static int defaultTenantQuota = 200;
|
||||
|
||||
/**
|
||||
* The maximum size of the content in the configuration of a single, unit for bytes.
|
||||
*/
|
||||
private static int defaultMaxSize = 100 * 1024;
|
||||
|
||||
/**
|
||||
* The default Maximum number of aggregated data.
|
||||
*/
|
||||
private static int defaultMaxAggrCount = 10000;
|
||||
|
||||
/**
|
||||
* The maximum size of content in a single subconfiguration of aggregated data.
|
||||
*/
|
||||
private static int defaultMaxAggrSize = 1024;
|
||||
|
||||
/**
|
||||
* Initialize the expansion percentage of capacity has reached the limit.
|
||||
*/
|
||||
private static int initialExpansionPercent = 100;
|
||||
|
||||
/**
|
||||
* Fixed capacity information table usage (usage) time interval, the unit is in seconds.
|
||||
*/
|
||||
private static int correctUsageDelay = 10 * 60;
|
||||
|
||||
/**
|
||||
* Standalone mode uses DB.
|
||||
*/
|
||||
private static boolean useExternalDB = false;
|
||||
|
||||
/**
|
||||
* Inline storage value = ${nacos.standalone}.
|
||||
*/
|
||||
private static boolean embeddedStorage = EnvUtil.getStandaloneMode();
|
||||
|
||||
public static int getNotifyConnectTimeout() {
|
||||
return notifyConnectTimeout;
|
||||
}
|
||||
|
||||
public static void setNotifyConnectTimeout(int notifyConnectTimeout) {
|
||||
AuthPropertyUtil.notifyConnectTimeout = notifyConnectTimeout;
|
||||
}
|
||||
|
||||
public static int getNotifySocketTimeout() {
|
||||
return notifySocketTimeout;
|
||||
}
|
||||
|
||||
public static void setNotifySocketTimeout(int notifySocketTimeout) {
|
||||
AuthPropertyUtil.notifySocketTimeout = notifySocketTimeout;
|
||||
}
|
||||
|
||||
public static int getMaxHealthCheckFailCount() {
|
||||
return maxHealthCheckFailCount;
|
||||
}
|
||||
|
||||
public static void setMaxHealthCheckFailCount(int maxHealthCheckFailCount) {
|
||||
AuthPropertyUtil.maxHealthCheckFailCount = maxHealthCheckFailCount;
|
||||
}
|
||||
|
||||
public static boolean isHealthCheck() {
|
||||
return isHealthCheck;
|
||||
}
|
||||
|
||||
public static void setHealthCheck(boolean isHealthCheck) {
|
||||
AuthPropertyUtil.isHealthCheck = isHealthCheck;
|
||||
}
|
||||
|
||||
public static int getMaxContent() {
|
||||
return maxContent;
|
||||
}
|
||||
|
||||
public static void setMaxContent(int maxContent) {
|
||||
AuthPropertyUtil.maxContent = maxContent;
|
||||
}
|
||||
|
||||
public static boolean isManageCapacity() {
|
||||
return isManageCapacity;
|
||||
}
|
||||
|
||||
public static void setManageCapacity(boolean isManageCapacity) {
|
||||
AuthPropertyUtil.isManageCapacity = isManageCapacity;
|
||||
}
|
||||
|
||||
public static int getDefaultClusterQuota() {
|
||||
return defaultClusterQuota;
|
||||
}
|
||||
|
||||
public static void setDefaultClusterQuota(int defaultClusterQuota) {
|
||||
AuthPropertyUtil.defaultClusterQuota = defaultClusterQuota;
|
||||
}
|
||||
|
||||
public static boolean isCapacityLimitCheck() {
|
||||
return isCapacityLimitCheck;
|
||||
}
|
||||
|
||||
public static void setCapacityLimitCheck(boolean isCapacityLimitCheck) {
|
||||
AuthPropertyUtil.isCapacityLimitCheck = isCapacityLimitCheck;
|
||||
}
|
||||
|
||||
public static int getDefaultGroupQuota() {
|
||||
return defaultGroupQuota;
|
||||
}
|
||||
|
||||
public static void setDefaultGroupQuota(int defaultGroupQuota) {
|
||||
AuthPropertyUtil.defaultGroupQuota = defaultGroupQuota;
|
||||
}
|
||||
|
||||
public static int getDefaultTenantQuota() {
|
||||
return defaultTenantQuota;
|
||||
}
|
||||
|
||||
public static void setDefaultTenantQuota(int defaultTenantQuota) {
|
||||
AuthPropertyUtil.defaultTenantQuota = defaultTenantQuota;
|
||||
}
|
||||
|
||||
public static int getInitialExpansionPercent() {
|
||||
return initialExpansionPercent;
|
||||
}
|
||||
|
||||
public static void setInitialExpansionPercent(int initialExpansionPercent) {
|
||||
AuthPropertyUtil.initialExpansionPercent = initialExpansionPercent;
|
||||
}
|
||||
|
||||
public static int getDefaultMaxSize() {
|
||||
return defaultMaxSize;
|
||||
}
|
||||
|
||||
public static void setDefaultMaxSize(int defaultMaxSize) {
|
||||
AuthPropertyUtil.defaultMaxSize = defaultMaxSize;
|
||||
}
|
||||
|
||||
public static int getDefaultMaxAggrCount() {
|
||||
return defaultMaxAggrCount;
|
||||
}
|
||||
|
||||
public static void setDefaultMaxAggrCount(int defaultMaxAggrCount) {
|
||||
AuthPropertyUtil.defaultMaxAggrCount = defaultMaxAggrCount;
|
||||
}
|
||||
|
||||
public static int getDefaultMaxAggrSize() {
|
||||
return defaultMaxAggrSize;
|
||||
}
|
||||
|
||||
public static void setDefaultMaxAggrSize(int defaultMaxAggrSize) {
|
||||
AuthPropertyUtil.defaultMaxAggrSize = defaultMaxAggrSize;
|
||||
}
|
||||
|
||||
public static int getCorrectUsageDelay() {
|
||||
return correctUsageDelay;
|
||||
}
|
||||
|
||||
public static void setCorrectUsageDelay(int correctUsageDelay) {
|
||||
AuthPropertyUtil.correctUsageDelay = correctUsageDelay;
|
||||
}
|
||||
|
||||
public static boolean isStandaloneMode() {
|
||||
return EnvUtil.getStandaloneMode();
|
||||
}
|
||||
|
||||
public static boolean isUseExternalDB() {
|
||||
return useExternalDB;
|
||||
}
|
||||
|
||||
public static void setUseExternalDB(boolean useExternalDB) {
|
||||
AuthPropertyUtil.useExternalDB = useExternalDB;
|
||||
}
|
||||
|
||||
public static boolean isEmbeddedStorage() {
|
||||
return embeddedStorage;
|
||||
}
|
||||
|
||||
// Determines whether to read the data directly
|
||||
// if use mysql, Reduce database read pressure
|
||||
// if use raft+derby, Reduce leader read pressure
|
||||
|
||||
public static boolean isDirectRead() {
|
||||
return EnvUtil.getStandaloneMode() && isEmbeddedStorage();
|
||||
}
|
||||
|
||||
public static void setEmbeddedStorage(boolean embeddedStorage) {
|
||||
AuthPropertyUtil.embeddedStorage = embeddedStorage;
|
||||
}
|
||||
|
||||
private void loadSetting() {
|
||||
try {
|
||||
setNotifyConnectTimeout(Integer.parseInt(EnvUtil.getProperty(PropertiesConstant.NOTIFY_CONNECT_TIMEOUT,
|
||||
String.valueOf(notifyConnectTimeout))));
|
||||
LOGGER.info("notifyConnectTimeout:{}", notifyConnectTimeout);
|
||||
setNotifySocketTimeout(Integer.parseInt(EnvUtil.getProperty(PropertiesConstant.NOTIFY_SOCKET_TIMEOUT,
|
||||
String.valueOf(notifySocketTimeout))));
|
||||
LOGGER.info("notifySocketTimeout:{}", notifySocketTimeout);
|
||||
setHealthCheck(Boolean.parseBoolean(
|
||||
EnvUtil.getProperty(PropertiesConstant.IS_HEALTH_CHECK, String.valueOf(isHealthCheck))));
|
||||
LOGGER.info("isHealthCheck:{}", isHealthCheck);
|
||||
setMaxHealthCheckFailCount(Integer.parseInt(
|
||||
EnvUtil.getProperty(PropertiesConstant.MAX_HEALTH_CHECK_FAIL_COUNT,
|
||||
String.valueOf(maxHealthCheckFailCount))));
|
||||
LOGGER.info("maxHealthCheckFailCount:{}", maxHealthCheckFailCount);
|
||||
setMaxContent(
|
||||
Integer.parseInt(EnvUtil.getProperty(PropertiesConstant.MAX_CONTENT, String.valueOf(maxContent))));
|
||||
LOGGER.info("maxContent:{}", maxContent);
|
||||
// capacity management
|
||||
setManageCapacity(getBoolean(PropertiesConstant.IS_MANAGE_CAPACITY, isManageCapacity));
|
||||
setCapacityLimitCheck(getBoolean(PropertiesConstant.IS_CAPACITY_LIMIT_CHECK, isCapacityLimitCheck));
|
||||
setDefaultClusterQuota(getInt(PropertiesConstant.DEFAULT_CLUSTER_QUOTA, defaultClusterQuota));
|
||||
setDefaultGroupQuota(getInt(PropertiesConstant.DEFAULT_GROUP_QUOTA, defaultGroupQuota));
|
||||
setDefaultTenantQuota(getInt(PropertiesConstant.DEFAULT_TENANT_QUOTA, defaultTenantQuota));
|
||||
setDefaultMaxSize(getInt(PropertiesConstant.DEFAULT_MAX_SIZE, defaultMaxSize));
|
||||
setDefaultMaxAggrCount(getInt(PropertiesConstant.DEFAULT_MAX_AGGR_COUNT, defaultMaxAggrCount));
|
||||
setDefaultMaxAggrSize(getInt(PropertiesConstant.DEFAULT_MAX_AGGR_SIZE, defaultMaxAggrSize));
|
||||
setCorrectUsageDelay(getInt(PropertiesConstant.CORRECT_USAGE_DELAY, correctUsageDelay));
|
||||
setInitialExpansionPercent(getInt(PropertiesConstant.INITIAL_EXPANSION_PERCENT, initialExpansionPercent));
|
||||
// External data sources are used by default in cluster mode
|
||||
setUseExternalDB(PropertiesConstant.MYSQL
|
||||
.equalsIgnoreCase(getString(PropertiesConstant.SPRING_DATASOURCE_PLATFORM, "")));
|
||||
// must initialize after setUseExternalDB
|
||||
// This value is true in stand-alone mode and false in cluster mode
|
||||
// If this value is set to true in cluster mode, nacos's distributed storage engine is turned on
|
||||
// default value is depend on ${nacos.standalone}
|
||||
|
||||
if (isUseExternalDB()) {
|
||||
setEmbeddedStorage(false);
|
||||
} else {
|
||||
boolean embeddedStorage =
|
||||
AuthPropertyUtil.embeddedStorage || Boolean.getBoolean(PropertiesConstant.EMBEDDED_STORAGE);
|
||||
setEmbeddedStorage(embeddedStorage);
|
||||
|
||||
// If the embedded data source storage is not turned on, it is automatically
|
||||
// upgraded to the external data source storage, as before
|
||||
if (!embeddedStorage) {
|
||||
setUseExternalDB(true);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("read application.properties failed", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean getBoolean(String key, boolean defaultValue) {
|
||||
return Boolean.parseBoolean(getString(key, String.valueOf(defaultValue)));
|
||||
}
|
||||
|
||||
private int getInt(String key, int defaultValue) {
|
||||
return Integer.parseInt(getString(key, String.valueOf(defaultValue)));
|
||||
}
|
||||
|
||||
private String getString(String key, String defaultValue) {
|
||||
String value = getProperty(key);
|
||||
if (value == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
LOGGER.info("{}:{}", key, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getProperty(String key) {
|
||||
return EnvUtil.getProperty(key);
|
||||
}
|
||||
|
||||
public String getProperty(String key, String defaultValue) {
|
||||
return EnvUtil.getProperty(key, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
|
||||
loadSetting();
|
||||
}
|
||||
}
|
96
auth/src/main/java/com/alibaba/nacos/auth/util/LogUtil.java
Normal file
96
auth/src/main/java/com/alibaba/nacos/auth/util/LogUtil.java
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.util;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Log util.
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class LogUtil {
|
||||
|
||||
/**
|
||||
* Default log.
|
||||
*/
|
||||
public static final Logger DEFAULT_LOG = LoggerFactory.getLogger("com.alibaba.nacos.auth.startLog");
|
||||
|
||||
/**
|
||||
* Fatal error log, require alarm.
|
||||
*/
|
||||
public static final Logger FATAL_LOG = LoggerFactory.getLogger("com.alibaba.nacos.auth.fatal");
|
||||
|
||||
/**
|
||||
* Http client log.
|
||||
*/
|
||||
public static final Logger PULL_LOG = LoggerFactory.getLogger("com.alibaba.nacos.auth.pullLog");
|
||||
|
||||
public static final Logger PULL_CHECK_LOG = LoggerFactory.getLogger("com.alibaba.nacos.auth.pullCheckLog");
|
||||
|
||||
/**
|
||||
* Dump log.
|
||||
*/
|
||||
public static final Logger DUMP_LOG = LoggerFactory.getLogger("com.alibaba.nacos.auth.dumpLog");
|
||||
|
||||
public static final Logger MEMORY_LOG = LoggerFactory.getLogger("com.alibaba.nacos.auth.monitorLog");
|
||||
|
||||
public static final Logger CLIENT_LOG = LoggerFactory.getLogger("com.alibaba.nacos.auth.clientLog");
|
||||
|
||||
public static final Logger TRACE_LOG = LoggerFactory.getLogger("com.alibaba.nacos.auth.traceLog");
|
||||
|
||||
public static final Logger NOTIFY_LOG = LoggerFactory.getLogger("com.alibaba.nacos.auth.notifyLog");
|
||||
|
||||
public static void setLogLevel(String logName, String level) {
|
||||
|
||||
switch (logName) {
|
||||
case "config-server":
|
||||
((ch.qos.logback.classic.Logger) DEFAULT_LOG).setLevel(Level.valueOf(level));
|
||||
break;
|
||||
case "config-fatal":
|
||||
((ch.qos.logback.classic.Logger) FATAL_LOG).setLevel(Level.valueOf(level));
|
||||
break;
|
||||
case "config-pull":
|
||||
((ch.qos.logback.classic.Logger) PULL_LOG).setLevel(Level.valueOf(level));
|
||||
break;
|
||||
case "config-pull-check":
|
||||
((ch.qos.logback.classic.Logger) PULL_CHECK_LOG).setLevel(Level.valueOf(level));
|
||||
break;
|
||||
case "config-dump":
|
||||
((ch.qos.logback.classic.Logger) DUMP_LOG).setLevel(Level.valueOf(level));
|
||||
break;
|
||||
case "config-memory":
|
||||
((ch.qos.logback.classic.Logger) MEMORY_LOG).setLevel(Level.valueOf(level));
|
||||
break;
|
||||
case "config-client-request":
|
||||
((ch.qos.logback.classic.Logger) CLIENT_LOG).setLevel(Level.valueOf(level));
|
||||
break;
|
||||
case "config-trace":
|
||||
((ch.qos.logback.classic.Logger) TRACE_LOG).setLevel(Level.valueOf(level));
|
||||
break;
|
||||
case "config-notify":
|
||||
((ch.qos.logback.classic.Logger) NOTIFY_LOG).setLevel(Level.valueOf(level));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.util;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Check precondition, throws an {@code IllegalArgumentException} If the conditions are not met.
|
||||
* @author zzq
|
||||
* @date 2021/7/29
|
||||
*/
|
||||
public class Preconditions {
|
||||
|
||||
/**
|
||||
* check precondition.
|
||||
* @param expression a boolean expression
|
||||
* @param errorMessage the exception message to use if the check fails
|
||||
* @throws IllegalArgumentException if {@code expression} is false
|
||||
*/
|
||||
public static void checkArgument(boolean expression, Object errorMessage) {
|
||||
if (Objects.isNull(errorMessage)) {
|
||||
throw new IllegalArgumentException("errorMessage cannot be null.");
|
||||
}
|
||||
if (!expression) {
|
||||
throw new IllegalArgumentException(String.valueOf(errorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check precondition.
|
||||
* @param expression a boolean expression
|
||||
* @param errorMessageTemplate the exception message template to use if the check fails
|
||||
* @param errorMessageArgs the arguments to be substituted into the message template.
|
||||
* @throws IllegalArgumentException if {@code expression} is false
|
||||
*/
|
||||
public static void checkArgument(boolean expression, String errorMessageTemplate, Object... errorMessageArgs) {
|
||||
if (Objects.isNull(errorMessageArgs) || Objects.isNull(errorMessageTemplate)) {
|
||||
throw new IllegalArgumentException("errorMessageTemplate or errorMessage cannot be null.");
|
||||
}
|
||||
if (!expression) {
|
||||
throw new IllegalArgumentException(String.format(errorMessageTemplate, errorMessageArgs));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.persist;
|
||||
|
||||
import com.alibaba.nacos.auth.model.Page;
|
||||
import com.alibaba.nacos.auth.model.PermissionInfo;
|
||||
import com.alibaba.nacos.auth.persist.repository.PaginationHelper;
|
||||
import com.alibaba.nacos.auth.persist.repository.externel.ExternalStoragePersistServiceImpl;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ExternalPermissionPersistServiceImplTest {
|
||||
|
||||
@Mock
|
||||
private ExternalStoragePersistServiceImpl externalStoragePersistService;
|
||||
|
||||
@Mock
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
@Mock
|
||||
private PaginationHelper paginationHelper;
|
||||
|
||||
private ExternalPermissionPersistServiceImpl externalPermissionPersistService;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
externalPermissionPersistService = new ExternalPermissionPersistServiceImpl();
|
||||
|
||||
Class<ExternalPermissionPersistServiceImpl> externalPermissionPersistServiceClass = ExternalPermissionPersistServiceImpl.class;
|
||||
Field persistServiceClassDeclaredField = externalPermissionPersistServiceClass
|
||||
.getDeclaredField("persistService");
|
||||
persistServiceClassDeclaredField.setAccessible(true);
|
||||
persistServiceClassDeclaredField.set(externalPermissionPersistService, externalStoragePersistService);
|
||||
|
||||
Mockito.when(externalStoragePersistService.getJdbcTemplate()).thenReturn(jdbcTemplate);
|
||||
Mockito.when(externalStoragePersistService.createPaginationHelper()).thenReturn(paginationHelper);
|
||||
|
||||
externalPermissionPersistService.init();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPermissions() {
|
||||
Page<PermissionInfo> role = externalPermissionPersistService.getPermissions("role", 1, 10);
|
||||
Assert.assertNotNull(role);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.persist;
|
||||
|
||||
import com.alibaba.nacos.auth.model.Page;
|
||||
import com.alibaba.nacos.auth.persist.repository.PaginationHelper;
|
||||
import com.alibaba.nacos.auth.persist.repository.externel.ExternalStoragePersistServiceImpl;
|
||||
import com.alibaba.nacos.auth.roles.RoleInfo;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ExternalRolePersistServiceImplTest {
|
||||
|
||||
@Mock
|
||||
private ExternalStoragePersistServiceImpl persistService;
|
||||
|
||||
@Mock
|
||||
private JdbcTemplate jt;
|
||||
|
||||
@Mock
|
||||
private PaginationHelper paginationHelper;
|
||||
|
||||
private ExternalRolePersistServiceImpl externalRolePersistService;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
externalRolePersistService = new ExternalRolePersistServiceImpl();
|
||||
Class<ExternalRolePersistServiceImpl> externalRolePersistServiceClass = ExternalRolePersistServiceImpl.class;
|
||||
Field persistServiceClassDeclaredField = externalRolePersistServiceClass.getDeclaredField("persistService");
|
||||
persistServiceClassDeclaredField.setAccessible(true);
|
||||
persistServiceClassDeclaredField.set(externalRolePersistService, persistService);
|
||||
|
||||
Mockito.when(persistService.getJdbcTemplate()).thenReturn(jt);
|
||||
Mockito.when(persistService.createPaginationHelper()).thenReturn(paginationHelper);
|
||||
|
||||
externalRolePersistService.init();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRolesByUserName() {
|
||||
Page<RoleInfo> userName = externalRolePersistService.getRolesByUserName("userName", 1, 10);
|
||||
Assert.assertNull(userName);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.persist;
|
||||
|
||||
import com.alibaba.nacos.auth.model.Page;
|
||||
import com.alibaba.nacos.auth.users.User;
|
||||
import com.alibaba.nacos.auth.persist.repository.PaginationHelper;
|
||||
import com.alibaba.nacos.auth.persist.repository.externel.ExternalStoragePersistServiceImpl;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ExternalUserPersistServiceImplTest {
|
||||
|
||||
@Mock
|
||||
private ExternalStoragePersistServiceImpl persistService;
|
||||
|
||||
@Mock
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
@Mock
|
||||
private PaginationHelper paginationHelper;
|
||||
|
||||
private ExternalUserPersistServiceImpl externalUserPersistService;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
externalUserPersistService = new ExternalUserPersistServiceImpl();
|
||||
|
||||
Class<ExternalUserPersistServiceImpl> externalUserPersistServiceClass = ExternalUserPersistServiceImpl.class;
|
||||
Field persistServiceClassDeclaredField = externalUserPersistServiceClass.getDeclaredField("persistService");
|
||||
persistServiceClassDeclaredField.setAccessible(true);
|
||||
persistServiceClassDeclaredField.set(externalUserPersistService, persistService);
|
||||
|
||||
Mockito.when(persistService.getJdbcTemplate()).thenReturn(jdbcTemplate);
|
||||
Mockito.when(persistService.createPaginationHelper()).thenReturn(paginationHelper);
|
||||
externalUserPersistService.init();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateUser() {
|
||||
externalUserPersistService.createUser("username", "password");
|
||||
|
||||
String sql = "INSERT INTO users (username, password, enabled) VALUES (?, ?, ?)";
|
||||
Mockito.verify(jdbcTemplate).update(sql, "username", "password", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindUserByUsername() {
|
||||
User username = externalUserPersistService.findUserByUsername("username");
|
||||
Assert.assertNull(username);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUsers() {
|
||||
Page<User> users = externalUserPersistService.getUsers(1, 10);
|
||||
Assert.assertNotNull(users);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 1999-2020 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.persist.datasource;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class DataSourcePoolPropertiesTest {
|
||||
|
||||
private static final String JDBC_URL = "jdbc:derby://127.0.0.1:3306/nacos_devtest?characterEncoding=utf8&serverTimezone=UTC";
|
||||
|
||||
private static final String JDBC_DRIVER_CLASS_NAME = "org.apache.derby.jdbc.EmbeddedDriver";
|
||||
|
||||
private static final String PASSWORD = "nacos";
|
||||
|
||||
private static final String USERNAME = "nacos_devtest";
|
||||
|
||||
private static final Long CONNECTION_TIMEOUT = 10000L;
|
||||
|
||||
private static final Integer MAX_POOL_SIZE = 50;
|
||||
|
||||
private MockEnvironment environment;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
environment = new MockEnvironment();
|
||||
environment.setProperty("db.user", USERNAME);
|
||||
environment.setProperty("db.password", PASSWORD);
|
||||
environment.setProperty("db.pool.config.connectionTimeout", CONNECTION_TIMEOUT.toString());
|
||||
environment.setProperty("db.pool.config.maximumPoolSize", MAX_POOL_SIZE.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuild() {
|
||||
DataSourcePoolProperties poolProperties = DataSourcePoolProperties.build(environment);
|
||||
poolProperties.setJdbcUrl(JDBC_URL);
|
||||
// poolProperties.setDriverClassName(JDBC_DRIVER_CLASS_NAME);
|
||||
poolProperties.setUsername(USERNAME);
|
||||
poolProperties.setPassword(PASSWORD);
|
||||
HikariDataSource actual = poolProperties.getDataSource();
|
||||
assertEquals(JDBC_URL, actual.getJdbcUrl());
|
||||
assertEquals(JDBC_DRIVER_CLASS_NAME, actual.getDriverClassName());
|
||||
assertEquals(USERNAME, actual.getUsername());
|
||||
assertEquals(PASSWORD, actual.getPassword());
|
||||
assertEquals(CONNECTION_TIMEOUT.longValue(), actual.getConnectionTimeout());
|
||||
assertEquals(DataSourcePoolProperties.DEFAULT_VALIDATION_TIMEOUT, actual.getValidationTimeout());
|
||||
assertEquals(MAX_POOL_SIZE.intValue(), actual.getMaximumPoolSize());
|
||||
assertEquals(DataSourcePoolProperties.DEFAULT_MINIMUM_IDLE, actual.getMinimumIdle());
|
||||
}
|
||||
}
|
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.alibaba.nacos.auth.persist.datasource;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ExternalDataSourcePropertiesTest {
|
||||
|
||||
@SuppressWarnings("checkstyle:linelength")
|
||||
public static final String JDBC_URL = "jdbc:mysql://127.0.0.1:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC";
|
||||
|
||||
public static final String PASSWORD = "nacos";
|
||||
|
||||
public static final String USERNAME = "nacos_devtest";
|
||||
|
||||
@Test
|
||||
public void externalDatasourceNormally() {
|
||||
HikariDataSource expectedDataSource = new HikariDataSource();
|
||||
expectedDataSource.setJdbcUrl(JDBC_URL);
|
||||
expectedDataSource.setUsername(USERNAME);
|
||||
expectedDataSource.setPassword(PASSWORD);
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
environment.setProperty("db.num", "1");
|
||||
environment.setProperty("db.user", USERNAME);
|
||||
environment.setProperty("db.password", PASSWORD);
|
||||
environment.setProperty("db.url.0", JDBC_URL);
|
||||
List<HikariDataSource> dataSources = new ExternalDataSourceProperties().build(environment, (dataSource -> {
|
||||
Assert.assertEquals(dataSource.getJdbcUrl(), expectedDataSource.getJdbcUrl());
|
||||
Assert.assertEquals(dataSource.getUsername(), expectedDataSource.getUsername());
|
||||
Assert.assertEquals(dataSource.getPassword(), expectedDataSource.getPassword());
|
||||
|
||||
}));
|
||||
Assert.assertEquals(dataSources.size(), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void externalDatasourceToAssertMultiJdbcUrl() {
|
||||
|
||||
HikariDataSource expectedDataSource = new HikariDataSource();
|
||||
expectedDataSource.setJdbcUrl(JDBC_URL);
|
||||
expectedDataSource.setUsername(USERNAME);
|
||||
expectedDataSource.setPassword(PASSWORD);
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
environment.setProperty("db.num", "2");
|
||||
environment.setProperty("db.user", USERNAME);
|
||||
environment.setProperty("db.password", PASSWORD);
|
||||
environment.setProperty("db.url.0", JDBC_URL);
|
||||
environment.setProperty("db.url.1", JDBC_URL);
|
||||
List<HikariDataSource> dataSources = new ExternalDataSourceProperties().build(environment, (dataSource -> {
|
||||
Assert.assertEquals(dataSource.getJdbcUrl(), expectedDataSource.getJdbcUrl());
|
||||
Assert.assertEquals(dataSource.getUsername(), expectedDataSource.getUsername());
|
||||
Assert.assertEquals(dataSource.getPassword(), expectedDataSource.getPassword());
|
||||
|
||||
}));
|
||||
Assert.assertEquals(dataSources.size(), 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void externalDatasourceToAssertMultiPasswordAndUsername() {
|
||||
|
||||
HikariDataSource expectedDataSource = new HikariDataSource();
|
||||
expectedDataSource.setJdbcUrl(JDBC_URL);
|
||||
expectedDataSource.setUsername(USERNAME);
|
||||
expectedDataSource.setPassword(PASSWORD);
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
environment.setProperty("db.num", "2");
|
||||
environment.setProperty("db.user.0", USERNAME);
|
||||
environment.setProperty("db.user.1", USERNAME);
|
||||
environment.setProperty("db.password.0", PASSWORD);
|
||||
environment.setProperty("db.password.1", PASSWORD);
|
||||
environment.setProperty("db.url.0", JDBC_URL);
|
||||
environment.setProperty("db.url.1", JDBC_URL);
|
||||
List<HikariDataSource> dataSources = new ExternalDataSourceProperties().build(environment, (dataSource -> {
|
||||
Assert.assertEquals(dataSource.getJdbcUrl(), expectedDataSource.getJdbcUrl());
|
||||
Assert.assertEquals(dataSource.getUsername(), expectedDataSource.getUsername());
|
||||
Assert.assertEquals(dataSource.getPassword(), expectedDataSource.getPassword());
|
||||
|
||||
}));
|
||||
Assert.assertEquals(dataSources.size(), 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void externalDatasourceToAssertMinIdle() {
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
environment.setProperty("db.num", "1");
|
||||
environment.setProperty("db.user", USERNAME);
|
||||
environment.setProperty("db.password", PASSWORD);
|
||||
environment.setProperty("db.url.0", JDBC_URL);
|
||||
List<HikariDataSource> dataSources = new ExternalDataSourceProperties().build(environment, (dataSource -> {
|
||||
dataSource.validate();
|
||||
Assert.assertEquals(dataSource.getMinimumIdle(), DataSourcePoolProperties.DEFAULT_MINIMUM_IDLE);
|
||||
}));
|
||||
Assert.assertEquals(dataSources.size(), 1);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void externalDatasourceFailureWithLarkInfo() {
|
||||
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
new ExternalDataSourceProperties().build(environment, null);
|
||||
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void externalDatasourceFailureWithErrorInfo() {
|
||||
|
||||
HikariDataSource expectedDataSource = new HikariDataSource();
|
||||
expectedDataSource.setJdbcUrl(JDBC_URL);
|
||||
expectedDataSource.setUsername(USERNAME);
|
||||
expectedDataSource.setPassword(PASSWORD);
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
// error num of db
|
||||
environment.setProperty("db.num", "2");
|
||||
environment.setProperty("db.user", USERNAME);
|
||||
environment.setProperty("db.password", PASSWORD);
|
||||
environment.setProperty("db.url.0", JDBC_URL);
|
||||
List<HikariDataSource> dataSources = new ExternalDataSourceProperties().build(environment, (dataSource -> {
|
||||
Assert.assertEquals(dataSource.getJdbcUrl(), expectedDataSource.getJdbcUrl());
|
||||
Assert.assertEquals(dataSource.getUsername(), expectedDataSource.getUsername());
|
||||
Assert.assertEquals(dataSource.getPassword(), expectedDataSource.getPassword());
|
||||
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user