diff --git a/config/pom.xml b/config/pom.xml index 7d14106078a..0625b907867 100644 --- a/config/pom.xml +++ b/config/pom.xml @@ -122,14 +122,14 @@ - + org.apache.maven.plugins maven-assembly-plugin diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/AuthType.java b/config/src/main/java/com/alibaba/nacos/config/server/model/AuthType.java deleted file mode 100644 index 75a91d4a486..00000000000 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/AuthType.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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.config.server.model; - -/** - * Auth type. - * - * @author Nacos - */ -public enum AuthType { - /** - * Auth type. - */ - GROUP, - GROUP_DATAID, - TENANT_GROUP, - TENANT -} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigAdvanceInfo.java b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigAdvanceInfo.java index f683a2bf1cb..8c9bd77cad2 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigAdvanceInfo.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigAdvanceInfo.java @@ -17,6 +17,7 @@ package com.alibaba.nacos.config.server.model; import java.io.Serializable; +import java.util.Objects; /** * Config advance info. @@ -126,4 +127,20 @@ public String getConfigTags() { public void setConfigTags(String configTags) { this.configTags = configTags; } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConfigAdvanceInfo that = (ConfigAdvanceInfo) o; + return createTime == that.createTime && modifyTime == that.modifyTime && Objects.equals(createUser, + that.createUser) && Objects.equals(createIp, that.createIp) && Objects.equals(desc, that.desc) + && Objects.equals(use, that.use) && Objects.equals(effect, that.effect) && Objects.equals(type, + that.type) && Objects.equals(schema, that.schema) && Objects.equals(configTags, that.configTags); + } + } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigHistoryInfo.java b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigHistoryInfo.java index 71a8d7489b4..d99505af8a6 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigHistoryInfo.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigHistoryInfo.java @@ -21,6 +21,7 @@ import java.io.Serializable; import java.sql.Timestamp; +import java.util.Objects; /** * ConfigHistoryInfo. @@ -174,4 +175,27 @@ public String getEncryptedDataKey() { public void setEncryptedDataKey(String encryptedDataKey) { this.encryptedDataKey = encryptedDataKey; } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConfigHistoryInfo that = (ConfigHistoryInfo) o; + return id == that.id && lastId == that.lastId && Objects.equals(dataId, that.dataId) && Objects.equals(group, + that.group) && Objects.equals(tenant, that.tenant) && Objects.equals(appName, that.appName) + && Objects.equals(md5, that.md5) && Objects.equals(content, that.content) && Objects.equals(srcIp, + that.srcIp) && Objects.equals(srcUser, that.srcUser) && Objects.equals(opType, that.opType) + && Objects.equals(createdTime, that.createdTime) && Objects.equals(lastModifiedTime, + that.lastModifiedTime) && Objects.equals(encryptedDataKey, that.encryptedDataKey); + } + + @Override + public int hashCode() { + return Objects.hash(id, lastId, dataId, group, tenant, appName, md5, content, srcIp, srcUser, opType, + createdTime, lastModifiedTime, encryptedDataKey); + } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoAggr.java b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoAggr.java index 71df2f535e6..3e2e8cfb960 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoAggr.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoAggr.java @@ -45,21 +45,6 @@ public class ConfigInfoAggr implements Serializable { private String content; - public ConfigInfoAggr(String dataId, String group, String datumId, String content) { - this.dataId = dataId; - this.group = group; - this.datumId = datumId; - this.content = content; - } - - public ConfigInfoAggr(String dataId, String group, String datumId, String appName, String content) { - this.dataId = dataId; - this.group = group; - this.datumId = datumId; - this.appName = appName; - this.content = content; - } - public ConfigInfoAggr() { } @@ -104,17 +89,6 @@ public void setContent(String content) { this.content = content; } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((content == null) ? 0 : content.hashCode()); - result = prime * result + ((dataId == null) ? 0 : dataId.hashCode()); - result = prime * result + ((datumId == null) ? 0 : datumId.hashCode()); - result = prime * result + ((group == null) ? 0 : group.hashCode()); - return result; - } - @Override public boolean equals(Object obj) { if (this == obj) { diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoBase.java b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoBase.java index 58891c87d10..374a9a79b27 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoBase.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoBase.java @@ -56,7 +56,7 @@ public ConfigInfoBase(String dataId, String group, String content) { this.group = group; this.content = content; if (this.content != null) { - this.md5 = MD5Utils.md5Hex(this.content, Constants.ENCODE); + this.md5 = MD5Utils.md5Hex(this.content, Constants.PERSIST_ENCODE); } } @@ -170,17 +170,6 @@ public int compareTo(ConfigInfoBase o) { return 0; } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((content == null) ? 0 : content.hashCode()); - result = prime * result + ((dataId == null) ? 0 : dataId.hashCode()); - result = prime * result + ((group == null) ? 0 : group.hashCode()); - result = prime * result + ((md5 == null) ? 0 : md5.hashCode()); - return result; - } - @Override public boolean equals(Object obj) { if (this == obj) { diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoChanged.java b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoChanged.java index 542c70c0777..42db6310759 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoChanged.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoChanged.java @@ -59,15 +59,6 @@ public void setGroup(String group) { this.group = group; } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((dataId == null) ? 0 : dataId.hashCode()); - result = prime * result + ((group == null) ? 0 : group.hashCode()); - return result; - } - @Override public boolean equals(Object obj) { if (this == obj) { diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoStateWrapper.java b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoStateWrapper.java index 33feb685b66..700b63750d0 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoStateWrapper.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoStateWrapper.java @@ -17,6 +17,7 @@ package com.alibaba.nacos.config.server.model; import java.io.Serializable; +import java.util.Objects; /** * ConfigInfoStateWrapper. include id,dataId,group,tenant,lastModified. @@ -74,4 +75,22 @@ public String getTenant() { public void setTenant(String tenant) { this.tenant = tenant; } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConfigInfoStateWrapper that = (ConfigInfoStateWrapper) o; + return id == that.id && lastModified == that.lastModified && Objects.equals(dataId, that.dataId) + && Objects.equals(group, that.group) && Objects.equals(tenant, that.tenant); + } + + @Override + public int hashCode() { + return Objects.hash(id, dataId, group, tenant, lastModified); + } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigKey.java b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigKey.java index 407b1b71a61..9ceb3baca47 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigKey.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigKey.java @@ -17,6 +17,7 @@ package com.alibaba.nacos.config.server.model; import java.io.Serializable; +import java.util.Objects; /** * ConfigKey. @@ -36,12 +37,6 @@ public class ConfigKey implements Serializable { public ConfigKey() { } - public ConfigKey(String appName, String dataId, String group) { - this.appName = appName; - this.dataId = dataId; - this.group = group; - } - public String getAppName() { return appName; } @@ -66,4 +61,21 @@ public void setGroup(String group) { this.group = group; } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConfigKey configKey = (ConfigKey) o; + return Objects.equals(appName, configKey.appName) && Objects.equals(dataId, configKey.dataId) && Objects.equals( + group, configKey.group); + } + + @Override + public int hashCode() { + return Objects.hash(appName, dataId, group); + } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/GroupInfo.java b/config/src/main/java/com/alibaba/nacos/config/server/model/GroupInfo.java deleted file mode 100644 index 594fd27dd80..00000000000 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/GroupInfo.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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.config.server.model; - -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; - -import java.io.Serializable; - -/** - * GroupInfo. - * - * @author Nacos - */ -public class GroupInfo implements Serializable { - - static final long serialVersionUID = 3930805434971004186L; - - @JsonSerialize(using = ToStringSerializer.class) - private long id; - - private String address; - - private String group; - - private String dataId; - - public GroupInfo() { - - } - - public GroupInfo(String address, String dataId, String group) { - super(); - this.address = address; - this.group = group; - this.dataId = dataId; - } - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } - - public String getGroup() { - return group; - } - - public void setGroup(String group) { - this.group = group; - } - - public String getDataId() { - return dataId; - } - - public void setDataId(String dataId) { - this.dataId = dataId; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((address == null) ? 0 : address.hashCode()); - result = prime * result + ((dataId == null) ? 0 : dataId.hashCode()); - result = prime * result + ((group == null) ? 0 : group.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - GroupInfo other = (GroupInfo) obj; - if (address == null) { - if (other.address != null) { - return false; - } - } else if (!address.equals(other.address)) { - return false; - } - if (dataId == null) { - if (other.dataId != null) { - return false; - } - } else if (!dataId.equals(other.dataId)) { - return false; - } - if (group == null) { - if (other.group != null) { - return false; - } - } else if (!group.equals(other.group)) { - return false; - } - return true; - } - -} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/HistoryContext.java b/config/src/main/java/com/alibaba/nacos/config/server/model/HistoryContext.java deleted file mode 100644 index 75b51327680..00000000000 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/HistoryContext.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * 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.config.server.model; - -import com.alibaba.nacos.persistence.model.Page; - -import java.io.Serializable; - -/** - * HistoryContext. - * - * @author Nacos - */ -public class HistoryContext implements Serializable { - - private static final long serialVersionUID = -8400843549603420766L; - - public String serverId; - - public String dataId; - - public String group; - - public String tenant; - - private String appName; - - public boolean success; - - public int statusCode; - - public String statusMsg; - - public Page configs; - - public HistoryContext(String serverId, String dataId, String group, int statusCode, String statusMsg, - Page configs) { - this.serverId = serverId; - this.dataId = dataId; - this.group = group; - this.statusCode = statusCode; - this.statusMsg = statusMsg; - this.configs = configs; - this.success = 200 == statusCode; - } - - public HistoryContext() { - } - - public String getServerId() { - return serverId; - } - - public void setServerId(String serverId) { - this.serverId = serverId; - } - - public String getDataId() { - return dataId; - } - - public void setDataId(String dataId) { - this.dataId = dataId; - } - - public String getGroup() { - return group; - } - - public void setGroup(String group) { - this.group = group; - } - - public String getTenant() { - return tenant; - } - - public void setTenant(String tenant) { - this.tenant = tenant; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public int getStatusCode() { - return statusCode; - } - - public void setStatusCode(int statusCode) { - this.statusCode = statusCode; - } - - public String getStatusMsg() { - return statusMsg; - } - - public void setStatusMsg(String statusMsg) { - this.statusMsg = statusMsg; - } - - public Page getConfigs() { - return configs; - } - - public void setConfigs(Page configs) { - this.configs = configs; - } - - public String getAppName() { - return appName; - } - - public void setAppName(String appName) { - this.appName = appName; - } - -} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/RestPageResult.java b/config/src/main/java/com/alibaba/nacos/config/server/model/ListenerCheckResult.java similarity index 53% rename from config/src/main/java/com/alibaba/nacos/config/server/model/RestPageResult.java rename to config/src/main/java/com/alibaba/nacos/config/server/model/ListenerCheckResult.java index c2e97dadd28..8d498613878 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/RestPageResult.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/ListenerCheckResult.java @@ -19,25 +19,25 @@ import java.io.Serializable; /** - * RestPageResult. + * check config has listener. * - * @author Nacos + * @author shiyiyue */ -public class RestPageResult implements Serializable { - - private static final long serialVersionUID = -8048577763828650575L; +public class ListenerCheckResult implements Serializable { + + private boolean hasListener; private int code; private String message; - private int total; - - private int pageSize; - - private int currentPage; + public boolean isHasListener() { + return hasListener; + } - private T data; + public void setHasListener(boolean hasListener) { + this.hasListener = hasListener; + } public int getCode() { return code; @@ -54,41 +54,4 @@ public String getMessage() { public void setMessage(String message) { this.message = message; } - - public int getTotal() { - return total; - } - - public void setTotal(int total) { - this.total = total; - } - - public int getPageSize() { - return pageSize; - } - - public void setPageSize(int pageSize) { - this.pageSize = pageSize; - } - - public int getCurrentPage() { - return currentPage; - } - - public void setCurrentPage(int currentPage) { - this.currentPage = currentPage; - } - - public T getData() { - return data; - } - - public void setData(T data) { - this.data = data; - } - - public static long getSerialversionuid() { - return serialVersionUID; - } - } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/SubInfo.java b/config/src/main/java/com/alibaba/nacos/config/server/model/SubInfo.java deleted file mode 100644 index 3e57261f703..00000000000 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/SubInfo.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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.config.server.model; - -import java.io.Serializable; -import java.sql.Timestamp; - -/** - * SubInfo. - * - * @author Nacos - */ -public class SubInfo implements Serializable { - - private static final long serialVersionUID = -3900485932969066685L; - - private String appName; - - private String dataId; - - private String group; - - private String localIp; - - private Timestamp date; - - public String getAppName() { - return appName; - } - - public String getDataId() { - return dataId; - } - - public String getGroup() { - return group; - } - - public Timestamp getDate() { - return new Timestamp(date.getTime()); - } - - public void setAppName(String appName) { - this.appName = appName; - } - - public void setDataId(String dataId) { - this.dataId = dataId; - } - - public void setGroup(String group) { - this.group = group; - } - - public void setDate(Timestamp date) { - this.date = new Timestamp(date.getTime()); - } - - public String getLocalIp() { - return localIp; - } - - public void setLocalIp(String localIp) { - this.localIp = localIp; - } - -} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigCacheService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigCacheService.java index 2e984b9da61..b155e89b752 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigCacheService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigCacheService.java @@ -24,14 +24,10 @@ import com.alibaba.nacos.config.server.constant.Constants; import com.alibaba.nacos.config.server.model.CacheItem; import com.alibaba.nacos.config.server.model.ConfigCache; -import com.alibaba.nacos.config.server.model.ConfigInfoBase; import com.alibaba.nacos.config.server.model.event.LocalDataChangeEvent; import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskServiceFactory; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; import com.alibaba.nacos.config.server.utils.GroupKey2; import com.alibaba.nacos.config.server.utils.PropertyUtil; -import com.alibaba.nacos.persistence.configuration.DatasourceConfiguration; -import com.alibaba.nacos.sys.utils.ApplicationUtils; import com.google.common.collect.Lists; import java.io.IOException; @@ -64,23 +60,10 @@ public class ConfigCacheService { */ private static final ConcurrentHashMap CACHE = new ConcurrentHashMap<>(); - private static ConfigInfoPersistService configInfoPersistService; - - public static ConfigInfoPersistService getConfigInfoPersistService() { - if (configInfoPersistService == null) { - configInfoPersistService = ApplicationUtils.getBean(ConfigInfoPersistService.class); - } - return configInfoPersistService; - } - public static int groupCount() { return CACHE.size(); } - public static boolean hasGroupKey(String groupKey) { - return CACHE.containsKey(groupKey); - } - /** * Save config file and update md5 value in cache. * @@ -414,68 +397,6 @@ public static boolean dumpChange(String dataId, String group, String tenant, Str } } - /** - * Reload config. - */ - public static void reloadConfig() { - String aggreds = null; - try { - if (DatasourceConfiguration.isEmbeddedStorage()) { - ConfigInfoBase config = getConfigInfoPersistService().findConfigInfoBase(AggrWhitelist.AGGRIDS_METADATA, - "DEFAULT_GROUP"); - if (config != null) { - aggreds = config.getContent(); - } - } else { - aggreds = ConfigDiskServiceFactory.getInstance() - .getContent(AggrWhitelist.AGGRIDS_METADATA, "DEFAULT_GROUP", StringUtils.EMPTY); - } - if (aggreds != null) { - AggrWhitelist.load(aggreds); - } - } catch (IOException e) { - DUMP_LOG.error("reload fail:" + AggrWhitelist.AGGRIDS_METADATA, e); - } - - String clientIpWhitelist = null; - try { - if (DatasourceConfiguration.isEmbeddedStorage()) { - ConfigInfoBase config = getConfigInfoPersistService().findConfigInfoBase( - ClientIpWhiteList.CLIENT_IP_WHITELIST_METADATA, "DEFAULT_GROUP"); - if (config != null) { - clientIpWhitelist = config.getContent(); - } - } else { - clientIpWhitelist = ConfigDiskServiceFactory.getInstance() - .getContent(ClientIpWhiteList.CLIENT_IP_WHITELIST_METADATA, "DEFAULT_GROUP", StringUtils.EMPTY); - } - if (clientIpWhitelist != null) { - ClientIpWhiteList.load(clientIpWhitelist); - } - } catch (IOException e) { - DUMP_LOG.error("reload fail:" + ClientIpWhiteList.CLIENT_IP_WHITELIST_METADATA, e); - } - - String switchContent = null; - try { - if (DatasourceConfiguration.isEmbeddedStorage()) { - ConfigInfoBase config = getConfigInfoPersistService().findConfigInfoBase( - SwitchService.SWITCH_META_DATA_ID, "DEFAULT_GROUP"); - if (config != null) { - switchContent = config.getContent(); - } - } else { - switchContent = ConfigDiskServiceFactory.getInstance() - .getContent(SwitchService.SWITCH_META_DATA_ID, "DEFAULT_GROUP", StringUtils.EMPTY); - } - if (switchContent != null) { - SwitchService.load(switchContent); - } - } catch (IOException e) { - DUMP_LOG.error("reload fail:" + SwitchService.SWITCH_META_DATA_ID, e); - } - } - /** * Delete config file, and delete cache. * @@ -868,7 +789,7 @@ public static void updateTimeStamp(String groupKey, long lastModifiedTs, String * @param ips4Beta ips4Beta. * @param lastModifiedTs lastModifiedTs. */ - public static void updateBetaIpList(String groupKey, List ips4Beta, long lastModifiedTs) { + private static void updateBetaIpList(String groupKey, List ips4Beta, long lastModifiedTs) { CacheItem cache = makeSure(groupKey, null); cache.initBetaCacheIfEmpty(); cache.setBeta(true); @@ -884,7 +805,7 @@ public static void updateBetaIpList(String groupKey, List ips4Beta, long * @param groupKey groupKey. * @param lastModifiedTs lastModifiedTs. */ - public static void updateBetaTimeStamp(String groupKey, long lastModifiedTs) { + private static void updateBetaTimeStamp(String groupKey, long lastModifiedTs) { CacheItem cache = makeSure(groupKey, null); cache.initBetaCacheIfEmpty(); cache.getConfigCacheBeta().setLastModifiedTs(lastModifiedTs); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigSubService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigSubService.java index fd1f2cb2730..31b2a2c9234 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigSubService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigSubService.java @@ -20,10 +20,10 @@ import com.alibaba.nacos.common.http.param.Header; import com.alibaba.nacos.common.http.param.Query; import com.alibaba.nacos.common.model.RestResult; -import com.alibaba.nacos.common.utils.CollectionUtils; import com.alibaba.nacos.common.utils.JacksonUtils; import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.config.server.constant.Constants; +import com.alibaba.nacos.config.server.model.ListenerCheckResult; import com.alibaba.nacos.config.server.model.SampleResult; import com.alibaba.nacos.config.server.service.notify.HttpClientManager; import com.alibaba.nacos.config.server.utils.ConfigExecutor; @@ -31,9 +31,10 @@ import com.alibaba.nacos.core.cluster.Member; import com.alibaba.nacos.core.cluster.ServerMemberManager; import com.alibaba.nacos.sys.env.EnvUtil; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Collection; @@ -43,7 +44,6 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.CompletionService; -import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingDeque; @@ -62,16 +62,11 @@ public class ConfigSubService { private ServerMemberManager memberManager; - @Autowired @SuppressWarnings("PMD.ThreadPoolCreationRule") public ConfigSubService(ServerMemberManager memberManager) { this.memberManager = memberManager; } - protected ConfigSubService() { - - } - /** * Get and return called url string value. * @@ -79,49 +74,198 @@ protected ConfigSubService() { * @param relativePath path. * @return all path. */ - private String getUrl(String ip, String relativePath) { + private static String getUrl(String ip, String relativePath) { return HTTP_PREFIX + ip + EnvUtil.getContextPath() + relativePath; } - private List runCollectionJob(String url, Map params, - CompletionService completionService, List resultList) { + private List runConfigListenerCollectionJob(Map params, + CompletionService completionService) { + return new ClusterListenerJob(params, completionService, memberManager).runJobs(); + } + + static class ClusterListenerJob extends ClusterJob { + + static final String URL = Constants.COMMUNICATION_CONTROLLER_PATH + "/configWatchers"; - Collection ipList = memberManager.allMembers(); - List collectionResult = new ArrayList<>(ipList.size()); - // Submit query task. - for (Member ip : ipList) { - try { - completionService.submit(new Job(ip.getAddress(), url, params)); - } catch (Exception e) { // Send request failed. - LogUtil.DEFAULT_LOG.warn("Get client info from {} with exception: {} during submit job", ip, - e.getMessage()); + ClusterListenerJob(Map params, CompletionService completionService, + ServerMemberManager serverMemberManager) { + super(URL, params, completionService, serverMemberManager); + } + } + + private List runHasCheckListenerCollectionJob(Map params, + CompletionService completionService) { + return new ClusterCheckHasListenerJob(params, completionService, memberManager).runJobs(); + } + + class ClusterCheckHasListenerJob extends ClusterJob { + + static final String URL = Constants.COMMUNICATION_CONTROLLER_PATH + "/checkConfigWatchers"; + + ClusterCheckHasListenerJob(Map params, CompletionService completionService, + ServerMemberManager serverMemberManager) { + super(URL, params, completionService, serverMemberManager); + } + } + + @SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule") + abstract static class ClusterJob { + + private String url; + + private Map params; + + private CompletionService completionService; + + private ServerMemberManager serverMemberManager; + + ClusterJob(String url, Map params, CompletionService completionService, + ServerMemberManager serverMemberManager) { + this.url = url; + this.params = params; + this.completionService = completionService; + this.serverMemberManager = serverMemberManager; + } + + class Job implements Callable { + + private String ip; + + public Job(String ip) { + this.ip = ip; + } + + @Override + public T call() throws Exception { + return (T) runSingleJob(ip, params, url, ((ParameterizedType) ClusterJob.this.getClass() + .getGenericSuperclass()).getActualTypeArguments()[0]); } } - // Get and merge result. - SampleResult sampleResults; - for (Member member : ipList) { - try { - Future f = completionService.poll(1000, TimeUnit.MILLISECONDS); + + List runJobs() { + Collection ipList = serverMemberManager.allMembers(); + List collectionResult = new ArrayList<>(ipList.size()); + // Submit query task. + for (Member ip : ipList) { + try { + completionService.submit(new Job(ip.getAddress()) { + }); + } catch (Exception e) { // Send request failed. + LogUtil.DEFAULT_LOG.warn("invoke to {} with exception: {} during submit job", ip, e.getMessage()); + } + } + // Get and merge result. + T sampleResults; + for (Member member : ipList) { try { - if (f != null) { - sampleResults = f.get(500, TimeUnit.MILLISECONDS); - if (sampleResults != null) { - collectionResult.add(sampleResults); + Future f = completionService.poll(1000, TimeUnit.MILLISECONDS); + try { + if (f != null) { + sampleResults = f.get(500, TimeUnit.MILLISECONDS); + if (sampleResults != null) { + collectionResult.add(sampleResults); + } + } else { + LogUtil.DEFAULT_LOG.warn("The task in ip: {} did not completed in 1000ms ", member); } - } else { - LogUtil.DEFAULT_LOG.warn("The task in ip: {} did not completed in 1000ms ", member); + } catch (TimeoutException e) { + if (f != null) { + f.cancel(true); + } + LogUtil.DEFAULT_LOG.warn("get task result with TimeoutException: {} ", e.getMessage()); } - } catch (TimeoutException e) { - f.cancel(true); - LogUtil.DEFAULT_LOG.warn("get task result with TimeoutException: {} ", e.getMessage()); + } catch (Exception e) { + LogUtil.DEFAULT_LOG.warn("get task result with Exception: {} ", e.getMessage()); } - } catch (InterruptedException e) { - LogUtil.DEFAULT_LOG.warn("get task result with InterruptedException: {} ", e.getMessage()); - } catch (ExecutionException e) { - LogUtil.DEFAULT_LOG.warn("get task result with ExecutionException: {} ", e.getMessage()); } + return collectionResult; } - return collectionResult; + } + + /** + * run job to a single member. + * + * @param ip ip. + * @param params params. + * @param url url. + * @param type type. + * @return + */ + public static Object runSingleJob(String ip, Map params, String url, Type type) { + try { + StringBuilder paramUrl = new StringBuilder(); + for (Map.Entry param : params.entrySet()) { + paramUrl.append("&").append(param.getKey()).append("=") + .append(URLEncoder.encode(param.getValue(), Constants.ENCODE_UTF8)); + } + + String urlAll = getUrl(ip, url) + "?" + paramUrl; + RestResult result = invokeUrl(urlAll, Constants.ENCODE_UTF8); + // Http code 200 + if (result.ok()) { + Object t = JacksonUtils.toObj(result.getData(), type); + return t; + } else { + LogUtil.DEFAULT_LOG.info("Can not get remote from {} with {}", ip, result.getData()); + return null; + } + } catch (Exception e) { + LogUtil.DEFAULT_LOG.warn("Get remote info from {} with exception: {}", ip, e.getMessage()); + return null; + } + } + + public ListenerCheckResult getCheckHasListenerResult(String dataId, String group, String tenant, int sampleTime) + throws Exception { + Map params = new HashMap<>(5); + params.put("dataId", dataId); + params.put("group", group); + if (!StringUtils.isBlank(tenant)) { + params.put("tenant", tenant); + } + int size = memberManager.getServerList().size(); + BlockingQueue> queue = new LinkedBlockingDeque<>( + memberManager.getServerList().size()); + CompletionService completionService = new ExecutorCompletionService<>( + ConfigExecutor.getConfigSubServiceExecutor(), queue); + + ListenerCheckResult sampleCollectResult = new ListenerCheckResult(); + sampleCollectResult.setCode(201); + for (int i = 0; i < sampleTime; i++) { + List sampleResults = runHasCheckListenerCollectionJob(params, completionService); + if (sampleResults != null) { + sampleCollectResult = mergeListenerCheckResult(sampleCollectResult, sampleResults, size); + } + if (sampleCollectResult.isHasListener()) { + break; + } + + } + + return sampleCollectResult; + } + + /** + * if has all server has not listener,return false. + * + * @param listenerCheckResult listenerCheckResult. + * @param sampleResults sampleResults. + * @return + */ + public ListenerCheckResult mergeListenerCheckResult(ListenerCheckResult listenerCheckResult, + List sampleResults, int expectSize) { + for (ListenerCheckResult sampleResult : sampleResults) { + if (sampleResult.getCode() == 200 && sampleResult.isHasListener()) { + listenerCheckResult.setHasListener(true); + listenerCheckResult.setCode(200); + break; + } + } + if (!listenerCheckResult.isHasListener() && sampleResults.size() != expectSize) { + listenerCheckResult.setCode(201); + } + + return listenerCheckResult; } /** @@ -149,75 +293,8 @@ public SampleResult mergeSampleResult(SampleResult sampleCollectResult, List { - - private final String ip; - - private final String url; - - private final Map params; - - public Job(String ip, String url, Map params) { - this.ip = ip; - this.url = url; - this.params = params; - } - - @Override - public SampleResult call() throws Exception { - - try { - StringBuilder paramUrl = new StringBuilder(); - for (Map.Entry param : params.entrySet()) { - paramUrl.append('&').append(param.getKey()).append('=') - .append(URLEncoder.encode(param.getValue(), Constants.ENCODE)); - } - - String urlAll = getUrl(ip, url) + "?" + paramUrl; - RestResult result = invokeUrl(urlAll, null, Constants.ENCODE); - - // Http code 200 - if (result.ok()) { - return JacksonUtils.toObj(result.getData(), SampleResult.class); - } else { - - LogUtil.DEFAULT_LOG.info("Can not get clientInfo from {} with {}", ip, result.getData()); - return null; - } - } catch (Exception e) { - LogUtil.DEFAULT_LOG.warn("Get client info from {} with exception: {}", ip, e.getMessage()); - return null; - } - } - } - - /** - * invoke url. - * - * @param url url. - * @param headers headers. - * @param encoding encoding. - * @return result. - * @throws Exception Exception. - */ - private static RestResult invokeUrl(String url, List headers, String encoding) throws Exception { - Header header = Header.newInstance(); - header.addParam(HttpHeaderConsts.ACCEPT_CHARSET, encoding); - if (CollectionUtils.isNotEmpty(headers)) { - header.addAll(headers); - } - return HttpClientManager.getNacosRestTemplate().get(url, header, Query.EMPTY, String.class); - } - public SampleResult getCollectSampleResult(String dataId, String group, String tenant, int sampleTime) throws Exception { - List resultList = new ArrayList<>(); - String url = Constants.COMMUNICATION_CONTROLLER_PATH + "/configWatchers"; Map params = new HashMap<>(5); params.put("dataId", dataId); params.put("group", group); @@ -230,15 +307,15 @@ public SampleResult getCollectSampleResult(String dataId, String group, String t SampleResult sampleCollectResult = new SampleResult(); for (int i = 0; i < sampleTime; i++) { - List sampleResults = runCollectionJob(url, params, completionService, resultList); - sampleCollectResult = mergeSampleResult(sampleCollectResult, sampleResults); + List sampleResults = runConfigListenerCollectionJob(params, completionService); + if (sampleResults != null) { + sampleCollectResult = mergeSampleResult(sampleCollectResult, sampleResults); + } } return sampleCollectResult; } public SampleResult getCollectSampleResultByIp(String ip, int sampleTime) { - List resultList = new ArrayList<>(10); - String url = Constants.COMMUNICATION_CONTROLLER_PATH + "/watcherConfigs"; Map params = new HashMap<>(50); params.put("ip", ip); BlockingQueue> queue = new LinkedBlockingDeque<>(memberManager.getServerList().size()); @@ -247,10 +324,25 @@ public SampleResult getCollectSampleResultByIp(String ip, int sampleTime) { SampleResult sampleCollectResult = new SampleResult(); for (int i = 0; i < sampleTime; i++) { - List sampleResults = runCollectionJob(url, params, completionService, resultList); - sampleCollectResult = mergeSampleResult(sampleCollectResult, sampleResults); + List sampleResults = runConfigListenerCollectionJob(params, completionService); + if (sampleResults != null) { + sampleCollectResult = mergeSampleResult(sampleCollectResult, sampleResults); + } } return sampleCollectResult; } + /** + * invoke url with http. + * + * @param url url. + * @param encoding encoding. + * @return result. + * @throws Exception exception. + */ + public static RestResult invokeUrl(String url, String encoding) throws Exception { + Header header = Header.newInstance(); + header.addParam(HttpHeaderConsts.ACCEPT_CHARSET, encoding); + return HttpClientManager.getNacosRestTemplate().get(url, header, Query.EMPTY, String.class); + } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpChangeConfigWorker.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpChangeConfigWorker.java index 694bcf163d7..1c41b0fcbe4 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpChangeConfigWorker.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpChangeConfigWorker.java @@ -46,12 +46,19 @@ public class DumpChangeConfigWorker implements Runnable { Timestamp startTime; - public DumpChangeConfigWorker(DumpService dumpService, Timestamp startTime) { - this.configInfoPersistService = dumpService.getConfigInfoPersistService(); - this.historyConfigInfoPersistService = dumpService.getHistoryConfigInfoPersistService(); + public DumpChangeConfigWorker(ConfigInfoPersistService configInfoPersistService, + HistoryConfigInfoPersistService historyConfigInfoPersistService, Timestamp startTime) { + this.configInfoPersistService = configInfoPersistService; + this.historyConfigInfoPersistService = historyConfigInfoPersistService; this.startTime = startTime; } + int pageSize = 100; + + public void setPageSize(int pageSize) { + this.pageSize = pageSize; + } + /** * do check change. */ @@ -68,7 +75,6 @@ public void run() { LogUtil.DEFAULT_LOG.info("Start to check delete configs from time {}", startTime); - int pageSize = 100; long startDeletedConfigTime = System.currentTimeMillis(); LogUtil.DEFAULT_LOG.info("Check delete configs from time {}", startTime); @@ -78,7 +84,7 @@ public void run() { List configDeleted = historyConfigInfoPersistService.findDeletedConfig(startTime, deleteCursorId, pageSize); for (ConfigInfo configInfo : configDeleted) { - if (configInfoPersistService.findConfigInfo(configInfo.getDataId(), configInfo.getGroup(), + if (configInfoPersistService.findConfigInfoState(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()) == null) { ConfigCacheService.remove(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpService.java index 824352732fb..ad3c430001f 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpService.java @@ -21,15 +21,10 @@ import com.alibaba.nacos.common.notify.Event; import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.common.notify.listener.Subscriber; -import com.alibaba.nacos.common.utils.MD5Utils; import com.alibaba.nacos.common.utils.StringUtils; -import com.alibaba.nacos.config.server.constant.Constants; import com.alibaba.nacos.config.server.manager.TaskManager; -import com.alibaba.nacos.config.server.model.ConfigInfo; -import com.alibaba.nacos.config.server.model.ConfigInfoAggr; import com.alibaba.nacos.config.server.model.ConfigInfoChanged; import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent; -import com.alibaba.nacos.config.server.service.ConfigCacheService; import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskServiceFactory; import com.alibaba.nacos.config.server.service.dump.processor.DumpAllBetaProcessor; import com.alibaba.nacos.config.server.service.dump.processor.DumpAllProcessor; @@ -39,16 +34,13 @@ import com.alibaba.nacos.config.server.service.dump.task.DumpAllTagTask; import com.alibaba.nacos.config.server.service.dump.task.DumpAllTask; import com.alibaba.nacos.config.server.service.dump.task.DumpTask; -import com.alibaba.nacos.config.server.service.merge.MergeTaskProcessor; +import com.alibaba.nacos.config.server.service.merge.MergeDatumService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoAggrPersistService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoBetaPersistService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService; import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService; import com.alibaba.nacos.config.server.utils.ConfigExecutor; -import com.alibaba.nacos.config.server.utils.ContentUtils; -import com.alibaba.nacos.config.server.utils.DiskUtil; -import com.alibaba.nacos.config.server.utils.GroupKey; import com.alibaba.nacos.config.server.utils.GroupKey2; import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.config.server.utils.PropertyUtil; @@ -56,9 +48,7 @@ import com.alibaba.nacos.core.cluster.ServerMemberManager; import com.alibaba.nacos.core.namespace.repository.NamespacePersistService; import com.alibaba.nacos.persistence.datasource.DynamicDataSource; -import com.alibaba.nacos.persistence.model.Page; import com.alibaba.nacos.sys.env.EnvUtil; -import com.alibaba.nacos.sys.utils.InetUtils; import com.alibaba.nacos.sys.utils.TimerContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -66,12 +56,10 @@ import java.io.IOException; import java.sql.Timestamp; import java.text.SimpleDateFormat; -import java.util.ArrayList; import java.util.Calendar; import java.util.List; import java.util.Random; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; import static com.alibaba.nacos.config.server.utils.LogUtil.DUMP_LOG; import static com.alibaba.nacos.config.server.utils.LogUtil.FATAL_LOG; @@ -106,6 +94,8 @@ public abstract class DumpService { protected ConfigInfoTagPersistService configInfoTagPersistService; + protected MergeDatumService mergeDatumService; + protected final ServerMemberManager memberManager; /** @@ -113,11 +103,6 @@ public abstract class DumpService { */ static final int DUMP_ALL_INTERVAL_IN_MINUTE = 6 * 60; - /** - * full dump interval. - */ - static final int DUMP_CHANGE_INTERVAL_IN_SECONDS = 15; - /** * full dump delay. */ @@ -127,8 +112,6 @@ public abstract class DumpService { private TaskManager dumpAllTaskMgr; - static final AtomicInteger FINISHED = new AtomicInteger(); - static final int INIT_THREAD_COUNT = 10; int total = 0; @@ -150,13 +133,15 @@ public DumpService(ConfigInfoPersistService configInfoPersistService, HistoryConfigInfoPersistService historyConfigInfoPersistService, ConfigInfoAggrPersistService configInfoAggrPersistService, ConfigInfoBetaPersistService configInfoBetaPersistService, - ConfigInfoTagPersistService configInfoTagPersistService, ServerMemberManager memberManager) { + ConfigInfoTagPersistService configInfoTagPersistService, MergeDatumService mergeDatumService, + ServerMemberManager memberManager) { this.configInfoPersistService = configInfoPersistService; this.namespacePersistService = namespacePersistService; this.historyConfigInfoPersistService = historyConfigInfoPersistService; this.configInfoAggrPersistService = configInfoAggrPersistService; this.configInfoBetaPersistService = configInfoBetaPersistService; this.configInfoTagPersistService = configInfoTagPersistService; + this.mergeDatumService = mergeDatumService; this.memberManager = memberManager; this.processor = new DumpProcessor(this.configInfoPersistService, this.configInfoBetaPersistService, this.configInfoTagPersistService); @@ -179,17 +164,7 @@ public DumpService(ConfigInfoPersistService configInfoPersistService, @Override public void onEvent(Event event) { - // Generate ConfigDataChangeEvent concurrently - if (event instanceof ConfigDataChangeEvent) { - ConfigDataChangeEvent evt = (ConfigDataChangeEvent) event; - - DumpRequest dumpRequest = DumpRequest.create(evt.dataId, evt.group, evt.tenant, evt.lastModifiedTs, - NetUtils.localIP()); - dumpRequest.setBeta(evt.isBeta); - dumpRequest.setBatch(evt.isBatch); - dumpRequest.setTag(evt.tag); - DumpService.this.dump(dumpRequest); - } + handleConfigDataChange(event); } @Override @@ -199,56 +174,92 @@ public Class subscribeType() { }); } - public ConfigInfoPersistService getConfigInfoPersistService() { - return configInfoPersistService; + void handleConfigDataChange(Event event) { + // Generate ConfigDataChangeEvent concurrently + if (event instanceof ConfigDataChangeEvent) { + ConfigDataChangeEvent evt = (ConfigDataChangeEvent) event; + + DumpRequest dumpRequest = DumpRequest.create(evt.dataId, evt.group, evt.tenant, evt.lastModifiedTs, + NetUtils.localIP()); + dumpRequest.setBeta(evt.isBeta); + dumpRequest.setBatch(evt.isBatch); + dumpRequest.setTag(evt.tag); + DumpService.this.dump(dumpRequest); + } } - public ConfigInfoBetaPersistService getConfigInfoBetaPersistService() { - return configInfoBetaPersistService; + /** + * initialize. + * + * @throws Throwable throws Exception when actually operate. + */ + protected abstract void init() throws Throwable; + + void clearConfigHistory() { + LOGGER.warn("clearConfigHistory start"); + if (canExecute()) { + try { + Timestamp startTime = getBeforeStamp(TimeUtils.getCurrentTime(), 24 * getRetentionDays()); + int pageSize = 1000; + LOGGER.warn("clearConfigHistory, getBeforeStamp:{}, pageSize:{}", startTime, pageSize); + historyConfigInfoPersistService.removeConfigHistory(startTime, pageSize); + } catch (Throwable e) { + LOGGER.error("clearConfigHistory error : {}", e.toString()); + } + } + } - public ConfigInfoTagPersistService getConfigInfoTagPersistService() { - return configInfoTagPersistService; + /** + * config history clear. + */ + class ConfigHistoryClear implements Runnable { + + @Override + public void run() { + clearConfigHistory(); + } } - public HistoryConfigInfoPersistService getHistoryConfigInfoPersistService() { - return historyConfigInfoPersistService; + /** + * config history clear. + */ + class DumpAllProcessorRunner implements Runnable { + + @Override + public void run() { + dumpAllTaskMgr.addTask(DumpAllTask.TASK_ID, new DumpAllTask()); + } } /** - * initialize. - * - * @throws Throwable throws Exception when actually operate. + * dump all beta processor runner. */ - protected abstract void init() throws Throwable; + class DumpAllBetaProcessorRunner implements Runnable { + + @Override + public void run() { + dumpAllTaskMgr.addTask(DumpAllBetaTask.TASK_ID, new DumpAllBetaTask()); + } + } - protected void dumpOperate(DumpProcessor processor, DumpAllProcessor dumpAllProcessor, - DumpAllBetaProcessor dumpAllBetaProcessor, DumpAllTagProcessor dumpAllTagProcessor) throws NacosException { + /** + * dump all tag processor runner. + */ + class DumpAllTagProcessorRunner implements Runnable { + + @Override + public void run() { + dumpAllTaskMgr.addTask(DumpAllTagTask.TASK_ID, new DumpAllTagTask()); + } + } + + protected void dumpOperate() throws NacosException { String dumpFileContext = "CONFIG_DUMP_TO_FILE"; TimerContext.start(dumpFileContext); try { LogUtil.DEFAULT_LOG.warn("DumpService start"); - Runnable dumpAll = () -> dumpAllTaskMgr.addTask(DumpAllTask.TASK_ID, new DumpAllTask()); - - Runnable dumpAllBeta = () -> dumpAllTaskMgr.addTask(DumpAllBetaTask.TASK_ID, new DumpAllBetaTask()); - - Runnable dumpAllTag = () -> dumpAllTaskMgr.addTask(DumpAllTagTask.TASK_ID, new DumpAllTagTask()); - - Runnable clearConfigHistory = () -> { - LOGGER.warn("clearConfigHistory start"); - if (canExecute()) { - try { - Timestamp startTime = getBeforeStamp(TimeUtils.getCurrentTime(), 24 * getRetentionDays()); - int pageSize = 1000; - LOGGER.warn("clearConfigHistory, getBeforeStamp:{}, pageSize:{}", startTime, pageSize); - historyConfigInfoPersistService.removeConfigHistory(startTime, pageSize); - } catch (Throwable e) { - LOGGER.error("clearConfigHistory error : {}", e.toString()); - } - } - }; - Timestamp currentTime = new Timestamp(System.currentTimeMillis()); try { @@ -271,10 +282,10 @@ protected void dumpOperate(DumpProcessor processor, DumpAllProcessor dumpAllProc List configList = configInfoAggrPersistService.findAllAggrGroup(); if (configList != null && !configList.isEmpty()) { total = configList.size(); - List> splitList = splitList(configList, INIT_THREAD_COUNT); + List> splitList = mergeDatumService.splitList(configList, + INIT_THREAD_COUNT); for (List list : splitList) { - MergeAllDataWorker work = new MergeAllDataWorker(list); - work.start(); + mergeDatumService.executeConfigsMerge(list); } LOGGER.info("server start, schedule merge end."); } @@ -286,34 +297,27 @@ protected void dumpOperate(DumpProcessor processor, DumpAllProcessor dumpAllProc e); } if (!EnvUtil.getStandaloneMode()) { - Runnable heartbeat = () -> { - String heartBeatTime = TimeUtils.getCurrentTime().toString(); - // write disk - try { - DiskUtil.saveHeartBeatToDisk(heartBeatTime); - } catch (IOException e) { - LogUtil.FATAL_LOG.error("save heartbeat fail" + e.getMessage()); - } - }; - ConfigExecutor.scheduleConfigTask(heartbeat, 0, 10, TimeUnit.SECONDS); Random random = new Random(); long initialDelay = random.nextInt(INITIAL_DELAY_IN_MINUTE) + 10; LogUtil.DEFAULT_LOG.warn("initialDelay:{}", initialDelay); - ConfigExecutor.scheduleConfigTask(dumpAll, initialDelay, DUMP_ALL_INTERVAL_IN_MINUTE, TimeUnit.MINUTES); + ConfigExecutor.scheduleConfigTask(new DumpAllProcessorRunner(), initialDelay, + DUMP_ALL_INTERVAL_IN_MINUTE, TimeUnit.MINUTES); - ConfigExecutor.scheduleConfigTask(dumpAllBeta, initialDelay, DUMP_ALL_INTERVAL_IN_MINUTE, - TimeUnit.MINUTES); + ConfigExecutor.scheduleConfigTask(new DumpAllBetaProcessorRunner(), initialDelay, + DUMP_ALL_INTERVAL_IN_MINUTE, TimeUnit.MINUTES); - ConfigExecutor.scheduleConfigTask(dumpAllTag, initialDelay, DUMP_ALL_INTERVAL_IN_MINUTE, - TimeUnit.MINUTES); - ConfigExecutor.scheduleConfigChangeTask(new DumpChangeConfigWorker(this, currentTime), - random.nextInt((int) PropertyUtil.getDumpChangeWorkerInterval()), TimeUnit.MILLISECONDS); + ConfigExecutor.scheduleConfigTask(new DumpAllTagProcessorRunner(), initialDelay, + DUMP_ALL_INTERVAL_IN_MINUTE, TimeUnit.MINUTES); + ConfigExecutor.scheduleConfigChangeTask( + new DumpChangeConfigWorker(this.configInfoPersistService, this.historyConfigInfoPersistService, + currentTime), random.nextInt((int) PropertyUtil.getDumpChangeWorkerInterval()), + TimeUnit.MILLISECONDS); } - ConfigExecutor.scheduleConfigTask(clearConfigHistory, 10, 10, TimeUnit.MINUTES); + ConfigExecutor.scheduleConfigTask(new ConfigHistoryClear(), 10, 10, TimeUnit.MINUTES); } finally { TimerContext.end(dumpFileContext, LogUtil.DUMP_LOG); } @@ -392,7 +396,7 @@ public void dump(DumpRequest dumpRequest) { */ private void dumpFormal(String dataId, String group, String tenant, long lastModified, String handleIp) { String groupKey = GroupKey2.getKey(dataId, group, tenant); - String taskKey = dataId + group + tenant; + String taskKey = groupKey; dumpTaskMgr.addTask(taskKey, new DumpTask(groupKey, false, false, false, null, lastModified, handleIp)); DUMP_LOG.info("[dump] add formal task. groupKey={}", groupKey); @@ -409,7 +413,7 @@ private void dumpFormal(String dataId, String group, String tenant, long lastMod */ private void dumpBeta(String dataId, String group, String tenant, long lastModified, String handleIp) { String groupKey = GroupKey2.getKey(dataId, group, tenant); - String taskKey = dataId + group + tenant + "+beta"; + String taskKey = groupKey + "+beta"; dumpTaskMgr.addTask(taskKey, new DumpTask(groupKey, true, false, false, null, lastModified, handleIp)); DUMP_LOG.info("[dump] add beta task. groupKey={}", groupKey); @@ -453,85 +457,6 @@ public void dumpAll() { dumpAllTaskMgr.addTask(DumpAllTask.TASK_ID, new DumpAllTask()); } - static List> splitList(List list, int count) { - List> result = new ArrayList<>(count); - for (int i = 0; i < count; i++) { - result.add(new ArrayList<>()); - } - for (int i = 0; i < list.size(); i++) { - ConfigInfoChanged config = list.get(i); - result.get(i % count).add(config); - } - return result; - } - - class MergeAllDataWorker extends Thread { - - static final int PAGE_SIZE = 10000; - - private List configInfoList; - - public MergeAllDataWorker(List configInfoList) { - super("MergeAllDataWorker"); - this.configInfoList = configInfoList; - } - - @Override - public void run() { - if (!canExecute()) { - return; - } - for (ConfigInfoChanged configInfo : configInfoList) { - String dataId = configInfo.getDataId(); - String group = configInfo.getGroup(); - String tenant = configInfo.getTenant(); - try { - List datumList = new ArrayList<>(); - int rowCount = configInfoAggrPersistService.aggrConfigInfoCount(dataId, group, tenant); - int pageCount = (int) Math.ceil(rowCount * 1.0 / PAGE_SIZE); - for (int pageNo = 1; pageNo <= pageCount; pageNo++) { - Page page = configInfoAggrPersistService.findConfigInfoAggrByPage(dataId, group, - tenant, pageNo, PAGE_SIZE); - if (page != null) { - datumList.addAll(page.getPageItems()); - LOGGER.info("[merge-query] {}, {}, size/total={}/{}", dataId, group, datumList.size(), - rowCount); - } - } - - // merge - if (datumList.size() > 0) { - ConfigInfo cf = MergeTaskProcessor.merge(dataId, group, tenant, datumList); - String aggrContent = cf.getContent(); - String localContentMD5 = ConfigCacheService.getContentMd5(GroupKey.getKey(dataId, group)); - String aggrConetentMD5 = MD5Utils.md5Hex(aggrContent, Constants.ENCODE); - - if (!StringUtils.equals(localContentMD5, aggrConetentMD5)) { - configInfoPersistService.insertOrUpdate(null, null, cf, null); - LOGGER.info("[merge-ok] {}, {}, size={}, length={}, md5={}, content={}", dataId, group, - datumList.size(), cf.getContent().length(), cf.getMd5(), - ContentUtils.truncateContent(cf.getContent())); - } - } else { - // remove config info - configInfoPersistService.removeConfigInfo(dataId, group, tenant, InetUtils.getSelfIP(), null); - LOGGER.warn( - "[merge-delete] delete config info because no datum. dataId=" + dataId + ", groupId=" - + group); - } - - } catch (Throwable e) { - LOGGER.info("[merge-error] " + dataId + ", " + group + ", " + e.toString(), e); - } - FINISHED.incrementAndGet(); - if (FINISHED.get() % 100 == 0) { - LOGGER.info("[all-merge-dump] {} / {}", FINISHED.get(), total); - } - } - LOGGER.info("[all-merge-dump] {} / {}", FINISHED.get(), total); - } - } - /** * Used to determine whether the aggregation task, configuration history cleanup task can be performed. * diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/EmbeddedDumpService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/EmbeddedDumpService.java index a26a072c8df..4895cbdf13c 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/EmbeddedDumpService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/EmbeddedDumpService.java @@ -20,6 +20,7 @@ import com.alibaba.nacos.common.utils.Observer; import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.common.utils.ThreadUtils; +import com.alibaba.nacos.config.server.service.merge.MergeDatumService; import com.alibaba.nacos.persistence.configuration.condition.ConditionOnEmbeddedStorage; import com.alibaba.nacos.core.namespace.repository.NamespacePersistService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoAggrPersistService; @@ -73,13 +74,15 @@ public class EmbeddedDumpService extends DumpService { * @param protocolManager {@link ProtocolManager} */ public EmbeddedDumpService(ConfigInfoPersistService configInfoPersistService, - NamespacePersistService namespacePersistService, HistoryConfigInfoPersistService historyConfigInfoPersistService, + NamespacePersistService namespacePersistService, + HistoryConfigInfoPersistService historyConfigInfoPersistService, ConfigInfoAggrPersistService configInfoAggrPersistService, ConfigInfoBetaPersistService configInfoBetaPersistService, - ConfigInfoTagPersistService configInfoTagPersistService, ServerMemberManager memberManager, - ProtocolManager protocolManager) { + ConfigInfoTagPersistService configInfoTagPersistService, MergeDatumService mergeDatumService, + ServerMemberManager memberManager, ProtocolManager protocolManager) { super(configInfoPersistService, namespacePersistService, historyConfigInfoPersistService, - configInfoAggrPersistService, configInfoBetaPersistService, configInfoTagPersistService, memberManager); + configInfoAggrPersistService, configInfoBetaPersistService, configInfoTagPersistService, + mergeDatumService, memberManager); this.protocolManager = protocolManager; } @@ -87,7 +90,7 @@ public EmbeddedDumpService(ConfigInfoPersistService configInfoPersistService, @Override protected void init() throws Throwable { if (EnvUtil.getStandaloneMode()) { - dumpOperate(processor, dumpAllProcessor, dumpAllBetaProcessor, dumpAllTagProcessor); + dumpOperate(); return; } @@ -110,14 +113,15 @@ public void update(Observable o) { return; } // Identify without a timeout mechanism - EmbeddedStorageContextHolder.putExtendInfo(PersistenceConstant.EXTEND_NEED_READ_UNTIL_HAVE_DATA, "true"); + EmbeddedStorageContextHolder.putExtendInfo(PersistenceConstant.EXTEND_NEED_READ_UNTIL_HAVE_DATA, + "true"); // Remove your own listening to avoid task accumulation boolean canEnd = false; for (; ; ) { try { - dumpOperate(processor, dumpAllProcessor, dumpAllBetaProcessor, dumpAllTagProcessor); - protocol.protocolMetaData() - .unSubscribe(PersistenceConstant.CONFIG_MODEL_RAFT_GROUP, MetadataKey.LEADER_META_DATA, this); + dumpOperate(); + protocol.protocolMetaData().unSubscribe(PersistenceConstant.CONFIG_MODEL_RAFT_GROUP, + MetadataKey.LEADER_META_DATA, this); canEnd = true; } catch (Throwable ex) { if (!shouldRetry(ex)) { diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/ExternalDumpService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/ExternalDumpService.java index 74afaa74bfc..3b2b20fba1d 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/ExternalDumpService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/ExternalDumpService.java @@ -16,6 +16,7 @@ package com.alibaba.nacos.config.server.service.dump; +import com.alibaba.nacos.config.server.service.merge.MergeDatumService; import com.alibaba.nacos.core.namespace.repository.NamespacePersistService; import com.alibaba.nacos.persistence.configuration.condition.ConditionOnExternalStorage; import com.alibaba.nacos.config.server.service.repository.ConfigInfoAggrPersistService; @@ -47,18 +48,21 @@ public class ExternalDumpService extends DumpService { * @param memberManager {@link ServerMemberManager} */ public ExternalDumpService(ConfigInfoPersistService configInfoPersistService, - NamespacePersistService namespacePersistService, HistoryConfigInfoPersistService historyConfigInfoPersistService, + NamespacePersistService namespacePersistService, + HistoryConfigInfoPersistService historyConfigInfoPersistService, ConfigInfoAggrPersistService configInfoAggrPersistService, ConfigInfoBetaPersistService configInfoBetaPersistService, - ConfigInfoTagPersistService configInfoTagPersistService, ServerMemberManager memberManager) { + ConfigInfoTagPersistService configInfoTagPersistService, MergeDatumService mergeDatumService, + ServerMemberManager memberManager) { super(configInfoPersistService, namespacePersistService, historyConfigInfoPersistService, - configInfoAggrPersistService, configInfoBetaPersistService, configInfoTagPersistService, memberManager); + configInfoAggrPersistService, configInfoBetaPersistService, configInfoTagPersistService, + mergeDatumService, memberManager); } @PostConstruct @Override protected void init() throws Throwable { - dumpOperate(processor, dumpAllProcessor, dumpAllBetaProcessor, dumpAllTagProcessor); + dumpOperate(); } @Override diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/disk/ConfigRocksDbDiskService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/disk/ConfigRocksDbDiskService.java index e655832e4e4..af62a0b3d91 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/disk/ConfigRocksDbDiskService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/disk/ConfigRocksDbDiskService.java @@ -59,11 +59,11 @@ public class ConfigRocksDbDiskService implements ConfigDiskService { private void createDirIfNotExist(String dir) { File roskDataDir = new File(EnvUtil.getNacosHome(), "rocksdata"); if (!roskDataDir.exists()) { - roskDataDir.mkdir(); + roskDataDir.mkdirs(); } File baseDir = new File(EnvUtil.getNacosHome(), dir); if (!baseDir.exists()) { - baseDir.mkdir(); + baseDir.mkdirs(); } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/merge/MergeDatumService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/merge/MergeDatumService.java index f358f312fc8..cb039bfe75d 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/merge/MergeDatumService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/merge/MergeDatumService.java @@ -16,19 +16,23 @@ package com.alibaba.nacos.config.server.service.merge; +import com.alibaba.nacos.common.utils.MD5Utils; +import com.alibaba.nacos.common.utils.StringUtils; +import com.alibaba.nacos.config.server.constant.Constants; import com.alibaba.nacos.config.server.manager.TaskManager; import com.alibaba.nacos.config.server.model.ConfigInfo; import com.alibaba.nacos.config.server.model.ConfigInfoAggr; import com.alibaba.nacos.config.server.model.ConfigInfoChanged; -import com.alibaba.nacos.persistence.configuration.DatasourceConfiguration; -import com.alibaba.nacos.persistence.constants.PersistenceConstant; -import com.alibaba.nacos.persistence.model.Page; +import com.alibaba.nacos.config.server.service.ConfigCacheService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoAggrPersistService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService; import com.alibaba.nacos.config.server.utils.ContentUtils; -import com.alibaba.nacos.config.server.utils.TimeUtils; +import com.alibaba.nacos.config.server.utils.GroupKey; import com.alibaba.nacos.core.distributed.ProtocolManager; +import com.alibaba.nacos.persistence.configuration.DatasourceConfiguration; +import com.alibaba.nacos.persistence.constants.PersistenceConstant; +import com.alibaba.nacos.persistence.model.Page; import com.alibaba.nacos.sys.env.EnvUtil; import com.alibaba.nacos.sys.utils.ApplicationUtils; import com.alibaba.nacos.sys.utils.InetUtils; @@ -37,7 +41,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; @@ -78,10 +81,17 @@ public MergeDatumService(ConfigInfoPersistService configInfoPersistService, configInfoTagPersistService, this)); } - static List> splitList(List list, int count) { + /** + * splitList. + * + * @param list list to split. + * @param count count expect to be split. + * @return + */ + public List> splitList(List list, int count) { List> result = new ArrayList<>(count); for (int i = 0; i < count; i++) { - result.add(new ArrayList()); + result.add(new ArrayList<>()); } for (int i = 0; i < list.size(); i++) { ConfigInfoChanged config = list.get(i); @@ -90,17 +100,6 @@ static List> splitList(List list, int return result; } - /** - * Called after data changes to add aggregation tasks. - */ - public void addMergeTask(String dataId, String groupId, String tenant, String tag, String clientIp) { - if (!canExecute()) { - return; - } - MergeDataTask task = new MergeDataTask(dataId, groupId, tenant, tag, clientIp); - mergeTasks.addTask(task.getId(), task); - } - /** * Called after data changes to add aggregation tasks. */ @@ -112,18 +111,6 @@ public void addMergeTask(String dataId, String groupId, String tenant, String cl mergeTasks.addTask(task.getId(), task); } - /** - * Merge all. - */ - public void mergeAll() { - if (!canExecute()) { - return; - } - for (ConfigInfoChanged item : configInfoAggrPersistService.findAllAggrGroup()) { - addMergeTask(item.getDataId(), item.getGroup(), item.getTenant(), InetUtils.getSelfIP()); - } - } - private boolean canExecute() { if (!DatasourceConfiguration.isEmbeddedStorage()) { return true; @@ -135,7 +122,61 @@ private boolean canExecute() { return protocolManager.getCpProtocol().isLeader(PersistenceConstant.CONFIG_MODEL_RAFT_GROUP); } - class MergeAllDataWorker extends Thread { + void executeMergeConfigTask(List configInfoList, int pageSize) { + for (ConfigInfoChanged configInfo : configInfoList) { + String dataId = configInfo.getDataId(); + String group = configInfo.getGroup(); + String tenant = configInfo.getTenant(); + try { + List datumList = new ArrayList<>(); + int rowCount = configInfoAggrPersistService.aggrConfigInfoCount(dataId, group, tenant); + int pageCount = (int) Math.ceil(rowCount * 1.0 / pageSize); + for (int pageNo = 1; pageNo <= pageCount; pageNo++) { + Page page = configInfoAggrPersistService.findConfigInfoAggrByPage(dataId, group, + tenant, pageNo, pageSize); + if (page != null) { + datumList.addAll(page.getPageItems()); + LOGGER.info("[merge-query] {}, {}, size/total={}/{}", dataId, group, datumList.size(), + rowCount); + } + } + + // merge + if (datumList.size() > 0) { + ConfigInfo cf = MergeTaskProcessor.merge(dataId, group, tenant, datumList); + String aggrContent = cf.getContent(); + String localContentMD5 = ConfigCacheService.getContentMd5(GroupKey.getKey(dataId, group)); + String aggrConetentMD5 = MD5Utils.md5Hex(aggrContent, Constants.ENCODE); + + if (!StringUtils.equals(localContentMD5, aggrConetentMD5)) { + configInfoPersistService.insertOrUpdate(null, null, cf, null); + LOGGER.info("[merge-ok] {}, {}, size={}, length={}, md5={}, content={}", dataId, group, + datumList.size(), cf.getContent().length(), cf.getMd5(), + ContentUtils.truncateContent(cf.getContent())); + } + } else { + // remove config info + configInfoPersistService.removeConfigInfo(dataId, group, tenant, InetUtils.getSelfIP(), null); + LOGGER.warn("[merge-delete] delete config info because no datum. dataId=" + dataId + ", groupId=" + + group); + } + + } catch (Throwable e) { + LOGGER.info("[merge-error] " + dataId + ", " + group + ", " + e.toString(), e); + } + FINISHED.incrementAndGet(); + if (FINISHED.get() % 100 == 0) { + LOGGER.info("[all-merge-dump] {} / {}", FINISHED.get(), total); + } + } + LOGGER.info("[all-merge-dump] {} / {}", FINISHED.get(), total); + } + + public void executeConfigsMerge(List configInfoList) { + new MergeAllDataWorker(configInfoList).start(); + } + + public class MergeAllDataWorker extends Thread { static final int PAGE_SIZE = 10000; @@ -148,49 +189,7 @@ public MergeAllDataWorker(List configInfoList) { @Override public void run() { - for (ConfigInfoChanged configInfo : configInfoList) { - String dataId = configInfo.getDataId(); - String group = configInfo.getGroup(); - String tenant = configInfo.getTenant(); - try { - List datumList = new ArrayList<>(); - int rowCount = configInfoAggrPersistService.aggrConfigInfoCount(dataId, group, tenant); - int pageCount = (int) Math.ceil(rowCount * 1.0 / PAGE_SIZE); - for (int pageNo = 1; pageNo <= pageCount; pageNo++) { - Page page = configInfoAggrPersistService - .findConfigInfoAggrByPage(dataId, group, tenant, pageNo, PAGE_SIZE); - if (page != null) { - datumList.addAll(page.getPageItems()); - LOGGER.info("[merge-query] {}, {}, size/total={}/{}", dataId, group, datumList.size(), - rowCount); - } - } - - final Timestamp time = TimeUtils.getCurrentTime(); - - if (datumList.size() > 0) { - // merge - ConfigInfo cf = MergeTaskProcessor.merge(dataId, group, tenant, datumList); - configInfoPersistService.insertOrUpdate(null, null, cf, null); - LOGGER.info("[merge-ok] {}, {}, size={}, length={}, md5={}, content={}", dataId, group, - datumList.size(), cf.getContent().length(), cf.getMd5(), - ContentUtils.truncateContent(cf.getContent())); - } else { - // remove - configInfoPersistService.removeConfigInfo(dataId, group, tenant, InetUtils.getSelfIP(), null); - LOGGER.warn("[merge-delete] delete config info because no datum. dataId=" + dataId + ", groupId=" - + group); - } - - } catch (Exception e) { - LOGGER.info("[merge-error] " + dataId + ", " + group + ", " + e.toString(), e); - } - FINISHED.incrementAndGet(); - if (FINISHED.get() % 100 == 0) { - LOGGER.info("[all-merge-dump] {} / {}", FINISHED.get(), total); - } - } - LOGGER.info("[all-merge-dump] {} / {}", FINISHED.get(), total); + executeMergeConfigTask(configInfoList, PAGE_SIZE); } } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/notify/AsyncNotifyService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/notify/AsyncNotifyService.java index 854566c2c86..cb66c8f4d22 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/notify/AsyncNotifyService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/notify/AsyncNotifyService.java @@ -88,31 +88,7 @@ public AsyncNotifyService(ServerMemberManager memberManager) { @Override public void onEvent(Event event) { // Generate ConfigDataChangeEvent concurrently - if (event instanceof ConfigDataChangeEvent) { - ConfigDataChangeEvent evt = (ConfigDataChangeEvent) event; - long dumpTs = evt.lastModifiedTs; - String dataId = evt.dataId; - String group = evt.group; - String tenant = evt.tenant; - String tag = evt.tag; - MetricsMonitor.incrementConfigChangeCount(tenant, group, dataId); - - Collection ipList = memberManager.allMembersWithoutSelf(); - - // In fact, any type of queue here can be - Queue rpcQueue = new LinkedList<>(); - - for (Member member : ipList) { - // grpc report data change only - rpcQueue.add( - new NotifySingleRpcTask(dataId, group, tenant, tag, dumpTs, evt.isBeta, evt.isBatch, - member)); - } - if (!rpcQueue.isEmpty()) { - ConfigExecutor.executeAsyncNotify(new AsyncRpcTask(rpcQueue)); - } - - } + handleConfigDataChangeEvent(event); } @Override @@ -122,11 +98,81 @@ public Class subscribeType() { }); } + void handleConfigDataChangeEvent(Event event) { + if (event instanceof ConfigDataChangeEvent) { + ConfigDataChangeEvent evt = (ConfigDataChangeEvent) event; + long dumpTs = evt.lastModifiedTs; + String dataId = evt.dataId; + String group = evt.group; + String tenant = evt.tenant; + String tag = evt.tag; + MetricsMonitor.incrementConfigChangeCount(tenant, group, dataId); + + Collection ipList = memberManager.allMembersWithoutSelf(); + + // In fact, any type of queue here can be + Queue rpcQueue = new LinkedList<>(); + + for (Member member : ipList) { + // grpc report data change only + rpcQueue.add( + new NotifySingleRpcTask(dataId, group, tenant, tag, dumpTs, evt.isBeta, evt.isBatch, member)); + } + if (!rpcQueue.isEmpty()) { + ConfigExecutor.executeAsyncNotify(new AsyncRpcTask(rpcQueue)); + } + } + } + private boolean isUnHealthy(String targetIp) { return !memberManager.stateCheck(targetIp, HEALTHY_CHECK_STATUS); } - class AsyncRpcTask implements Runnable { + void executeAsyncRpcTask(Queue queue) { + while (!queue.isEmpty()) { + NotifySingleRpcTask task = queue.poll(); + + ConfigChangeClusterSyncRequest syncRequest = new ConfigChangeClusterSyncRequest(); + syncRequest.setDataId(task.getDataId()); + syncRequest.setGroup(task.getGroup()); + syncRequest.setBeta(task.isBeta()); + syncRequest.setLastModified(task.getLastModified()); + syncRequest.setTag(task.getTag()); + syncRequest.setBatch(task.isBatch()); + syncRequest.setTenant(task.getTenant()); + Member member = task.member; + + String event = getNotifyEvent(task); + if (memberManager.hasMember(member.getAddress())) { + // start the health check and there are ips that are not monitored, put them directly in the notification queue, otherwise notify + boolean unHealthNeedDelay = isUnHealthy(member.getAddress()); + if (unHealthNeedDelay) { + // target ip is unhealthy, then put it in the notification list + ConfigTraceService.logNotifyEvent(task.getDataId(), task.getGroup(), task.getTenant(), null, + task.getLastModified(), InetUtils.getSelfIP(), event, + ConfigTraceService.NOTIFY_TYPE_UNHEALTH, 0, member.getAddress()); + // get delay time and set fail count to the task + asyncTaskExecute(task); + } else { + + // grpc report data change only + try { + configClusterRpcClientProxy.syncConfigChange(member, syncRequest, + new AsyncRpcNotifyCallBack(AsyncNotifyService.this, task)); + } catch (Exception e) { + MetricsMonitor.getConfigNotifyException().increment(); + asyncTaskExecute(task); + } + + } + } else { + //No nothing if member has offline. + } + + } + } + + public class AsyncRpcTask implements Runnable { private Queue queue; @@ -136,62 +182,22 @@ public AsyncRpcTask(Queue queue) { @Override public void run() { - while (!queue.isEmpty()) { - NotifySingleRpcTask task = queue.poll(); - - ConfigChangeClusterSyncRequest syncRequest = new ConfigChangeClusterSyncRequest(); - syncRequest.setDataId(task.getDataId()); - syncRequest.setGroup(task.getGroup()); - syncRequest.setBeta(task.isBeta); - syncRequest.setLastModified(task.getLastModified()); - syncRequest.setTag(task.tag); - syncRequest.setBatch(task.isBatch); - syncRequest.setTenant(task.getTenant()); - Member member = task.member; - - String event = getNotifyEvent(task); - if (memberManager.hasMember(member.getAddress())) { - // start the health check and there are ips that are not monitored, put them directly in the notification queue, otherwise notify - boolean unHealthNeedDelay = isUnHealthy(member.getAddress()); - if (unHealthNeedDelay) { - // target ip is unhealthy, then put it in the notification list - ConfigTraceService.logNotifyEvent(task.getDataId(), task.getGroup(), task.getTenant(), null, - task.getLastModified(), InetUtils.getSelfIP(), event, - ConfigTraceService.NOTIFY_TYPE_UNHEALTH, 0, member.getAddress()); - // get delay time and set fail count to the task - asyncTaskExecute(task); - } else { - - // grpc report data change only - try { - configClusterRpcClientProxy.syncConfigChange(member, syncRequest, - new AsyncRpcNotifyCallBack(task)); - } catch (Exception e) { - MetricsMonitor.getConfigNotifyException().increment(); - asyncTaskExecute(task); - } - - } - } else { - //No nothing if member has offline. - } - - } + executeAsyncRpcTask(queue); } } - static class NotifySingleRpcTask extends AbstractDelayTask { - + public static class NotifySingleRpcTask extends AbstractDelayTask { + private String dataId; - + private String group; - + private String tenant; - + private long lastModified; - + private int failCount; - + private Member member; private boolean isBeta; @@ -200,14 +206,6 @@ static class NotifySingleRpcTask extends AbstractDelayTask { private boolean isBatch; - public NotifySingleRpcTask(String dataId, String group, String tenant, String tag, long lastModified, - boolean isBeta, Member member) { - this(dataId, group, tenant, lastModified); - this.member = member; - this.isBeta = isBeta; - this.tag = tag; - } - public NotifySingleRpcTask(String dataId, String group, String tenant, String tag, long lastModified, boolean isBeta, boolean isBatch, Member member) { this(dataId, group, tenant, lastModified); @@ -216,15 +214,15 @@ public NotifySingleRpcTask(String dataId, String group, String tenant, String ta this.tag = tag; this.isBatch = isBatch; } - + private NotifySingleRpcTask(String dataId, String group, String tenant, long lastModified) { this.dataId = dataId; this.group = group; - this.setTenant(tenant); + this.tenant = tenant; this.lastModified = lastModified; setTaskInterval(3000L); } - + public boolean isBeta() { return isBeta; } @@ -252,48 +250,33 @@ public void setBatch(boolean batch) { public String getDataId() { return dataId; } - - public void setDataId(String dataId) { - this.dataId = dataId; - } - + public String getGroup() { return group; } - - public void setGroup(String group) { - this.group = group; - } - + public int getFailCount() { return failCount; } - + public void setFailCount(int failCount) { this.failCount = failCount; } - + public long getLastModified() { return lastModified; } - - public void setLastModified(long lastModified) { - this.lastModified = lastModified; - } - + @Override public void merge(AbstractDelayTask task) { // Perform merge, but do nothing, tasks with the same dataId and group, later will replace the previous - + } - + public String getTenant() { return tenant; } - - public void setTenant(String tenant) { - this.tenant = tenant; - } + } private void asyncTaskExecute(NotifySingleRpcTask task) { @@ -304,24 +287,27 @@ private void asyncTaskExecute(NotifySingleRpcTask task) { ConfigExecutor.scheduleAsyncNotify(asyncTask, delay, TimeUnit.MILLISECONDS); } - private String getNotifyEvent(NotifySingleRpcTask task) { + private static String getNotifyEvent(NotifySingleRpcTask task) { String event = ConfigTraceService.NOTIFY_EVENT; - if (task.isBeta) { + if (task.isBeta()) { event = ConfigTraceService.NOTIFY_EVENT_BETA; } else if (!StringUtils.isBlank(task.tag)) { event = ConfigTraceService.NOTIFY_EVENT_TAG + "-" + task.tag; - } else if (task.isBatch) { + } else if (task.isBatch()) { event = ConfigTraceService.NOTIFY_EVENT_BATCH; } return event; } - class AsyncRpcNotifyCallBack implements RequestCallBack { + public static class AsyncRpcNotifyCallBack implements RequestCallBack { private NotifySingleRpcTask task; - public AsyncRpcNotifyCallBack(NotifySingleRpcTask task) { + AsyncNotifyService asyncNotifyService; + + public AsyncRpcNotifyCallBack(AsyncNotifyService asyncNotifyService, NotifySingleRpcTask task) { this.task = task; + this.asyncNotifyService = asyncNotifyService; } @Override @@ -351,7 +337,7 @@ public void onResponse(ConfigChangeClusterSyncResponse response) { delayed, task.member.getAddress()); //get delay time and set fail count to the task - asyncTaskExecute(task); + asyncNotifyService.asyncTaskExecute(task); LogUtil.NOTIFY_LOG.error("[notify-retry] target:{} dataId:{} group:{} ts:{}", task.member.getAddress(), task.getDataId(), task.getGroup(), task.getLastModified()); @@ -372,7 +358,7 @@ public void onException(Throwable ex) { delayed, task.member.getAddress()); //get delay time and set fail count to the task - asyncTaskExecute(task); + asyncNotifyService.asyncTaskExecute(task); LogUtil.NOTIFY_LOG.error("[notify-retry] target:{} dataId:{} group:{} ts:{}", task.member.getAddress(), task.getDataId(), task.getGroup(), task.getLastModified()); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigInfoAggrPersistService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigInfoAggrPersistService.java index fcef7f2857e..6a1df0859ea 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigInfoAggrPersistService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigInfoAggrPersistService.java @@ -18,7 +18,6 @@ import com.alibaba.nacos.config.server.model.ConfigInfoAggr; import com.alibaba.nacos.config.server.model.ConfigInfoChanged; -import com.alibaba.nacos.config.server.model.ConfigKey; import com.alibaba.nacos.persistence.model.Page; import com.alibaba.nacos.persistence.repository.PaginationHelper; @@ -44,14 +43,6 @@ public interface ConfigInfoAggrPersistService { */ PaginationHelper createPaginationHelper(); - /** - * Generate fuzzy search Sql. - * - * @param s origin string - * @return fuzzy search Sql - */ - String generateLikeArgument(String s); - //------------------------------------------insert---------------------------------------------// /** @@ -82,53 +73,6 @@ boolean addAggrConfigInfo(final String dataId, final String group, String tenant boolean batchPublishAggr(final String dataId, final String group, final String tenant, final Map datumMap, final String appName); - /** - * Batch replacement, first delete all the specified DataID+Group data in the aggregation table, and then insert the - * data. Any exception during the transaction process will force a TransactionSystemException to be thrown. - * - * @param dataId dataId - * @param group group - * @param tenant tenant - * @param appName app name - * @param datumMap datumMap - * @return {@code true} if replace success - */ - boolean replaceAggr(final String dataId, final String group, final String tenant, - final Map datumMap, final String appName); - - //------------------------------------------delete---------------------------------------------// - - /** - * Delete a single piece of data before aggregation. - * - * @param dataId data id - * @param group group - * @param tenant tenant - * @param datumId datum id - */ - void removeSingleAggrConfigInfo(final String dataId, final String group, final String tenant, final String datumId); - - /** - * Delete all pre-aggregation data under a dataId. - * - * @param dataId data id - * @param group group - * @param tenant tenant - */ - void removeAggrConfigInfo(final String dataId, final String group, final String tenant); - - /** - * To delete aggregated data in bulk, you need to specify a list of datum. - * - * @param dataId dataId - * @param group group - * @param tenant tenant - * @param datumList datumList - * @return {@code true} if remove success - */ - boolean batchRemoveAggr(final String dataId, final String group, final String tenant, final List datumList); - - //------------------------------------------update---------------------------------------------// //------------------------------------------select---------------------------------------------// @@ -142,39 +86,6 @@ boolean replaceAggr(final String dataId, final String group, final String tenant */ int aggrConfigInfoCount(String dataId, String group, String tenant); - /** - * Get count of aggregation config info. - * - * @param dataId data id - * @param group group - * @param tenant tenant - * @param datumIds datum id list - * @param isIn search condition - * @return count - */ - int aggrConfigInfoCount(String dataId, String group, String tenant, List datumIds, boolean isIn); - - /** - * Find a single piece of data before aggregation. - * - * @param dataId data id - * @param group group - * @param tenant tenant - * @param datumId datum id - * @return {@link ConfigInfoAggr} - */ - ConfigInfoAggr findSingleConfigInfoAggr(String dataId, String group, String tenant, String datumId); - - /** - * Find all data before aggregation under a dataId. It is guaranteed not to return NULL. - * - * @param dataId data id - * @param group group - * @param tenant tenant - * @return {@link ConfigInfoAggr} list - */ - List findConfigInfoAggr(String dataId, String group, String tenant); - /** * Query aggregation config info. * @@ -188,32 +99,11 @@ boolean replaceAggr(final String dataId, final String group, final String tenant Page findConfigInfoAggrByPage(String dataId, String group, String tenant, final int pageNo, final int pageSize); - /** - * Query eligible aggregated data. - * - * @param pageNo pageNo - * @param pageSize pageSize - * @param configKeys aggregate data conditions - * @param blacklist blacklist - * @return {@link Page} with {@link ConfigInfoAggr} generation - */ - Page findConfigInfoAggrLike(final int pageNo, final int pageSize, ConfigKey[] configKeys, - boolean blacklist); - /** * Find all aggregated data sets. * * @return {@link ConfigInfoChanged} list */ List findAllAggrGroup(); - - /** - * Find datumId by datum content. - * - * @param dataId data id - * @param groupId group - * @param content content - * @return datum keys - */ - List findDatumIdByContent(String dataId, String groupId, String content); + } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigInfoPersistService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigInfoPersistService.java index aa760709d6a..f62b22afc85 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigInfoPersistService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigInfoPersistService.java @@ -23,13 +23,11 @@ import com.alibaba.nacos.config.server.model.ConfigInfoBase; import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; import com.alibaba.nacos.config.server.model.ConfigInfoWrapper; -import com.alibaba.nacos.config.server.model.ConfigKey; import com.alibaba.nacos.config.server.model.ConfigOperateResult; -import com.alibaba.nacos.persistence.model.Page; import com.alibaba.nacos.config.server.model.SameConfigPolicy; +import com.alibaba.nacos.persistence.model.Page; import com.alibaba.nacos.persistence.repository.PaginationHelper; -import java.io.IOException; import java.sql.Timestamp; import java.util.List; import java.util.Map; @@ -239,17 +237,6 @@ ConfigOperateResult updateConfigInfoCas(final ConfigInfo configInfo, final Strin void updateConfigInfoAtomic(final ConfigInfo configInfo, final String srcIp, final String srcUser, Map configAdvanceInfo); - /** - * update md5. - * - * @param dataId data id - * @param group group - * @param tenant tenant - * @param md5 md5 - * @param lastTime last modified time - */ - void updateMd5(String dataId, String group, String tenant, String md5, Timestamp lastTime); - //------------------------------------------select---------------------------------------------// /** @@ -258,24 +245,7 @@ void updateConfigInfoAtomic(final ConfigInfo configInfo, final String srcIp, fin * @return config max id */ long findConfigMaxId(); - - /** - * Find all dataId and group. It is guaranteed not to return NULL. - * - * @return {@link com.alibaba.nacos.config.server.Config} list - */ - @Deprecated - List findAllDataIdAndGroup(); - - /** - * Query configuration information based on dataId and group. - * - * @param dataId data id - * @param group group - * @return {@link ConfigInfoBase} - */ - ConfigInfoBase findConfigInfoBase(final String dataId, final String group); - + /** * Query configuration information by primary key ID. * @@ -308,27 +278,6 @@ void updateConfigInfoAtomic(final ConfigInfo configInfo, final String srcIp, fin Page findConfigInfo4Page(final int pageNo, final int pageSize, final String dataId, final String group, final String tenant, final Map configAdvanceInfo); - /** - * Query configuration information based on group. - * - * @param pageNo Page number (must be greater than 0) - * @param pageSize Page size (must be greater than 0) - * @param tenant tenant - * @param appName app name - * @return {@link Page} with {@link ConfigInfo} generation - */ - Page findConfigInfoByApp(final int pageNo, final int pageSize, final String tenant, - final String appName); - - /** - * Query configuration information based on group. - * - * @param pageNo Page number (must be greater than 0) - * @param pageSize Page size (must be greater than 0) - * @param group group - * @return {@link Page} with {@link ConfigInfoBase} generation - */ - Page findConfigInfoBaseByGroup(final int pageNo, final int pageSize, final String group); /** * Returns the number of configuration items. @@ -363,26 +312,6 @@ Page findConfigInfoByApp(final int pageNo, final int pageSize, final */ List getGroupIdList(int page, int pageSize); - /** - * Query all configuration information by page. - * - * @param pageNo Page number (starting at 1) - * @param pageSize Page size (must be greater than 0) - * @param tenant tenant - * @return {@link Page} with {@link ConfigInfo} generation - */ - Page findAllConfigInfo(final int pageNo, final int pageSize, final String tenant); - - /** - * Query all configuration information by page. - * - * @param pageNo Page number (starting at 1) - * @param pageSize Page size (must be greater than 0) - * @param tenant tenant - * @return {@link Page} with {@link ConfigKey} generation - */ - Page findAllConfigKey(final int pageNo, final int pageSize, final String tenant); - /** * Query all config info. * @@ -392,18 +321,6 @@ Page findConfigInfoByApp(final int pageNo, final int pageSize, final */ Page findAllConfigInfoFragment(final long lastMaxId, final int pageSize); - /** - * Fuzzy query configuration information based on dataId and group. - * - * @param pageNo Page number (must be greater than 0) - * @param pageSize Page size (must be greater than 0) - * @param configKeys Query configuration list - * @param blacklist Whether to blacklist - * @return {@link Page} with {@link ConfigInfo} generation - */ - Page findConfigInfoLike(final int pageNo, final int pageSize, final ConfigKey[] configKeys, - final boolean blacklist); - /** * Query config info. * @@ -417,21 +334,7 @@ Page findConfigInfoLike(final int pageNo, final int pageSize, final */ Page findConfigInfoLike4Page(final int pageNo, final int pageSize, final String dataId, final String group, final String tenant, final Map configAdvanceInfo); - - /** - * Fuzzy query configuration information based on dataId and group. - * - * @param pageNo Page number (must be greater than 0) - * @param pageSize Page size (must be greater than 0) - * @param dataId data id - * @param group group - * @param content config content - * @return {@link Page} with {@link ConfigInfoBase} generation - * @throws IOException exception - */ - Page findConfigInfoBaseLike(final int pageNo, final int pageSize, final String dataId, - final String group, final String content) throws IOException; - + /** * Query change config.order by id asc. * @@ -442,24 +345,6 @@ Page findConfigInfoBaseLike(final int pageNo, final int pageSize */ List findChangeConfig(final Timestamp startTime, long lastMaxId, final int pageSize); - /** - * According to the time period and configuration conditions to query the eligible configuration. - * - * @param dataId dataId Support Fuzzy query - * @param group dataId Support Fuzzy query - * @param tenant tenant - * @param appName app name - * @param startTime start time - * @param endTime end time - * @param pageNo pageNo - * @param pageSize pageSize - * @param lastMaxId last max id - * @return {@link Page} with {@link ConfigInfoWrapper} generation - */ - Page findChangeConfig(final String dataId, final String group, final String tenant, - final String appName, final Timestamp startTime, final Timestamp endTime, final int pageNo, - final int pageSize, final long lastMaxId); - /** * Query tag list. * @@ -500,49 +385,6 @@ Page findChangeConfig(final String dataId, final String group */ ConfigAllInfo findConfigAllInfo(final String dataId, final String group, final String tenant); - /** - * Convert delete config. - * - * @param list origin data - * @return {@link ConfigInfo} list - */ - List convertDeletedConfig(List> list); - - /** - * Convert change config. - * - * @param list origin data - * @return {@link ConfigInfoWrapper} list - */ - List convertChangeConfig(List> list); - - - /** - * Get the Md5 value of all configurations, through the paging method. - * - * @return {@link ConfigInfoWrapper} list - */ - List listAllGroupKeyMd5(); - - /** - * list group key md5 by page. - * - * @param pageNo page no - * @param pageSize page size - * @return {@link ConfigInfoWrapper} list - */ - List listGroupKeyMd5ByPage(int pageNo, int pageSize); - - /** - * Query config info. - * - * @param dataId data id - * @param group group - * @param tenant tenant - * @return {@link ConfigInfoWrapper} - */ - ConfigInfoWrapper queryConfigInfo(final String dataId, final String group, final String tenant); - /** * get config info state. * @@ -574,14 +416,4 @@ List findAllConfigInfo4Export(final String dataId, final String g */ List queryConfigInfoByNamespace(final String tenantId); - /** - * Query all configuration information by page. - * - * @param pageNo Page number (starting at 1) - * @param pageSize Page size (must be greater than 0) - * @return {@link Page} with {@link ConfigInfoBase} generation - */ - @Deprecated - Page findAllConfigInfoBase(final int pageNo, final int pageSize); - } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigRowMapperInjector.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigRowMapperInjector.java index 9907e9bb155..bbe15c8b9a8 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigRowMapperInjector.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigRowMapperInjector.java @@ -74,25 +74,25 @@ public class ConfigRowMapperInjector { public static final ConfigHistoryRowMapper HISTORY_LIST_ROW_MAPPER = new ConfigHistoryRowMapper(); public static final ConfigHistoryDetailRowMapper HISTORY_DETAIL_ROW_MAPPER = new ConfigHistoryDetailRowMapper(); - + static { injectConfigRowMapper(); } public ConfigRowMapperInjector() { } - + private static void injectConfigRowMapper() { // CONFIG_INFO_WRAPPER_ROW_MAPPER - RowMapperManager - .registerRowMapper(ConfigRowMapperInjector.CONFIG_INFO_WRAPPER_ROW_MAPPER.getClass().getCanonicalName(), - ConfigRowMapperInjector.CONFIG_INFO_WRAPPER_ROW_MAPPER); - + RowMapperManager.registerRowMapper( + ConfigRowMapperInjector.CONFIG_INFO_WRAPPER_ROW_MAPPER.getClass().getCanonicalName(), + ConfigRowMapperInjector.CONFIG_INFO_WRAPPER_ROW_MAPPER); + // CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER - RowMapperManager - .registerRowMapper(ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER.getClass().getCanonicalName(), - ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER); + RowMapperManager.registerRowMapper( + ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER.getClass().getCanonicalName(), + ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER); // CONFIG_KEY_ROW_MAPPER @@ -118,57 +118,57 @@ private static void injectConfigRowMapper() { // CONFIG_ADVANCE_INFO_ROW_MAPPER - RowMapperManager - .registerRowMapper(ConfigRowMapperInjector.CONFIG_ADVANCE_INFO_ROW_MAPPER.getClass().getCanonicalName(), - ConfigRowMapperInjector.CONFIG_ADVANCE_INFO_ROW_MAPPER); + RowMapperManager.registerRowMapper( + ConfigRowMapperInjector.CONFIG_ADVANCE_INFO_ROW_MAPPER.getClass().getCanonicalName(), + ConfigRowMapperInjector.CONFIG_ADVANCE_INFO_ROW_MAPPER); // CONFIG_ALL_INFO_ROW_MAPPER - RowMapperManager - .registerRowMapper(ConfigRowMapperInjector.CONFIG_ALL_INFO_ROW_MAPPER.getClass().getCanonicalName(), - ConfigRowMapperInjector.CONFIG_ALL_INFO_ROW_MAPPER); + RowMapperManager.registerRowMapper( + ConfigRowMapperInjector.CONFIG_ALL_INFO_ROW_MAPPER.getClass().getCanonicalName(), + ConfigRowMapperInjector.CONFIG_ALL_INFO_ROW_MAPPER); // CONFIG_INFO4BETA_ROW_MAPPER - RowMapperManager - .registerRowMapper(ConfigRowMapperInjector.CONFIG_INFO4BETA_ROW_MAPPER.getClass().getCanonicalName(), - ConfigRowMapperInjector.CONFIG_INFO4BETA_ROW_MAPPER); + RowMapperManager.registerRowMapper( + ConfigRowMapperInjector.CONFIG_INFO4BETA_ROW_MAPPER.getClass().getCanonicalName(), + ConfigRowMapperInjector.CONFIG_INFO4BETA_ROW_MAPPER); // CONFIG_INFO4TAG_ROW_MAPPER - RowMapperManager - .registerRowMapper(ConfigRowMapperInjector.CONFIG_INFO4TAG_ROW_MAPPER.getClass().getCanonicalName(), - ConfigRowMapperInjector.CONFIG_INFO4TAG_ROW_MAPPER); + RowMapperManager.registerRowMapper( + ConfigRowMapperInjector.CONFIG_INFO4TAG_ROW_MAPPER.getClass().getCanonicalName(), + ConfigRowMapperInjector.CONFIG_INFO4TAG_ROW_MAPPER); // CONFIG_INFO_BASE_ROW_MAPPER - RowMapperManager - .registerRowMapper(ConfigRowMapperInjector.CONFIG_INFO_BASE_ROW_MAPPER.getClass().getCanonicalName(), - ConfigRowMapperInjector.CONFIG_INFO_BASE_ROW_MAPPER); + RowMapperManager.registerRowMapper( + ConfigRowMapperInjector.CONFIG_INFO_BASE_ROW_MAPPER.getClass().getCanonicalName(), + ConfigRowMapperInjector.CONFIG_INFO_BASE_ROW_MAPPER); // CONFIG_INFO_AGGR_ROW_MAPPER - RowMapperManager - .registerRowMapper(ConfigRowMapperInjector.CONFIG_INFO_AGGR_ROW_MAPPER.getClass().getCanonicalName(), - ConfigRowMapperInjector.CONFIG_INFO_AGGR_ROW_MAPPER); + RowMapperManager.registerRowMapper( + ConfigRowMapperInjector.CONFIG_INFO_AGGR_ROW_MAPPER.getClass().getCanonicalName(), + ConfigRowMapperInjector.CONFIG_INFO_AGGR_ROW_MAPPER); // CONFIG_INFO_CHANGED_ROW_MAPPER - RowMapperManager - .registerRowMapper(ConfigRowMapperInjector.CONFIG_INFO_CHANGED_ROW_MAPPER.getClass().getCanonicalName(), - ConfigRowMapperInjector.CONFIG_INFO_CHANGED_ROW_MAPPER); + RowMapperManager.registerRowMapper( + ConfigRowMapperInjector.CONFIG_INFO_CHANGED_ROW_MAPPER.getClass().getCanonicalName(), + ConfigRowMapperInjector.CONFIG_INFO_CHANGED_ROW_MAPPER); // HISTORY_LIST_ROW_MAPPER - RowMapperManager - .registerRowMapper(ConfigRowMapperInjector.HISTORY_LIST_ROW_MAPPER.getClass().getCanonicalName(), - ConfigRowMapperInjector.HISTORY_LIST_ROW_MAPPER); + RowMapperManager.registerRowMapper( + ConfigRowMapperInjector.HISTORY_LIST_ROW_MAPPER.getClass().getCanonicalName(), + ConfigRowMapperInjector.HISTORY_LIST_ROW_MAPPER); // HISTORY_DETAIL_ROW_MAPPER - RowMapperManager - .registerRowMapper(ConfigRowMapperInjector.HISTORY_DETAIL_ROW_MAPPER.getClass().getCanonicalName(), - ConfigRowMapperInjector.HISTORY_DETAIL_ROW_MAPPER); + RowMapperManager.registerRowMapper( + ConfigRowMapperInjector.HISTORY_DETAIL_ROW_MAPPER.getClass().getCanonicalName(), + ConfigRowMapperInjector.HISTORY_DETAIL_ROW_MAPPER); } public static final class ConfigInfoWrapperRowMapper implements RowMapper { @@ -181,7 +181,11 @@ public ConfigInfoWrapper mapRow(ResultSet rs, int rowNum) throws SQLException { info.setGroup(rs.getString("group_id")); info.setTenant(rs.getString("tenant_id")); info.setAppName(rs.getString("app_name")); - info.setType(rs.getString("type")); + + try { + info.setType(rs.getString("type")); + } catch (SQLException ignore) { + } try { info.setContent(rs.getString("content")); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoAggrPersistServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoAggrPersistServiceImpl.java index 2cc5389f7ae..dab8c013af8 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoAggrPersistServiceImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoAggrPersistServiceImpl.java @@ -18,20 +18,19 @@ import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.common.utils.StringUtils; -import com.alibaba.nacos.persistence.configuration.condition.ConditionOnEmbeddedStorage; import com.alibaba.nacos.config.server.exception.NacosConfigException; import com.alibaba.nacos.config.server.model.ConfigInfoAggr; import com.alibaba.nacos.config.server.model.ConfigInfoChanged; -import com.alibaba.nacos.config.server.model.ConfigKey; -import com.alibaba.nacos.persistence.model.Page; -import com.alibaba.nacos.persistence.model.event.DerbyImportEvent; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoAggrPersistService; +import com.alibaba.nacos.persistence.configuration.condition.ConditionOnEmbeddedStorage; import com.alibaba.nacos.persistence.datasource.DataSourceService; import com.alibaba.nacos.persistence.datasource.DynamicDataSource; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoAggrPersistService; +import com.alibaba.nacos.persistence.model.Page; +import com.alibaba.nacos.persistence.model.event.DerbyImportEvent; import com.alibaba.nacos.persistence.repository.PaginationHelper; import com.alibaba.nacos.persistence.repository.embedded.EmbeddedPaginationHelperImpl; -import com.alibaba.nacos.persistence.repository.embedded.operate.DatabaseOperate; import com.alibaba.nacos.persistence.repository.embedded.EmbeddedStorageContextHolder; +import com.alibaba.nacos.persistence.repository.embedded.operate.DatabaseOperate; import com.alibaba.nacos.plugin.datasource.MapperManager; import com.alibaba.nacos.plugin.datasource.constants.CommonConstant; import com.alibaba.nacos.plugin.datasource.constants.FieldConstant; @@ -44,7 +43,6 @@ import org.springframework.stereotype.Service; import java.sql.Timestamp; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -89,17 +87,6 @@ public PaginationHelper createPaginationHelper() { return new EmbeddedPaginationHelperImpl<>(databaseOperate); } - @Override - public String generateLikeArgument(String s) { - String fuzzySearchSign = "\\*"; - String sqlLikePercentSign = "%"; - if (s.contains(PATTERN_STR)) { - return s.replaceAll(fuzzySearchSign, sqlLikePercentSign); - } else { - return s; - } - } - @Override public boolean addAggrConfigInfo(final String dataId, final String group, String tenant, final String datumId, String appName, final String content) { @@ -159,108 +146,6 @@ public boolean batchPublishAggr(final String dataId, final String group, final S } } - @Override - public boolean replaceAggr(final String dataId, final String group, final String tenant, - final Map datumMap, final String appName) { - Boolean isReplaceOk = false; - String appNameTmp = appName == null ? "" : appName; - - removeAggrConfigInfo(dataId, group, tenant); - - String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - ConfigInfoAggrMapper configInfoAggrMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO_AGGR); - final String sql = configInfoAggrMapper.insert( - Arrays.asList("data_id", "group_id", "tenant_id", "datum_id", "app_name", "content", "gmt_modified")); - for (Map.Entry datumEntry : datumMap.entrySet()) { - final Object[] args = new Object[] {dataId, group, tenantTmp, datumEntry.getKey(), appNameTmp, - datumEntry.getValue(), new Timestamp(System.currentTimeMillis())}; - EmbeddedStorageContextHolder.addSqlContext(sql, args); - } - try { - isReplaceOk = databaseOperate.update(EmbeddedStorageContextHolder.getCurrentSqlContext()); - - if (isReplaceOk == null) { - return false; - } - return isReplaceOk; - } finally { - EmbeddedStorageContextHolder.cleanAllContext(); - } - - } - - @Override - public void removeSingleAggrConfigInfo(final String dataId, final String group, final String tenant, - final String datumId) { - final String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - - ConfigInfoAggrMapper configInfoAggrMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO_AGGR); - final String sql = configInfoAggrMapper.delete(Arrays.asList("data_id", "group_id", "tenant_id", "datum_id")); - final Object[] args = new Object[] {dataId, group, tenantTmp, datumId}; - EmbeddedStorageContextHolder.addSqlContext(sql, args); - - try { - boolean result = databaseOperate.update(EmbeddedStorageContextHolder.getCurrentSqlContext()); - if (!result) { - throw new NacosConfigException("[aggregation with single] Configuration deletion failed"); - } - } finally { - EmbeddedStorageContextHolder.cleanAllContext(); - } - } - - @Override - public void removeAggrConfigInfo(final String dataId, final String group, final String tenant) { - final String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - - ConfigInfoAggrMapper configInfoAggrMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO_AGGR); - final String sql = configInfoAggrMapper.delete(Arrays.asList("data_id", "group_id", "tenant_id")); - final Object[] args = new Object[] {dataId, group, tenantTmp}; - EmbeddedStorageContextHolder.addSqlContext(sql, args); - - try { - boolean result = databaseOperate.update(EmbeddedStorageContextHolder.getCurrentSqlContext()); - if (!result) { - throw new NacosConfigException("[aggregation with all] Configuration deletion failed"); - } - } finally { - EmbeddedStorageContextHolder.cleanAllContext(); - } - } - - @Override - public boolean batchRemoveAggr(final String dataId, final String group, final String tenant, - final List datumList) { - final String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - ConfigInfoAggrMapper configInfoAggrMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO_AGGR); - - MapperContext context = new MapperContext(); - context.putWhereParameter(FieldConstant.DATUM_ID, datumList); - context.putWhereParameter(FieldConstant.DATA_ID, dataId); - context.putWhereParameter(FieldConstant.GROUP_ID, group); - context.putWhereParameter(FieldConstant.TENANT_ID, tenantTmp); - - MapperResult mapperResult = configInfoAggrMapper.batchRemoveAggr(context); - - final String sql = mapperResult.getSql(); - final Object[] args = mapperResult.getParamList().toArray(); - EmbeddedStorageContextHolder.addSqlContext(sql, args); - - try { - boolean result = databaseOperate.update(EmbeddedStorageContextHolder.getCurrentSqlContext()); - if (!result) { - throw new NacosConfigException("[aggregation] Failed to configure batch deletion"); - } - return true; - } finally { - EmbeddedStorageContextHolder.cleanAllContext(); - } - } - @Override public int aggrConfigInfoCount(String dataId, String group, String tenant) { String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; @@ -274,67 +159,6 @@ public int aggrConfigInfoCount(String dataId, String group, String tenant) { return result; } - @Override - public int aggrConfigInfoCount(String dataId, String group, String tenant, List datumIds, boolean isIn) { - if (datumIds == null || datumIds.isEmpty()) { - return 0; - } - final String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - ConfigInfoAggrMapper configInfoAggrMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO_AGGR); - - MapperContext context = new MapperContext(); - context.putWhereParameter(FieldConstant.DATUM_ID, datumIds); - context.putWhereParameter(FieldConstant.IS_IN, true); - context.putWhereParameter(FieldConstant.DATA_ID, dataId); - context.putWhereParameter(FieldConstant.GROUP_ID, group); - context.putWhereParameter(FieldConstant.TENANT_ID, tenantTmp); - - MapperResult mapperResult = configInfoAggrMapper.aggrConfigInfoCount(context); - - String sql = mapperResult.getSql(); - Object[] args = mapperResult.getParamList().toArray(); - - Integer result = databaseOperate.queryOne(sql, args, Integer.class); - if (result == null) { - throw new IllegalArgumentException("aggrConfigInfoCount error"); - } - return result; - } - - @Override - public ConfigInfoAggr findSingleConfigInfoAggr(String dataId, String group, String tenant, String datumId) { - String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - ConfigInfoAggrMapper configInfoAggrMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO_AGGR); - String sql = configInfoAggrMapper.select( - Arrays.asList("id", "data_id", "group_id", "tenant_id", "datum_id", "app_name", "content"), - Arrays.asList("data_id", "group_id", "tenant_id", "datum_id")); - - return databaseOperate.queryOne(sql, new Object[] {dataId, group, tenantTmp, datumId}, - CONFIG_INFO_AGGR_ROW_MAPPER); - - } - - @Override - public List findConfigInfoAggr(String dataId, String group, String tenant) { - String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - ConfigInfoAggrMapper configInfoAggrMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO_AGGR); - - MapperContext context = new MapperContext(); - context.putWhereParameter(FieldConstant.DATA_ID, dataId); - context.putWhereParameter(FieldConstant.GROUP_ID, group); - context.putWhereParameter(FieldConstant.TENANT_ID, tenantTmp); - - MapperResult mapperResult = configInfoAggrMapper.findConfigInfoAggrIsOrdered(context); - String sql = mapperResult.getSql(); - Object[] args = mapperResult.getParamList().toArray(); - - return databaseOperate.queryMany(sql, args, CONFIG_INFO_AGGR_ROW_MAPPER); - - } - @Override public Page findConfigInfoAggrByPage(String dataId, String group, String tenant, final int pageNo, final int pageSize) { @@ -359,101 +183,7 @@ public Page findConfigInfoAggrByPage(String dataId, String group return helper.fetchPageLimit(sqlCountRows, new Object[] {dataId, group, tenantTmp}, sqlFetchRows, sqlFetchArgs, pageNo, pageSize, CONFIG_INFO_AGGR_ROW_MAPPER); } - - @Override - public Page findConfigInfoAggrLike(final int pageNo, final int pageSize, ConfigKey[] configKeys, - boolean blacklist) { - - String sqlCountRows = "SELECT count(*) FROM config_info_aggr WHERE "; - String sqlFetchRows = "SELECT data_id,group_id,tenant_id,datum_id,app_name,content FROM config_info_aggr WHERE "; - StringBuilder where = new StringBuilder(" 1=1 "); - // White list, please synchronize the condition is empty, there is no qualified configuration - if (configKeys.length == 0 && blacklist == false) { - Page page = new Page<>(); - page.setTotalCount(0); - return page; - } - List params = new ArrayList<>(); - boolean isFirst = true; - - for (ConfigKey configInfoAggr : configKeys) { - String dataId = configInfoAggr.getDataId(); - String group = configInfoAggr.getGroup(); - String appName = configInfoAggr.getAppName(); - if (StringUtils.isBlank(dataId) && StringUtils.isBlank(group) && StringUtils.isBlank(appName)) { - break; - } - if (blacklist) { - if (isFirst) { - isFirst = false; - where.append(" AND "); - } else { - where.append(" AND "); - } - - where.append('('); - boolean isFirstSub = true; - if (!StringUtils.isBlank(dataId)) { - where.append(" data_id NOT LIKE ? "); - params.add(generateLikeArgument(dataId)); - isFirstSub = false; - } - if (!StringUtils.isBlank(group)) { - if (!isFirstSub) { - where.append(" OR "); - } - where.append(" group_id NOT LIKE ? "); - params.add(generateLikeArgument(group)); - isFirstSub = false; - } - if (!StringUtils.isBlank(appName)) { - if (!isFirstSub) { - where.append(" OR "); - } - where.append(" app_name != ? "); - params.add(appName); - isFirstSub = false; - } - where.append(") "); - } else { - if (isFirst) { - isFirst = false; - where.append(" AND "); - } else { - where.append(" OR "); - } - where.append('('); - boolean isFirstSub = true; - if (!StringUtils.isBlank(dataId)) { - where.append(" data_id LIKE ? "); - params.add(generateLikeArgument(dataId)); - isFirstSub = false; - } - if (!StringUtils.isBlank(group)) { - if (!isFirstSub) { - where.append(" AND "); - } - where.append(" group_id LIKE ? "); - params.add(generateLikeArgument(group)); - isFirstSub = false; - } - if (!StringUtils.isBlank(appName)) { - if (!isFirstSub) { - where.append(" AND "); - } - where.append(" app_name = ? "); - params.add(appName); - isFirstSub = false; - } - where.append(") "); - } - } - PaginationHelper helper = createPaginationHelper(); - return helper.fetchPage(sqlCountRows + where.toString(), sqlFetchRows + where.toString(), params.toArray(), - pageNo, pageSize, CONFIG_INFO_AGGR_ROW_MAPPER); - - } - + @Override public List findAllAggrGroup() { ConfigInfoAggrMapper configInfoAggrMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), @@ -463,14 +193,5 @@ public List findAllAggrGroup() { return databaseOperate.queryMany(mapperResult.getSql(), EMPTY_ARRAY, CONFIG_INFO_CHANGED_ROW_MAPPER); } - - @Override - public List findDatumIdByContent(String dataId, String groupId, String content) { - ConfigInfoAggrMapper configInfoAggrMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO_AGGR); - String sql = configInfoAggrMapper.select(Collections.singletonList("datum_id"), - Arrays.asList("data_id", "group_id", "content")); - return databaseOperate.queryMany(sql, new Object[] {dataId, groupId, content}, String.class); - - } + } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoBetaPersistServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoBetaPersistServiceImpl.java index 72f86c8948c..584df79257c 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoBetaPersistServiceImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoBetaPersistServiceImpl.java @@ -147,17 +147,17 @@ public ConfigOperateResult addConfigInfo4Beta(ConfigInfo configInfo, String beta @Override public ConfigOperateResult insertOrUpdateBeta(final ConfigInfo configInfo, final String betaIps, final String srcIp, final String srcUser) { - if (findConfigInfo4Beta(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()) == null) { - return addConfigInfo4Beta(configInfo, betaIps, srcIp, null); + if (findConfigInfo4BetaState(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()) == null) { + return addConfigInfo4Beta(configInfo, betaIps, srcIp, srcUser); } else { - return updateConfigInfo4Beta(configInfo, betaIps, srcIp, null); + return updateConfigInfo4Beta(configInfo, betaIps, srcIp, srcUser); } } @Override public ConfigOperateResult insertOrUpdateBetaCas(final ConfigInfo configInfo, final String betaIps, final String srcIp, final String srcUser) { - if (findConfigInfo4Beta(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()) == null) { + if (findConfigInfo4BetaState(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()) == null) { return addConfigInfo4Beta(configInfo, betaIps, srcIp, srcUser); } else { return updateConfigInfo4BetaCas(configInfo, betaIps, srcIp, srcUser); @@ -168,7 +168,7 @@ public ConfigOperateResult insertOrUpdateBetaCas(final ConfigInfo configInfo, fi @Override public void removeConfigInfo4Beta(final String dataId, final String group, final String tenant) { final String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - ConfigInfo configInfo = findConfigInfo4Beta(dataId, group, tenant); + ConfigInfoStateWrapper configInfo = findConfigInfo4BetaState(dataId, group, tenant); if (configInfo != null) { try { ConfigInfoBetaMapper configInfoBetaMapper = mapperManager.findMapper( @@ -227,7 +227,7 @@ public ConfigOperateResult updateConfigInfo4BetaCas(ConfigInfo configInfo, Strin String srcUser) { String appNameTmp = StringUtils.defaultEmptyIfBlank(configInfo.getAppName()); String tenantTmp = StringUtils.defaultEmptyIfBlank(configInfo.getTenant()); - + configInfo.setTenant(tenantTmp); try { String md5 = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoPersistServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoPersistServiceImpl.java index 7d9d51b0b4d..3095073a32b 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoPersistServiceImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoPersistServiceImpl.java @@ -28,10 +28,8 @@ import com.alibaba.nacos.config.server.model.ConfigAdvanceInfo; import com.alibaba.nacos.config.server.model.ConfigAllInfo; import com.alibaba.nacos.config.server.model.ConfigInfo; -import com.alibaba.nacos.config.server.model.ConfigInfoBase; import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; import com.alibaba.nacos.config.server.model.ConfigInfoWrapper; -import com.alibaba.nacos.config.server.model.ConfigKey; import com.alibaba.nacos.config.server.model.ConfigOperateResult; import com.alibaba.nacos.config.server.model.SameConfigPolicy; import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; @@ -63,7 +61,6 @@ import org.springframework.context.annotation.Conditional; import org.springframework.stereotype.Service; -import java.io.IOException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Arrays; @@ -78,11 +75,9 @@ import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_ADVANCE_INFO_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_ALL_INFO_ROW_MAPPER; -import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_BASE_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_WRAPPER_ROW_MAPPER; -import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_KEY_ROW_MAPPER; import static com.alibaba.nacos.config.server.utils.LogUtil.DEFAULT_LOG; import static com.alibaba.nacos.persistence.repository.RowMapperManager.MAP_ROW_MAPPER; @@ -139,7 +134,7 @@ public class EmbeddedConfigInfoPersistServiceImpl implements ConfigInfoPersistSe /** * The constructor sets the dependency injection order. * - * @param databaseOperate databaseOperate. + * @param databaseOperate databaseOperate. * @param idGeneratorManager {@link IdGeneratorManager} */ public EmbeddedConfigInfoPersistServiceImpl(DatabaseOperate databaseOperate, IdGeneratorManager idGeneratorManager, @@ -234,7 +229,7 @@ private ConfigOperateResult addConfigInfo(final String srcIp, final String srcUs @Override public ConfigOperateResult insertOrUpdate(String srcIp, String srcUser, ConfigInfo configInfo, Map configAdvanceInfo) { - if (Objects.isNull(findConfigInfo(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()))) { + if (Objects.isNull(findConfigInfoState(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()))) { return addConfigInfo(srcIp, srcUser, configInfo, configAdvanceInfo); } else { return updateConfigInfo(configInfo, srcIp, srcUser, configAdvanceInfo); @@ -244,7 +239,7 @@ public ConfigOperateResult insertOrUpdate(String srcIp, String srcUser, ConfigIn @Override public ConfigOperateResult insertOrUpdateCas(String srcIp, String srcUser, ConfigInfo configInfo, Map configAdvanceInfo) { - if (Objects.isNull(findConfigInfo(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()))) { + if (Objects.isNull(findConfigInfoState(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()))) { return addConfigInfo(srcIp, srcUser, configInfo, configAdvanceInfo); } else { return updateConfigInfoCas(configInfo, srcIp, srcUser, configAdvanceInfo); @@ -647,27 +642,6 @@ public void updateConfigInfoAtomic(final ConfigInfo configInfo, final String src EmbeddedStorageContextHolder.addSqlContext(sql, args); } - @Override - public void updateMd5(String dataId, String group, String tenant, String md5, Timestamp lastTime) { - String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - try { - ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO); - final String sql = configInfoMapper.update(Collections.singletonList("md5"), - Arrays.asList("data_id", "group_id", "tenant_id", "gmt_modified")); - final Object[] args = new Object[] {md5, dataId, group, tenantTmp, lastTime}; - - EmbeddedStorageContextHolder.addSqlContext(sql, args); - - boolean result = databaseOperate.update(EmbeddedStorageContextHolder.getCurrentSqlContext()); - if (!result) { - throw new NacosConfigException("Failed to config the MD5 modification"); - } - } finally { - EmbeddedStorageContextHolder.cleanAllContext(); - } - } - @Override public long findConfigMaxId() { ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), @@ -676,25 +650,6 @@ public long findConfigMaxId() { return Optional.ofNullable(databaseOperate.queryOne(mapperResult.getSql(), Long.class)).orElse(0L); } - @Override - public List findAllDataIdAndGroup() { - ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO); - MapperResult sql = configInfoMapper.findAllDataIdAndGroup(null); - return databaseOperate.queryMany(sql.getSql(), EMPTY_ARRAY, CONFIG_INFO_ROW_MAPPER); - } - - @Override - public ConfigInfoBase findConfigInfoBase(final String dataId, final String group) { - ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO); - final String sql = configInfoMapper.select(Arrays.asList("id", "data_id", "group_id", "content"), - Arrays.asList("data_id", "group_id", "tenant_id")); - - return databaseOperate.queryOne(sql, new Object[] {dataId, group, StringUtils.EMPTY}, - CONFIG_INFO_BASE_ROW_MAPPER); - } - @Override public ConfigInfo findConfigInfo(long id) { ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), @@ -747,7 +702,7 @@ public Page findConfigInfo4Page(final int pageNo, final int pageSize if (StringUtils.isNotBlank(configTags)) { String[] tagArr = configTags.split(","); - context.putWhereParameter(FieldConstant.TAG_ARR, Arrays.asList(tagArr)); + context.putWhereParameter(FieldConstant.TAG_ARR, tagArr); ConfigTagsRelationMapper configTagsRelationMapper = mapperManager.findMapper( dataSourceService.getDataSourceType(), TableConstant.CONFIG_TAGS_RELATION); sqlCount = configTagsRelationMapper.findConfigInfo4PageCountRows(context); @@ -771,41 +726,6 @@ public Page findConfigInfo4Page(final int pageNo, final int pageSize return page; } - @Override - public Page findConfigInfoByApp(final int pageNo, final int pageSize, final String tenant, - final String appName) { - String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - final int startRow = (pageNo - 1) * pageSize; - MapperContext context = new MapperContext(startRow, pageSize); - context.putWhereParameter(FieldConstant.APP_NAME, appName); - context.putWhereParameter(FieldConstant.TENANT_ID, generateLikeArgument(tenantTmp)); - - ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO); - MapperResult countRows = configInfoMapper.findConfigInfoByAppCountRows(context); - MapperResult fetchRows = configInfoMapper.findConfigInfoByAppFetchRows(context); - - final PaginationHelper helper = createPaginationHelper(); - return helper.fetchPageLimit(countRows, fetchRows, pageNo, pageSize, CONFIG_INFO_ROW_MAPPER); - - } - - @Override - public Page findConfigInfoBaseByGroup(final int pageNo, final int pageSize, final String group) { - PaginationHelper helper = createPaginationHelper(); - final int startRow = (pageNo - 1) * pageSize; - ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO); - - MapperContext context = new MapperContext(startRow, pageSize); - context.putWhereParameter(FieldConstant.GROUP_ID, group); - context.putWhereParameter(FieldConstant.TENANT_ID, StringUtils.EMPTY); - MapperResult mapperResult = configInfoMapper.findConfigInfoBaseByGroupFetchRows(context); - - return helper.fetchPage(configInfoMapper.count(Arrays.asList("group_id", "tenant_id")), mapperResult.getSql(), - mapperResult.getParamList().toArray(), pageNo, pageSize, CONFIG_INFO_BASE_ROW_MAPPER); - } - @Override public int configInfoCount() { ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), @@ -863,56 +783,6 @@ public List getGroupIdList(int page, int pageSize) { .collect(Collectors.toList()); } - @Override - public Page findAllConfigInfo(final int pageNo, final int pageSize, final String tenant) { - String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - final int startRow = (pageNo - 1) * pageSize; - ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO); - String sqlCountRows = configInfoMapper.count(null); - MapperContext context = new MapperContext(startRow, pageSize); - context.putWhereParameter(FieldConstant.TENANT_ID, generateLikeArgument(tenantTmp)); - MapperResult sqlFetchRows = configInfoMapper.findAllConfigInfoFetchRows(context); - - PaginationHelper helper = createPaginationHelper(); - return helper.fetchPageLimit(sqlCountRows, sqlFetchRows.getSql(), sqlFetchRows.getParamList().toArray(), pageNo, - pageSize, CONFIG_INFO_ROW_MAPPER); - - } - - @Override - public Page findAllConfigKey(final int pageNo, final int pageSize, final String tenant) { - final String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO); - MapperContext context = new MapperContext((pageNo - 1) * pageSize, pageSize); - context.putWhereParameter(FieldConstant.TENANT_ID, generateLikeArgument(tenantTmp)); - final MapperResult mapperResult = configInfoMapper.findAllConfigKey(context); - - final int totalCount = configInfoCount(tenant); - int pageCount = totalCount / pageSize; - if (totalCount > pageSize * pageCount) { - pageCount++; - } - - if (pageNo > pageCount) { - return null; - } - - final Page page = new Page<>(); - page.setPageNumber(pageNo); - page.setPagesAvailable(pageCount); - page.setTotalCount(totalCount); - - List result = databaseOperate.queryMany(mapperResult.getSql(), mapperResult.getParamList().toArray(), - CONFIG_KEY_ROW_MAPPER); - - for (ConfigKey item : result) { - page.getPageItems().add(item); - } - return page; - } - @Override public Page findAllConfigInfoFragment(final long lastMaxId, final int pageSize) { ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), @@ -926,100 +796,6 @@ public Page findAllConfigInfoFragment(final long lastMaxId, f } - @Override - public Page findConfigInfoLike(final int pageNo, final int pageSize, final ConfigKey[] configKeys, - final boolean blacklist) { - String sqlCountRows = "SELECT count(*) FROM config_info WHERE "; - String sqlFetchRows = "SELECT id,data_id,group_id,tenant_id,app_name,content FROM config_info WHERE "; - StringBuilder where = new StringBuilder(" 1=1 "); - // White list, please synchronize the condition is empty, there is no qualified configuration - if (configKeys.length == 0 && !blacklist) { - Page page = new Page<>(); - page.setTotalCount(0); - return page; - } - List params = new ArrayList<>(); - boolean isFirst = true; - for (ConfigKey configInfo : configKeys) { - String dataId = configInfo.getDataId(); - String group = configInfo.getGroup(); - String appName = configInfo.getAppName(); - - if (StringUtils.isBlank(dataId) && StringUtils.isBlank(group) && StringUtils.isBlank(appName)) { - break; - } - - if (blacklist) { - if (isFirst) { - isFirst = false; - where.append(" AND "); - } else { - where.append(" AND "); - } - - where.append('('); - boolean isFirstSub = true; - if (!StringUtils.isBlank(dataId)) { - where.append(" data_id NOT LIKE ? "); - params.add(generateLikeArgument(dataId)); - isFirstSub = false; - } - if (!StringUtils.isBlank(group)) { - if (!isFirstSub) { - where.append(" OR "); - } - where.append(" group_id NOT LIKE ? "); - params.add(generateLikeArgument(group)); - isFirstSub = false; - } - if (!StringUtils.isBlank(appName)) { - if (!isFirstSub) { - where.append(" OR "); - } - where.append(" app_name != ? "); - params.add(appName); - isFirstSub = false; - } - where.append(") "); - } else { - if (isFirst) { - isFirst = false; - where.append(" AND "); - } else { - where.append(" OR "); - } - where.append('('); - boolean isFirstSub = true; - if (!StringUtils.isBlank(dataId)) { - where.append(" data_id LIKE ? "); - params.add(generateLikeArgument(dataId)); - isFirstSub = false; - } - if (!StringUtils.isBlank(group)) { - if (!isFirstSub) { - where.append(" AND "); - } - where.append(" group_id LIKE ? "); - params.add(generateLikeArgument(group)); - isFirstSub = false; - } - if (!StringUtils.isBlank(appName)) { - if (!isFirstSub) { - where.append(" AND "); - } - where.append(" app_name = ? "); - params.add(appName); - isFirstSub = false; - } - where.append(") "); - } - } - PaginationHelper helper = createPaginationHelper(); - return helper.fetchPage(sqlCountRows + where, sqlFetchRows + where, params.toArray(), pageNo, pageSize, - CONFIG_INFO_ROW_MAPPER); - - } - @Override public Page findConfigInfoLike4Page(final int pageNo, final int pageSize, final String dataId, final String group, final String tenant, final Map configAdvanceInfo) { @@ -1071,33 +847,6 @@ public Page findConfigInfoLike4Page(final int pageNo, final int page } - @Override - public Page findConfigInfoBaseLike(final int pageNo, final int pageSize, final String dataId, - final String group, final String content) throws IOException { - if (StringUtils.isBlank(dataId) && StringUtils.isBlank(group)) { - throw new IOException("invalid param"); - } - MapperContext context = new MapperContext((pageNo - 1) * pageSize, pageSize); - - if (!StringUtils.isBlank(dataId)) { - context.putWhereParameter(FieldConstant.DATA_ID, generateLikeArgument(dataId)); - } - if (!StringUtils.isBlank(group)) { - context.putWhereParameter(FieldConstant.GROUP_ID, generateLikeArgument(group)); - } - if (!StringUtils.isBlank(content)) { - context.putWhereParameter(FieldConstant.CONTENT, generateLikeArgument(content)); - } - - ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO); - MapperResult sqlCountRows = configInfoMapper.findConfigInfoBaseLikeCountRows(context); - MapperResult sqlFetchRows = configInfoMapper.findConfigInfoBaseLikeFetchRows(context); - PaginationHelper helper = createPaginationHelper(); - return helper.fetchPageLimit(sqlCountRows, sqlFetchRows, pageNo, pageSize, CONFIG_INFO_BASE_ROW_MAPPER); - - } - @Override public List findChangeConfig(final Timestamp startTime, long lastMaxId, final int pageSize) { ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), @@ -1109,45 +858,8 @@ public List findChangeConfig(final Timestamp startTime, long context.putWhereParameter(FieldConstant.LAST_MAX_ID, lastMaxId); MapperResult mapperResult = configInfoMapper.findChangeConfig(context); - List> list = databaseOperate.queryMany(mapperResult.getSql(), - mapperResult.getParamList().toArray()); - return convertChangeConfig(list); - - } - - @SuppressWarnings("checkstyle:WhitespaceAfter") - @Override - public Page findChangeConfig(final String dataId, final String group, final String tenant, - final String appName, final Timestamp startTime, final Timestamp endTime, final int pageNo, - final int pageSize, final long lastMaxId) { - String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - MapperContext context = new MapperContext((pageNo - 1) * pageSize, pageSize); - if (!StringUtils.isBlank(dataId)) { - context.putWhereParameter(FieldConstant.DATA_ID, generateLikeArgument(dataId)); - } - if (!StringUtils.isBlank(group)) { - context.putWhereParameter(FieldConstant.GROUP_ID, generateLikeArgument(group)); - } - if (!StringUtils.isBlank(tenantTmp)) { - context.putWhereParameter(FieldConstant.TENANT, tenantTmp); - } - if (!StringUtils.isBlank(appName)) { - context.putWhereParameter(FieldConstant.APP_NAME, appName); - } - if (startTime != null) { - context.putWhereParameter(FieldConstant.START_TIME, startTime); - } - if (endTime != null) { - context.putWhereParameter(FieldConstant.END_TIME, endTime); - } - - ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO); - MapperResult sqlCountRows = configInfoMapper.findChangeConfigCountRows(context); - MapperResult sqlFetchRows = configInfoMapper.findChangeConfigFetchRows(context); - - PaginationHelper helper = createPaginationHelper(); - return helper.fetchPageLimit(sqlCountRows, sqlFetchRows, pageNo, pageSize, CONFIG_INFO_WRAPPER_ROW_MAPPER); + return databaseOperate.queryMany(mapperResult.getSql(), mapperResult.getParamList().toArray(), + CONFIG_INFO_WRAPPER_ROW_MAPPER); } @@ -1236,83 +948,6 @@ public ConfigAllInfo findConfigAllInfo(final String dataId, final String group, return configAdvance; } - @Override - public List convertDeletedConfig(List> list) { - List configs = new ArrayList<>(); - for (Map map : list) { - String dataId = (String) map.get("data_id"); - String group = (String) map.get("group_id"); - String tenant = (String) map.get("tenant_id"); - ConfigInfo config = new ConfigInfo(); - config.setDataId(dataId); - config.setGroup(group); - config.setTenant(tenant); - configs.add(config); - } - return configs; - } - - @Override - public List convertChangeConfig(List> list) { - List configs = new ArrayList<>(); - for (Map map : list) { - Long id = ((java.lang.Number) map.get("id")).longValue(); - String dataId = (String) map.get("data_id"); - String group = (String) map.get("group_id"); - String tenant = (String) map.get("tenant_id"); - String md5 = (String) map.get("md5"); - long mTime = ((Timestamp) map.get("gmt_modified")).getTime(); - ConfigInfoWrapper config = new ConfigInfoWrapper(); - config.setId(id); - config.setDataId(dataId); - config.setGroup(group); - config.setMd5(md5); - config.setTenant(tenant); - config.setLastModified(mTime); - configs.add(config); - } - return configs; - } - - @Override - public List listAllGroupKeyMd5() { - final int pageSize = 10000; - int totalCount = configInfoCount(); - int pageCount = (int) Math.ceil(totalCount * 1.0 / pageSize); - List allConfigInfo = new ArrayList<>(); - for (int pageNo = 1; pageNo <= pageCount; pageNo++) { - List configInfoList = listGroupKeyMd5ByPage(pageNo, pageSize); - allConfigInfo.addAll(configInfoList); - } - return allConfigInfo; - } - - @Override - public List listGroupKeyMd5ByPage(int pageNo, int pageSize) { - ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO); - String sqlCountRows = configInfoMapper.count(null); - MapperResult sqlFetchRows = configInfoMapper.listGroupKeyMd5ByPageFetchRows( - new MapperContext((pageNo - 1) * pageSize, pageSize)); - PaginationHelper helper = createPaginationHelper(); - Page page = helper.fetchPageLimit(sqlCountRows, sqlFetchRows.getSql(), new Object[] {}, - pageNo, pageSize, CONFIG_INFO_WRAPPER_ROW_MAPPER); - - return page.getPageItems(); - } - - @Override - public ConfigInfoWrapper queryConfigInfo(final String dataId, final String group, final String tenant) { - String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO); - final String sql = configInfoMapper.select( - Arrays.asList("id", "data_id", "group_id", "tenant_id", "app_name", "content", "type", "gmt_modified", - "md5", "encrypted_data_key"), Arrays.asList("data_id", "group_id", "tenant_id")); - - return databaseOperate.queryOne(sql, new Object[] {dataId, group, tenantTmp}, CONFIG_INFO_WRAPPER_ROW_MAPPER); - } - @Override public List findAllConfigInfo4Export(final String dataId, final String group, final String tenant, final String appName, final List ids) { @@ -1354,18 +989,4 @@ public List queryConfigInfoByNamespace(String tenantId) { return databaseOperate.queryMany(sql, new Object[] {tenantTmp}, CONFIG_INFO_WRAPPER_ROW_MAPPER); } - @Override - public Page findAllConfigInfoBase(final int pageNo, final int pageSize) { - final int startRow = (pageNo - 1) * pageSize; - ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO); - String sqlCountRows = configInfoMapper.count(null); - MapperResult sqlFetchRows = configInfoMapper.findAllConfigInfoBaseFetchRows( - new MapperContext(startRow, pageSize)); - - PaginationHelper helper = createPaginationHelper(); - return helper.fetchPageLimit(sqlCountRows, sqlFetchRows.getSql(), sqlFetchRows.getParamList().toArray(), pageNo, - pageSize, CONFIG_INFO_BASE_ROW_MAPPER); - - } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoTagPersistServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoTagPersistServiceImpl.java index 7c6f078f2a0..a4d9d437fd5 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoTagPersistServiceImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoTagPersistServiceImpl.java @@ -147,7 +147,7 @@ public ConfigOperateResult addConfigInfo4Tag(ConfigInfo configInfo, String tag, @Override public ConfigOperateResult insertOrUpdateTag(final ConfigInfo configInfo, final String tag, final String srcIp, final String srcUser) { - if (findConfigInfo4Tag(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant(), tag) == null) { + if (findConfigInfo4TagState(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant(), tag) == null) { return addConfigInfo4Tag(configInfo, tag, srcIp, srcUser); } else { return updateConfigInfo4Tag(configInfo, tag, srcIp, srcUser); @@ -157,7 +157,7 @@ public ConfigOperateResult insertOrUpdateTag(final ConfigInfo configInfo, final @Override public ConfigOperateResult insertOrUpdateTagCas(final ConfigInfo configInfo, final String tag, final String srcIp, final String srcUser) { - if (findConfigInfo4Tag(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant(), tag) == null) { + if (findConfigInfo4TagState(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant(), tag) == null) { return addConfigInfo4Tag(configInfo, tag, srcIp, srcUser); } else { return updateConfigInfo4TagCas(configInfo, tag, srcIp, srcUser); @@ -248,7 +248,7 @@ public ConfigOperateResult updateConfigInfo4TagCas(ConfigInfo configInfo, String final MapperResult mapperResult = configInfoTagMapper.updateConfigInfo4TagCas(context); EmbeddedStorageContextUtils.onModifyConfigTagInfo(configInfo, tagTmp, srcIp, time); - EmbeddedStorageContextHolder.addSqlContext(mapperResult.getSql(), mapperResult.getParamList()); + EmbeddedStorageContextHolder.addSqlContext(mapperResult.getSql(), mapperResult.getParamList().toArray()); Boolean success = databaseOperate.blockUpdate(); if (success) { diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoAggrPersistServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoAggrPersistServiceImpl.java index 071e54118d9..03c7d093e1c 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoAggrPersistServiceImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoAggrPersistServiceImpl.java @@ -17,16 +17,15 @@ package com.alibaba.nacos.config.server.service.repository.extrnal; import com.alibaba.nacos.common.utils.StringUtils; -import com.alibaba.nacos.persistence.configuration.condition.ConditionOnExternalStorage; import com.alibaba.nacos.config.server.model.ConfigInfoAggr; import com.alibaba.nacos.config.server.model.ConfigInfoChanged; -import com.alibaba.nacos.config.server.model.ConfigKey; -import com.alibaba.nacos.persistence.model.Page; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoAggrPersistService; +import com.alibaba.nacos.config.server.utils.LogUtil; +import com.alibaba.nacos.persistence.configuration.condition.ConditionOnExternalStorage; import com.alibaba.nacos.persistence.datasource.DataSourceService; import com.alibaba.nacos.persistence.datasource.DynamicDataSource; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoAggrPersistService; +import com.alibaba.nacos.persistence.model.Page; import com.alibaba.nacos.persistence.repository.PaginationHelper; -import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.persistence.repository.extrnal.ExternalStoragePaginationHelperImpl; import com.alibaba.nacos.plugin.datasource.MapperManager; import com.alibaba.nacos.plugin.datasource.constants.CommonConstant; @@ -39,7 +38,6 @@ import org.springframework.context.annotation.Conditional; import org.springframework.dao.DataAccessException; import org.springframework.dao.EmptyResultDataAccessException; -import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.jdbc.CannotGetJdbcConnectionException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; @@ -48,7 +46,6 @@ import org.springframework.transaction.support.TransactionTemplate; import java.sql.Timestamp; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -89,17 +86,6 @@ public PaginationHelper createPaginationHelper() { return new ExternalStoragePaginationHelperImpl<>(jt); } - @Override - public String generateLikeArgument(String s) { - String fuzzySearchSign = "\\*"; - String sqlLikePercentSign = "%"; - if (s.contains(PATTERN_STR)) { - return s.replaceAll(fuzzySearchSign, sqlLikePercentSign); - } else { - return s; - } - } - @Override public boolean addAggrConfigInfo(final String dataId, final String group, String tenant, final String datumId, String appName, final String content) { @@ -160,108 +146,6 @@ public boolean batchPublishAggr(final String dataId, final String group, final S } } - @Override - public boolean replaceAggr(final String dataId, final String group, final String tenant, - final Map datumMap, final String appName) { - try { - ConfigInfoAggrMapper configInfoAggrMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO_AGGR); - Boolean isReplaceOk = tjt.execute(status -> { - try { - String appNameTmp = appName == null ? "" : appName; - removeAggrConfigInfo(dataId, group, tenant); - String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - String sql = configInfoAggrMapper.insert( - Arrays.asList("data_id", "group_id", "tenant_id", "datum_id", "app_name", "content", - "gmt_modified")); - for (Map.Entry datumEntry : datumMap.entrySet()) { - jt.update(sql, dataId, group, tenantTmp, datumEntry.getKey(), appNameTmp, datumEntry.getValue(), - new Timestamp(System.currentTimeMillis())); - } - } catch (Throwable e) { - throw new TransactionSystemException("error in addAggrConfigInfo"); - } - return Boolean.TRUE; - }); - if (isReplaceOk == null) { - return false; - } - return isReplaceOk; - } catch (TransactionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - return false; - } - - } - - @Override - public void removeSingleAggrConfigInfo(final String dataId, final String group, final String tenant, - final String datumId) { - final String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - ConfigInfoAggrMapper configInfoAggrMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO_AGGR); - String sql = configInfoAggrMapper.delete(Arrays.asList("data_id", "group_id", "tenant_id", "datum_id")); - - try { - this.jt.update(sql, ps -> { - int index = 1; - ps.setString(index++, dataId); - ps.setString(index++, group); - ps.setString(index++, tenantTmp); - ps.setString(index, datumId); - }); - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } - } - - @Override - public void removeAggrConfigInfo(final String dataId, final String group, final String tenant) { - final String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - ConfigInfoAggrMapper configInfoAggrMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO_AGGR); - String sql = configInfoAggrMapper.delete(Arrays.asList("data_id", "group_id", "tenant_id")); - - try { - this.jt.update(sql, ps -> { - int index = 1; - ps.setString(index++, dataId); - ps.setString(index++, group); - ps.setString(index, tenantTmp); - }); - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } - } - - @Override - public boolean batchRemoveAggr(final String dataId, final String group, final String tenant, - final List datumList) { - final String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - ConfigInfoAggrMapper configInfoAggrMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO_AGGR); - - MapperContext context = new MapperContext(); - context.putWhereParameter(FieldConstant.DATUM_ID, datumList); - context.putWhereParameter(FieldConstant.DATA_ID, dataId); - context.putWhereParameter(FieldConstant.GROUP_ID, group); - context.putWhereParameter(FieldConstant.TENANT_ID, tenantTmp); - - MapperResult result = configInfoAggrMapper.batchRemoveAggr(context); - final String sql = result.getSql(); - final Object[] args = result.getParamList().toArray(); - - try { - jt.update(sql, args); - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - return false; - } - return true; - } - @Override public int aggrConfigInfoCount(String dataId, String group, String tenant) { String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; @@ -269,90 +153,9 @@ public int aggrConfigInfoCount(String dataId, String group, String tenant) { TableConstant.CONFIG_INFO_AGGR); String sql = configInfoAggrMapper.count(Arrays.asList("data_id", "group_id", "tenant_id")); Integer result = jt.queryForObject(sql, Integer.class, new Object[] {dataId, group, tenantTmp}); - if (result == null) { - throw new IllegalArgumentException("aggrConfigInfoCount error"); - } - return result.intValue(); - } - - @Override - public int aggrConfigInfoCount(String dataId, String group, String tenant, List datumIds, boolean isIn) { - if (datumIds == null || datumIds.isEmpty()) { - return 0; - } - final String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - ConfigInfoAggrMapper configInfoAggrMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO_AGGR); - - MapperContext context = new MapperContext(); - context.putWhereParameter(FieldConstant.DATUM_ID, datumIds); - context.putWhereParameter(FieldConstant.IS_IN, true); - context.putWhereParameter(FieldConstant.DATA_ID, dataId); - context.putWhereParameter(FieldConstant.GROUP_ID, group); - context.putWhereParameter(FieldConstant.TENANT_ID, tenantTmp); - - MapperResult mapperResult = configInfoAggrMapper.aggrConfigInfoCount(context); - String sql = mapperResult.getSql(); - Object[] args = mapperResult.getParamList().toArray(); - Integer result = jt.queryForObject(sql, Integer.class, args); - if (result == null) { - throw new IllegalArgumentException("aggrConfigInfoCount error"); - } return result.intValue(); } - @Override - public ConfigInfoAggr findSingleConfigInfoAggr(String dataId, String group, String tenant, String datumId) { - String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - ConfigInfoAggrMapper configInfoAggrMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO_AGGR); - String sql = configInfoAggrMapper.select( - Arrays.asList("id", "data_id", "group_id", "tenant_id", "datum_id", "app_name", "content"), - Arrays.asList("data_id", "group_id", "tenant_id", "datum_id")); - - try { - return this.jt.queryForObject(sql, new Object[] {dataId, group, tenantTmp, datumId}, - CONFIG_INFO_AGGR_ROW_MAPPER); - } catch (EmptyResultDataAccessException e) { - // EmptyResultDataAccessException, indicating that the data does not exist, returns null - return null; - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } catch (Exception e) { - LogUtil.FATAL_LOG.error("[db-other-error]" + e.getMessage(), e); - throw new RuntimeException(e); - } - } - - @Override - public List findConfigInfoAggr(String dataId, String group, String tenant) { - String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - ConfigInfoAggrMapper configInfoAggrMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO_AGGR); - - MapperContext context = new MapperContext(); - context.putWhereParameter(FieldConstant.DATA_ID, dataId); - context.putWhereParameter(FieldConstant.GROUP_ID, group); - context.putWhereParameter(FieldConstant.TENANT_ID, tenantTmp); - - MapperResult mapperResult = configInfoAggrMapper.findConfigInfoAggrIsOrdered(context); - String sql = mapperResult.getSql(); - Object[] args = mapperResult.getParamList().toArray(); - - try { - return this.jt.query(sql, args, CONFIG_INFO_AGGR_ROW_MAPPER); - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } catch (EmptyResultDataAccessException e) { - return Collections.emptyList(); - } catch (Exception e) { - LogUtil.FATAL_LOG.error("[db-other-error]" + e.getMessage(), e); - throw new RuntimeException(e); - } - } - @Override public Page findConfigInfoAggrByPage(String dataId, String group, String tenant, final int pageNo, final int pageSize) { @@ -385,106 +188,6 @@ public Page findConfigInfoAggrByPage(String dataId, String group } } - @Override - public Page findConfigInfoAggrLike(final int pageNo, final int pageSize, ConfigKey[] configKeys, - boolean blacklist) { - - String sqlCountRows = "SELECT count(*) FROM config_info_aggr WHERE "; - String sqlFetchRows = "SELECT data_id,group_id,tenant_id,datum_id,app_name,content FROM config_info_aggr WHERE "; - StringBuilder where = new StringBuilder(" 1=1 "); - // Whitelist, please leave the synchronization condition empty, there is no configuration that meets the conditions - if (configKeys.length == 0 && blacklist == false) { - Page page = new Page<>(); - page.setTotalCount(0); - return page; - } - PaginationHelper helper = createPaginationHelper(); - List params = new ArrayList<>(); - boolean isFirst = true; - - for (ConfigKey configInfoAggr : configKeys) { - String dataId = configInfoAggr.getDataId(); - String group = configInfoAggr.getGroup(); - String appName = configInfoAggr.getAppName(); - if (StringUtils.isBlank(dataId) && StringUtils.isBlank(group) && StringUtils.isBlank(appName)) { - break; - } - if (blacklist) { - if (isFirst) { - isFirst = false; - where.append(" AND "); - } else { - where.append(" AND "); - } - - where.append('('); - boolean isFirstSub = true; - if (!StringUtils.isBlank(dataId)) { - where.append(" data_id NOT LIKE ? "); - params.add(generateLikeArgument(dataId)); - isFirstSub = false; - } - if (!StringUtils.isBlank(group)) { - if (!isFirstSub) { - where.append(" OR "); - } - where.append(" group_id NOT LIKE ? "); - params.add(generateLikeArgument(group)); - isFirstSub = false; - } - if (!StringUtils.isBlank(appName)) { - if (!isFirstSub) { - where.append(" OR "); - } - where.append(" app_name != ? "); - params.add(appName); - isFirstSub = false; - } - where.append(") "); - } else { - if (isFirst) { - isFirst = false; - where.append(" AND "); - } else { - where.append(" OR "); - } - where.append('('); - boolean isFirstSub = true; - if (!StringUtils.isBlank(dataId)) { - where.append(" data_id LIKE ? "); - params.add(generateLikeArgument(dataId)); - isFirstSub = false; - } - if (!StringUtils.isBlank(group)) { - if (!isFirstSub) { - where.append(" AND "); - } - where.append(" group_id LIKE ? "); - params.add(generateLikeArgument(group)); - isFirstSub = false; - } - if (!StringUtils.isBlank(appName)) { - if (!isFirstSub) { - where.append(" AND "); - } - where.append(" app_name = ? "); - params.add(appName); - isFirstSub = false; - } - where.append(") "); - } - } - - try { - Page result = helper.fetchPage(sqlCountRows + where, sqlFetchRows + where, params.toArray(), - pageNo, pageSize, CONFIG_INFO_AGGR_ROW_MAPPER); - return result; - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } - } - @Override public List findAllAggrGroup() { ConfigInfoAggrMapper configInfoAggrMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), @@ -495,7 +198,7 @@ public List findAllAggrGroup() { return jt.query(mapperResult.getSql(), mapperResult.getParamList().toArray(), CONFIG_INFO_CHANGED_ROW_MAPPER); } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e.toString(), e); + LogUtil.FATAL_LOG.error("[db-error] " + e, e); throw e; } catch (EmptyResultDataAccessException e) { return null; @@ -505,22 +208,4 @@ public List findAllAggrGroup() { } } - @Override - public List findDatumIdByContent(String dataId, String groupId, String content) { - ConfigInfoAggrMapper configInfoAggrMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO_AGGR); - String sql = configInfoAggrMapper.select(Collections.singletonList("datum_id"), - Arrays.asList("data_id", "group_id", "content")); - - try { - return this.jt.queryForList(sql, new Object[] {dataId, groupId, content}, String.class); - } catch (EmptyResultDataAccessException e) { - return null; - } catch (IncorrectResultSizeDataAccessException e) { - return null; - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } - } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoBetaPersistServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoBetaPersistServiceImpl.java index 681efe131f0..d0b62bd498d 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoBetaPersistServiceImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoBetaPersistServiceImpl.java @@ -40,7 +40,6 @@ import com.alibaba.nacos.plugin.datasource.model.MapperResult; import com.alibaba.nacos.sys.env.EnvUtil; import org.springframework.context.annotation.Conditional; -import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.CannotGetJdbcConnectionException; import org.springframework.jdbc.core.JdbcTemplate; @@ -90,7 +89,7 @@ public PaginationHelper createPaginationHelper() { public ConfigOperateResult addConfigInfo4Beta(ConfigInfo configInfo, String betaIps, String srcIp, String srcUser) { String appNameTmp = StringUtils.defaultEmptyIfBlank(configInfo.getAppName()); String tenantTmp = StringUtils.defaultEmptyIfBlank(configInfo.getTenant()); - String md5 = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); + String md5 = MD5Utils.md5Hex(configInfo.getContent(), Constants.PERSIST_ENCODE); String encryptedDataKey = StringUtils.defaultEmptyIfBlank(configInfo.getEncryptedDataKey()); try { ConfigInfoBetaMapper configInfoBetaMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), @@ -113,9 +112,13 @@ public ConfigOperateResult addConfigInfo4Beta(ConfigInfo configInfo, String beta @Override public ConfigOperateResult insertOrUpdateBeta(final ConfigInfo configInfo, final String betaIps, final String srcIp, final String srcUser) { - try { + + ConfigInfoStateWrapper configInfo4BetaState = this.findConfigInfo4BetaState(configInfo.getDataId(), + configInfo.getGroup(), configInfo.getTenant()); + if (configInfo4BetaState == null) { return addConfigInfo4Beta(configInfo, betaIps, srcIp, srcUser); - } catch (DataIntegrityViolationException ive) { // Unique constraint conflict + + } else { return updateConfigInfo4Beta(configInfo, betaIps, srcIp, srcUser); } } @@ -123,9 +126,11 @@ public ConfigOperateResult insertOrUpdateBeta(final ConfigInfo configInfo, final @Override public ConfigOperateResult insertOrUpdateBetaCas(final ConfigInfo configInfo, final String betaIps, final String srcIp, final String srcUser) { - try { + ConfigInfoStateWrapper configInfo4BetaState = this.findConfigInfo4BetaState(configInfo.getDataId(), + configInfo.getGroup(), configInfo.getTenant()); + if (configInfo4BetaState == null) { return addConfigInfo4Beta(configInfo, betaIps, srcIp, srcUser); - } catch (DataIntegrityViolationException ive) { // Unique constraint conflict + } else { return updateConfigInfo4BetaCas(configInfo, betaIps, srcIp, srcUser); } } @@ -135,7 +140,7 @@ public void removeConfigInfo4Beta(final String dataId, final String group, final final String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; tjt.execute(status -> { try { - ConfigInfo configInfo = findConfigInfo4Beta(dataId, group, tenant); + ConfigInfoStateWrapper configInfo = findConfigInfo4BetaState(dataId, group, tenant); if (configInfo != null) { ConfigInfoBetaMapper configInfoBetaMapper = mapperManager.findMapper( dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO_BETA); @@ -265,10 +270,8 @@ public int configInfoBetaCount() { TableConstant.CONFIG_INFO_BETA); String sql = configInfoBetaMapper.count(null); Integer result = jt.queryForObject(sql, Integer.class); - if (result == null) { - throw new IllegalArgumentException("configInfoBetaCount error"); - } - return result; + + return result.intValue(); } @Override diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoPersistServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoPersistServiceImpl.java index 5fc724be0ed..2473a3c77d4 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoPersistServiceImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoPersistServiceImpl.java @@ -25,10 +25,8 @@ import com.alibaba.nacos.config.server.model.ConfigAdvanceInfo; import com.alibaba.nacos.config.server.model.ConfigAllInfo; import com.alibaba.nacos.config.server.model.ConfigInfo; -import com.alibaba.nacos.config.server.model.ConfigInfoBase; import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; import com.alibaba.nacos.config.server.model.ConfigInfoWrapper; -import com.alibaba.nacos.config.server.model.ConfigKey; import com.alibaba.nacos.config.server.model.ConfigOperateResult; import com.alibaba.nacos.config.server.model.SameConfigPolicy; import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; @@ -57,25 +55,20 @@ import org.springframework.context.annotation.Conditional; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.dao.DuplicateKeyException; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.jdbc.CannotGetJdbcConnectionException; import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.PreparedStatementCreator; import org.springframework.jdbc.support.KeyHolder; import org.springframework.stereotype.Service; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionTemplate; -import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Timestamp; -import java.time.LocalDateTime; -import java.time.ZoneOffset; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -86,11 +79,9 @@ import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_ADVANCE_INFO_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_ALL_INFO_ROW_MAPPER; -import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_BASE_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_WRAPPER_ROW_MAPPER; -import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_KEY_ROW_MAPPER; /** * ExternalConfigInfoPersistServiceImpl. @@ -102,16 +93,6 @@ @Service("externalConfigInfoPersistServiceImpl") public class ExternalConfigInfoPersistServiceImpl implements ConfigInfoPersistService { - private static final String DATA_ID = "dataId"; - - private static final String GROUP = "group"; - - private static final String APP_NAME = "appName"; - - private static final String CONTENT = "content"; - - private static final String TENANT = "tenant_id"; - /** * constant variables. */ @@ -123,7 +104,7 @@ public class ExternalConfigInfoPersistServiceImpl implements ConfigInfoPersistSe protected TransactionTemplate tjt; - private MapperManager mapperManager; + MapperManager mapperManager; private HistoryConfigInfoPersistService historyConfigInfoPersistService; @@ -132,8 +113,8 @@ public ExternalConfigInfoPersistServiceImpl( this.dataSourceService = DynamicDataSource.getInstance().getDataSource(); this.jt = dataSourceService.getJdbcTemplate(); this.tjt = dataSourceService.getTransactionTemplate(); - Boolean isDataSourceLogEnable = EnvUtil - .getProperty(CommonConstant.NACOS_PLUGIN_DATASOURCE_LOG, Boolean.class, false); + Boolean isDataSourceLogEnable = EnvUtil.getProperty(CommonConstant.NACOS_PLUGIN_DATASOURCE_LOG, Boolean.class, + false); this.mapperManager = MapperManager.instance(isDataSourceLogEnable); this.historyConfigInfoPersistService = historyConfigInfoPersistService; } @@ -166,8 +147,8 @@ public ConfigOperateResult addConfigInfo(final String srcIp, final String srcUse Timestamp now = new Timestamp(System.currentTimeMillis()); historyConfigInfoPersistService.insertConfigHistoryAtomic(0, configInfo, srcIp, srcUser, now, "I"); - ConfigInfoStateWrapper configInfoCurrent = this - .findConfigInfoState(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); + ConfigInfoStateWrapper configInfoCurrent = this.findConfigInfoState(configInfo.getDataId(), + configInfo.getGroup(), configInfo.getTenant()); if (configInfoCurrent == null) { return new ConfigOperateResult(false); } @@ -192,20 +173,18 @@ public ConfigOperateResult addConfigInfo(final String srcIp, final String srcUse public ConfigOperateResult insertOrUpdate(String srcIp, String srcUser, ConfigInfo configInfo, Map configAdvanceInfo) { try { - return addConfigInfo(srcIp, srcUser, configInfo, configAdvanceInfo); - } catch (DuplicateKeyException ignore) { - // Must be unique constraint conflict. - return updateConfigInfo(configInfo, srcIp, srcUser, configAdvanceInfo); - } catch (DataIntegrityViolationException dive) { - // Might be unique constraint conflict or some of other data integrity violation. try to update. - try { + ConfigInfoStateWrapper configInfoState = findConfigInfoState(configInfo.getDataId(), configInfo.getGroup(), + configInfo.getTenant()); + if (configInfoState == null) { + return addConfigInfo(srcIp, srcUser, configInfo, configAdvanceInfo); + } else { return updateConfigInfo(configInfo, srcIp, srcUser, configAdvanceInfo); - } catch (Exception e) { - LogUtil.FATAL_LOG - .error("[db-error] try to update config failed, with DataIntegrityViolationException, {}", - dive.getMessage(), e); - throw e; } + + } catch (Exception exception) { + LogUtil.FATAL_LOG.error("[db-error] try to update or add config failed, {}", exception.getMessage(), + exception); + throw exception; } } @@ -213,26 +192,49 @@ public ConfigOperateResult insertOrUpdate(String srcIp, String srcUser, ConfigIn public ConfigOperateResult insertOrUpdateCas(String srcIp, String srcUser, ConfigInfo configInfo, Map configAdvanceInfo) { try { - return addConfigInfo(srcIp, srcUser, configInfo, configAdvanceInfo); - } catch (DuplicateKeyException ignore) { - // Must be unique constraint conflict. - return updateConfigInfoCas(configInfo, srcIp, srcUser, configAdvanceInfo); - } catch (DataIntegrityViolationException dive) { - // Might be unique constraint conflict or some of other data integrity violation. try to update. - try { + ConfigInfoStateWrapper configInfoState = findConfigInfoState(configInfo.getDataId(), configInfo.getGroup(), + configInfo.getTenant()); + if (configInfoState == null) { + return addConfigInfo(srcIp, srcUser, configInfo, configAdvanceInfo); + } else { return updateConfigInfoCas(configInfo, srcIp, srcUser, configAdvanceInfo); - } catch (Exception e) { - LogUtil.FATAL_LOG - .error("[db-error] try to update config cas failed, with DataIntegrityViolationException, {}", - dive.getMessage(), e); - throw e; } + + } catch (Exception exception) { + LogUtil.FATAL_LOG.error("[db-error] try to update or add config failed, {}", exception.getMessage(), + exception); + throw exception; } } - + @Override public long addConfigInfoAtomic(final long configId, final String srcIp, final String srcUser, final ConfigInfo configInfo, Map configAdvanceInfo) { + + KeyHolder keyHolder = ExternalStorageUtils.createKeyHolder(); + + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO); + try { + jt.update( + connection -> createPsForInsertConfigInfo(srcIp, srcUser, configInfo, configAdvanceInfo, connection, + configInfoMapper), keyHolder); + Number nu = keyHolder.getKey(); + if (nu == null) { + throw new IllegalArgumentException("insert config_info fail"); + } + return nu.longValue(); + } catch (CannotGetJdbcConnectionException e) { + LogUtil.FATAL_LOG.error("[db-error] " + e, e); + throw e; + } + } + + PreparedStatement createPsForInsertConfigInfo(final String srcIp, final String srcUser, final ConfigInfo configInfo, + Map configAdvanceInfo, Connection connection, ConfigInfoMapper configInfoMapper) + throws SQLException { + + Timestamp now = new Timestamp(System.currentTimeMillis()); final String appNameTmp = StringUtils.defaultEmptyIfBlank(configInfo.getAppName()); final String tenantTmp = StringUtils.defaultEmptyIfBlank(configInfo.getTenant()); @@ -246,60 +248,38 @@ public long addConfigInfoAtomic(final long configId, final String srcIp, final S final String md5Tmp = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); - KeyHolder keyHolder = ExternalStorageUtils.createKeyHolder(); - - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); - final String sql = configInfoMapper.insert(Arrays - .asList("data_id", "group_id", "tenant_id", "app_name", "content", "md5", "src_ip", "src_user", + String insertSql = configInfoMapper.insert( + Arrays.asList("data_id", "group_id", "tenant_id", "app_name", "content", "md5", "src_ip", "src_user", "gmt_create", "gmt_modified", "c_desc", "c_use", "effect", "type", "c_schema", "encrypted_data_key")); - String[] returnGeneratedKeys = configInfoMapper.getPrimaryKeyGeneratedKeys(); - try { - jt.update(new PreparedStatementCreator() { - @Override - public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { - Timestamp now = new Timestamp(System.currentTimeMillis()); - - PreparedStatement ps = connection.prepareStatement(sql, returnGeneratedKeys); - ps.setString(1, configInfo.getDataId()); - ps.setString(2, configInfo.getGroup()); - ps.setString(3, tenantTmp); - ps.setString(4, appNameTmp); - ps.setString(5, configInfo.getContent()); - ps.setString(6, md5Tmp); - ps.setString(7, srcIp); - ps.setString(8, srcUser); - ps.setTimestamp(9, now); - ps.setTimestamp(10, now); - ps.setString(11, desc); - ps.setString(12, use); - ps.setString(13, effect); - ps.setString(14, type); - ps.setString(15, schema); - ps.setString(16, encryptedDataKey); - return ps; - } - }, keyHolder); - Number nu = keyHolder.getKey(); - if (nu == null) { - throw new IllegalArgumentException("insert config_info fail"); - } - return nu.longValue(); - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } + PreparedStatement ps = connection.prepareStatement(insertSql, configInfoMapper.getPrimaryKeyGeneratedKeys()); + ps.setString(1, configInfo.getDataId()); + ps.setString(2, configInfo.getGroup()); + ps.setString(3, tenantTmp); + ps.setString(4, appNameTmp); + ps.setString(5, configInfo.getContent()); + ps.setString(6, md5Tmp); + ps.setString(7, srcIp); + ps.setString(8, srcUser); + ps.setTimestamp(9, now); + ps.setTimestamp(10, now); + ps.setString(11, desc); + ps.setString(12, use); + ps.setString(13, effect); + ps.setString(14, type); + ps.setString(15, schema); + ps.setString(16, encryptedDataKey); + return ps; } @Override public void addConfigTagRelationAtomic(long configId, String tagName, String dataId, String group, String tenant) { try { - ConfigTagsRelationMapper configTagsRelationMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_TAGS_RELATION); - jt.update(configTagsRelationMapper - .insert(Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id")), configId, - tagName, StringUtils.EMPTY, dataId, group, tenant); + ConfigTagsRelationMapper configTagsRelationMapper = mapperManager.findMapper( + dataSourceService.getDataSourceType(), TableConstant.CONFIG_TAGS_RELATION); + jt.update(configTagsRelationMapper.insert( + Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id")), configId, tagName, + StringUtils.EMPTY, dataId, group, tenant); } catch (CannotGetJdbcConnectionException e) { LogUtil.FATAL_LOG.error("[db-error] " + e, e); throw e; @@ -327,8 +307,8 @@ public Map batchInsertOrUpdate(List configInfoLis for (int i = 0; i < configInfoList.size(); i++) { ConfigAllInfo configInfo = configInfoList.get(i); try { - ParamUtils - .checkParam(configInfo.getDataId(), configInfo.getGroup(), "datumId", configInfo.getContent()); + ParamUtils.checkParam(configInfo.getDataId(), configInfo.getGroup(), "datumId", + configInfo.getContent()); } catch (NacosException e) { LogUtil.DEFAULT_LOG.error("data verification failed", e); throw e; @@ -354,11 +334,18 @@ public Map batchInsertOrUpdate(List configInfoLis } configAdvanceInfo.put("type", type); configAdvanceInfo.put("desc", configInfo.getDesc()); + boolean success; try { - addConfigInfo(srcIp, srcUser, configInfo2Save, configAdvanceInfo); - succCount++; + ConfigOperateResult configOperateResult = addConfigInfo(srcIp, srcUser, configInfo2Save, + configAdvanceInfo); + success = configOperateResult.isSuccess(); } catch (DataIntegrityViolationException ive) { - // uniqueness constraint conflict + success = false; + } + if (success) { + succCount++; + } else { + // uniqueness constraint conflict or add config info fail. if (SameConfigPolicy.ABORT.equals(policy)) { failData = new ArrayList<>(); skipData = new ArrayList<>(); @@ -372,6 +359,7 @@ public Map batchInsertOrUpdate(List configInfoLis skipitem.put("dataId", skipConfigInfo.getDataId()); skipitem.put("group", skipConfigInfo.getGroup()); skipData.add(skipitem); + skipCount++; } break; } else if (SameConfigPolicy.SKIP.equals(policy)) { @@ -388,6 +376,7 @@ public Map batchInsertOrUpdate(List configInfoLis updateConfigInfo(configInfo2Save, srcIp, srcUser, configAdvanceInfo); } } + } Map result = new HashMap<>(4); result.put("succCount", succCount); @@ -414,8 +403,8 @@ public Boolean doInTransaction(TransactionStatus status) { if (configInfo != null) { removeConfigInfoAtomic(dataId, group, tenant, srcIp, srcUser); removeTagByIdAtomic(configInfo.getId()); - historyConfigInfoPersistService - .insertConfigHistoryAtomic(configInfo.getId(), configInfo, srcIp, srcUser, time, "D"); + historyConfigInfoPersistService.insertConfigHistoryAtomic(configInfo.getId(), configInfo, srcIp, + srcUser, time, "D"); } } catch (CannotGetJdbcConnectionException e) { LogUtil.FATAL_LOG.error("[db-error] " + e, e); @@ -444,9 +433,8 @@ public List doInTransaction(TransactionStatus status) { removeConfigInfoByIdsAtomic(idsStr); for (ConfigInfo configInfo : configInfoList) { removeTagByIdAtomic(configInfo.getId()); - historyConfigInfoPersistService - .insertConfigHistoryAtomic(configInfo.getId(), configInfo, srcIp, srcUser, time, - "D"); + historyConfigInfoPersistService.insertConfigHistoryAtomic(configInfo.getId(), configInfo, + srcIp, srcUser, time, "D"); } } return configInfoList; @@ -461,8 +449,8 @@ public List doInTransaction(TransactionStatus status) { @Override public void removeTagByIdAtomic(long id) { try { - ConfigTagsRelationMapper configTagsRelationMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_TAGS_RELATION); + ConfigTagsRelationMapper configTagsRelationMapper = mapperManager.findMapper( + dataSourceService.getDataSourceType(), TableConstant.CONFIG_TAGS_RELATION); jt.update(configTagsRelationMapper.delete(Collections.singletonList("id")), id); } catch (CannotGetJdbcConnectionException e) { LogUtil.FATAL_LOG.error("[db-error] " + e, e); @@ -475,8 +463,8 @@ public void removeConfigInfoAtomic(final String dataId, final String group, fina final String srcUser) { String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; try { - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO); jt.update(configInfoMapper.delete(Arrays.asList("data_id", "group_id", "tenant_id")), dataId, group, tenantTmp); } catch (CannotGetJdbcConnectionException e) { @@ -495,8 +483,8 @@ public void removeConfigInfoByIdsAtomic(final String ids) { for (int i = 0; i < idArr.length; i++) { paramList.add(Long.parseLong(idArr[i])); } - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO); MapperContext context = new MapperContext(); context.putWhereParameter(FieldConstant.IDS, paramList); MapperResult result = configInfoMapper.removeConfigInfoByIdsAtomic(context); @@ -541,8 +529,8 @@ public ConfigOperateResult updateConfigInfo(final ConfigInfo configInfo, final S } Timestamp now = new Timestamp(System.currentTimeMillis()); - historyConfigInfoPersistService - .insertConfigHistoryAtomic(oldConfigInfo.getId(), oldConfigInfo, srcIp, srcUser, now, "U"); + historyConfigInfoPersistService.insertConfigHistoryAtomic(oldConfigInfo.getId(), oldConfigInfo, srcIp, + srcUser, now, "U"); return getConfigInfoOperateResult(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); } catch (CannotGetJdbcConnectionException e) { @@ -596,10 +584,10 @@ public ConfigOperateResult updateConfigInfoCas(final ConfigInfo configInfo, fina } Timestamp now = new Timestamp(System.currentTimeMillis()); - historyConfigInfoPersistService - .insertConfigHistoryAtomic(oldConfigInfo.getId(), oldConfigInfo, srcIp, srcUser, now, "U"); - ConfigInfoStateWrapper configInfoLast = this - .findConfigInfoState(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); + historyConfigInfoPersistService.insertConfigHistoryAtomic(oldConfigInfo.getId(), oldConfigInfo, srcIp, + srcUser, now, "U"); + ConfigInfoStateWrapper configInfoLast = this.findConfigInfoState(configInfo.getDataId(), + configInfo.getGroup(), configInfo.getTenant()); if (configInfoLast == null) { return new ConfigOperateResult(false); } @@ -615,7 +603,7 @@ private int updateConfigInfoAtomicCas(final ConfigInfo configInfo, final String Map configAdvanceInfo) { String appNameTmp = StringUtils.defaultEmptyIfBlank(configInfo.getAppName()); String tenantTmp = StringUtils.defaultEmptyIfBlank(configInfo.getTenant()); - final String md5Tmp = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); + final String md5Tmp = MD5Utils.md5Hex(configInfo.getContent(), Constants.PERSIST_ENCODE); String desc = configAdvanceInfo == null ? null : (String) configAdvanceInfo.get("desc"); String use = configAdvanceInfo == null ? null : (String) configAdvanceInfo.get("use"); String effect = configAdvanceInfo == null ? null : (String) configAdvanceInfo.get("effect"); @@ -623,8 +611,8 @@ private int updateConfigInfoAtomicCas(final ConfigInfo configInfo, final String String schema = configAdvanceInfo == null ? null : (String) configAdvanceInfo.get("schema"); try { - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO); Timestamp now = new Timestamp(System.currentTimeMillis()); MapperContext context = new MapperContext(); @@ -668,14 +656,14 @@ public void updateConfigInfoAtomic(final ConfigInfo configInfo, final String src configInfo.getEncryptedDataKey() == null ? StringUtils.EMPTY : configInfo.getEncryptedDataKey(); try { - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO); Timestamp now = new Timestamp(System.currentTimeMillis()); - jt.update(configInfoMapper.update(Arrays - .asList("content", "md5", "src_ip", "src_user", "gmt_modified", "app_name", "c_desc", "c_use", + jt.update(configInfoMapper.update( + Arrays.asList("content", "md5", "src_ip", "src_user", "gmt_modified", "app_name", "c_desc", "c_use", "effect", "type", "c_schema", "encrypted_data_key"), - Arrays.asList("data_id", "group_id", "tenant_id")), configInfo.getContent(), md5Tmp, srcIp, srcUser, + Arrays.asList("data_id", "group_id", "tenant_id")), configInfo.getContent(), md5Tmp, srcIp, srcUser, now, appNameTmp, desc, use, effect, type, schema, encryptedDataKey, configInfo.getDataId(), configInfo.getGroup(), tenantTmp); } catch (CannotGetJdbcConnectionException e) { @@ -684,25 +672,10 @@ public void updateConfigInfoAtomic(final ConfigInfo configInfo, final String src } } - @Override - public void updateMd5(String dataId, String group, String tenant, String md5, Timestamp lastTime) { - String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - try { - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); - jt.update(configInfoMapper.update(Collections.singletonList("md5"), - Arrays.asList("data_id", "group_id", "tenant_id", "gmt_modified")), md5, dataId, group, tenantTmp, - lastTime); - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } - } - @Override public long findConfigMaxId() { - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO); MapperResult mapperResult = configInfoMapper.findConfigMaxId(null); try { @@ -712,50 +685,14 @@ public long findConfigMaxId() { } } - @Deprecated - @Override - public List findAllDataIdAndGroup() { - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); - MapperResult mapperResult = configInfoMapper.findAllDataIdAndGroup(null); - - try { - return jt.query(mapperResult.getSql(), new Object[] {}, CONFIG_INFO_ROW_MAPPER); - } catch (EmptyResultDataAccessException e) { - return Collections.emptyList(); - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } catch (Exception e) { - LogUtil.FATAL_LOG.error("[db-other-error]" + e.getMessage(), e); - throw new RuntimeException(e); - } - } - - @Override - public ConfigInfoBase findConfigInfoBase(final String dataId, final String group) { - try { - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); - return this.jt.queryForObject(configInfoMapper.select(Arrays.asList("id", "data_id", "group_id", "content"), - Arrays.asList("data_id", "group_id", "tenant_id")), new Object[] {dataId, group, StringUtils.EMPTY}, - CONFIG_INFO_BASE_ROW_MAPPER); - } catch (EmptyResultDataAccessException e) { // Indicates that the data does not exist, returns null. - return null; - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } - } - @Override public ConfigInfo findConfigInfo(long id) { try { - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); - return this.jt.queryForObject(configInfoMapper - .select(Arrays.asList("id", "data_id", "group_id", "tenant_id", "app_name", "content"), - Collections.singletonList("id")), new Object[] {id}, CONFIG_INFO_ROW_MAPPER); + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO); + return this.jt.queryForObject(configInfoMapper.select( + Arrays.asList("id", "data_id", "group_id", "tenant_id", "app_name", "content"), + Collections.singletonList("id")), new Object[] {id}, CONFIG_INFO_ROW_MAPPER); } catch (EmptyResultDataAccessException e) { // Indicates that the data does not exist, returns null. return null; } catch (CannotGetJdbcConnectionException e) { @@ -768,10 +705,10 @@ public ConfigInfo findConfigInfo(long id) { public ConfigInfoWrapper findConfigInfo(final String dataId, final String group, final String tenant) { final String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; try { - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); - return this.jt.queryForObject(configInfoMapper.select(Arrays - .asList("id", "data_id", "group_id", "tenant_id", "app_name", "content", "md5", "type", + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO); + return this.jt.queryForObject(configInfoMapper.select( + Arrays.asList("id", "data_id", "group_id", "tenant_id", "app_name", "content", "md5", "type", "encrypted_data_key", "gmt_modified"), Arrays.asList("data_id", "group_id", "tenant_id")), new Object[] {dataId, group, tenantTmp}, CONFIG_INFO_WRAPPER_ROW_MAPPER); } catch (EmptyResultDataAccessException e) { // Indicates that the data does not exist, returns null. @@ -813,14 +750,14 @@ public Page findConfigInfo4Page(final int pageNo, final int pageSize if (StringUtils.isNotBlank(configTags)) { String[] tagArr = configTags.split(","); - context.putWhereParameter(FieldConstant.TAG_ARR, Arrays.asList(tagArr)); - ConfigTagsRelationMapper configTagsRelationMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_TAGS_RELATION); + context.putWhereParameter(FieldConstant.TAG_ARR, tagArr); + ConfigTagsRelationMapper configTagsRelationMapper = mapperManager.findMapper( + dataSourceService.getDataSourceType(), TableConstant.CONFIG_TAGS_RELATION); sqlCount = configTagsRelationMapper.findConfigInfo4PageCountRows(context); sql = configTagsRelationMapper.findConfigInfo4PageFetchRows(context); } else { - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO); sqlCount = configInfoMapper.findConfigInfo4PageCountRows(context); sql = configInfoMapper.findConfigInfo4PageFetchRows(context); @@ -828,9 +765,8 @@ public Page findConfigInfo4Page(final int pageNo, final int pageSize try { Page page = helper.fetchPageLimit(sqlCount, sql, pageNo, pageSize, CONFIG_INFO_ROW_MAPPER); for (ConfigInfo configInfo : page.getPageItems()) { - Pair pair = EncryptionHandler - .decryptHandler(configInfo.getDataId(), configInfo.getEncryptedDataKey(), - configInfo.getContent()); + Pair pair = EncryptionHandler.decryptHandler(configInfo.getDataId(), + configInfo.getEncryptedDataKey(), configInfo.getContent()); configInfo.setContent(pair.getSecond()); } return page; @@ -840,55 +776,10 @@ public Page findConfigInfo4Page(final int pageNo, final int pageSize } } - @Override - public Page findConfigInfoByApp(final int pageNo, final int pageSize, final String tenant, - final String appName) { - String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - PaginationHelper helper = createPaginationHelper(); - try { - final int startRow = (pageNo - 1) * pageSize; - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); - MapperContext context = new MapperContext(startRow, pageSize); - context.putWhereParameter(FieldConstant.APP_NAME, appName); - context.putWhereParameter(FieldConstant.TENANT_ID, generateLikeArgument(tenantTmp)); - - MapperResult countRows = configInfoMapper.findConfigInfoByAppCountRows(context); - MapperResult fetchRows = configInfoMapper.findConfigInfoByAppFetchRows(context); - - return helper.fetchPageLimit(countRows, fetchRows, pageNo, pageSize, CONFIG_INFO_ROW_MAPPER); - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } - } - - @Override - public Page findConfigInfoBaseByGroup(final int pageNo, final int pageSize, final String group) { - PaginationHelper helper = createPaginationHelper(); - try { - final int startRow = (pageNo - 1) * pageSize; - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); - - MapperContext context = new MapperContext(startRow, pageSize); - context.putWhereParameter(FieldConstant.GROUP_ID, group); - context.putWhereParameter(FieldConstant.TENANT_ID, StringUtils.EMPTY); - MapperResult mapperResult = configInfoMapper.findConfigInfoBaseByGroupFetchRows(context); - - return helper - .fetchPage(configInfoMapper.count(Arrays.asList("group_id", "tenant_id")), mapperResult.getSql(), - mapperResult.getParamList().toArray(), pageNo, pageSize, CONFIG_INFO_BASE_ROW_MAPPER); - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } - } - @Override public int configInfoCount() { - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO); String sql = configInfoMapper.count(null); Integer result = jt.queryForObject(sql, Integer.class); if (result == null) { @@ -899,8 +790,8 @@ public int configInfoCount() { @Override public int configInfoCount(String tenant) { - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO); MapperContext context = new MapperContext(); context.putWhereParameter(FieldConstant.TENANT_ID, tenant); MapperResult mapperResult = configInfoMapper.configInfoLikeTenantCount(context); @@ -913,8 +804,8 @@ public int configInfoCount(String tenant) { @Override public List getTenantIdList(int page, int pageSize) { - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO); int from = (page - 1) * pageSize; MapperResult mapperResult = configInfoMapper.getTenantIdList(new MapperContext(from, pageSize)); return jt.queryForList(mapperResult.getSql(), mapperResult.getParamList().toArray(), String.class); @@ -922,79 +813,17 @@ public List getTenantIdList(int page, int pageSize) { @Override public List getGroupIdList(int page, int pageSize) { - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO); int from = (page - 1) * pageSize; MapperResult mapperResult = configInfoMapper.getGroupIdList(new MapperContext(from, pageSize)); return jt.queryForList(mapperResult.getSql(), mapperResult.getParamList().toArray(), String.class); } - @Override - public Page findAllConfigInfo(final int pageNo, final int pageSize, final String tenant) { - String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - final int startRow = (pageNo - 1) * pageSize; - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); - String sqlCountRows = configInfoMapper.count(null); - MapperContext context = new MapperContext(startRow, pageSize); - context.putWhereParameter(FieldConstant.TENANT_ID, generateLikeArgument(generateLikeArgument(tenantTmp))); - MapperResult sqlFetchRows = configInfoMapper.findAllConfigInfoFetchRows(context); - PaginationHelper helper = createPaginationHelper(); - try { - return helper - .fetchPageLimit(sqlCountRows, sqlFetchRows.getSql(), sqlFetchRows.getParamList().toArray(), pageNo, - pageSize, CONFIG_INFO_ROW_MAPPER); - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } - } - - @Override - public Page findAllConfigKey(final int pageNo, final int pageSize, final String tenant) { - String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); - int startRow = (pageNo - 1) * pageSize; - MapperContext context = new MapperContext(startRow, pageSize); - context.putWhereParameter(FieldConstant.TENANT_ID, generateLikeArgument(tenantTmp)); - final MapperResult mapperResult = configInfoMapper.findAllConfigKey(context); - - final int totalCount = configInfoCount(tenant); - int pageCount = totalCount / pageSize; - if (totalCount > pageSize * pageCount) { - pageCount++; - } - - if (pageNo > pageCount) { - return null; - } - - final Page page = new Page<>(); - page.setPageNumber(pageNo); - page.setPagesAvailable(pageCount); - page.setTotalCount(totalCount); - - try { - List result = jt - .query(mapperResult.getSql(), mapperResult.getParamList().toArray(), CONFIG_KEY_ROW_MAPPER); - - for (ConfigKey item : result) { - page.getPageItems().add(item); - } - return page; - } catch (EmptyResultDataAccessException e) { - return page; - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } - } - @Override public Page findAllConfigInfoFragment(final long lastMaxId, final int pageSize) { - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO); MapperContext context = new MapperContext(0, pageSize); context.putWhereParameter(FieldConstant.ID, lastMaxId); MapperResult select = configInfoMapper.findAllConfigInfoFragment(context); @@ -1008,105 +837,6 @@ public Page findAllConfigInfoFragment(final long lastMaxId, f } } - @Override - public Page findConfigInfoLike(final int pageNo, final int pageSize, final ConfigKey[] configKeys, - final boolean blacklist) { - String sqlCountRows = "SELECT count(*) FROM config_info WHERE "; - String sqlFetchRows = "SELECT id,data_id,group_id,tenant_id,app_name,content FROM config_info WHERE "; - StringBuilder where = new StringBuilder(" 1=1 "); - // Whitelist, please leave the synchronization condition empty, there is no configuration that meets the conditions - if (configKeys.length == 0 && blacklist == false) { - Page page = new Page<>(); - page.setTotalCount(0); - return page; - } - PaginationHelper helper = createPaginationHelper(); - List params = new ArrayList<>(); - boolean isFirst = true; - for (ConfigKey configInfo : configKeys) { - String dataId = configInfo.getDataId(); - String group = configInfo.getGroup(); - String appName = configInfo.getAppName(); - - if (StringUtils.isBlank(dataId) && StringUtils.isBlank(group) && StringUtils.isBlank(appName)) { - break; - } - - if (blacklist) { - if (isFirst) { - isFirst = false; - where.append(" AND "); - } else { - where.append(" AND "); - } - - where.append('('); - boolean isFirstSub = true; - if (!StringUtils.isBlank(dataId)) { - where.append(" data_id NOT LIKE ? "); - params.add(generateLikeArgument(dataId)); - isFirstSub = false; - } - if (!StringUtils.isBlank(group)) { - if (!isFirstSub) { - where.append(" OR "); - } - where.append(" group_id NOT LIKE ? "); - params.add(generateLikeArgument(group)); - isFirstSub = false; - } - if (!StringUtils.isBlank(appName)) { - if (!isFirstSub) { - where.append(" OR "); - } - where.append(" app_name != ? "); - params.add(appName); - isFirstSub = false; - } - where.append(") "); - } else { - if (isFirst) { - isFirst = false; - where.append(" AND "); - } else { - where.append(" OR "); - } - where.append('('); - boolean isFirstSub = true; - if (!StringUtils.isBlank(dataId)) { - where.append(" data_id LIKE ? "); - params.add(generateLikeArgument(dataId)); - isFirstSub = false; - } - if (!StringUtils.isBlank(group)) { - if (!isFirstSub) { - where.append(" AND "); - } - where.append(" group_id LIKE ? "); - params.add(generateLikeArgument(group)); - isFirstSub = false; - } - if (!StringUtils.isBlank(appName)) { - if (!isFirstSub) { - where.append(" AND "); - } - where.append(" app_name = ? "); - params.add(appName); - isFirstSub = false; - } - where.append(") "); - } - } - - try { - return helper.fetchPage(sqlCountRows + where, sqlFetchRows + where, params.toArray(), pageNo, pageSize, - CONFIG_INFO_ROW_MAPPER); - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } - } - @Override public Page findConfigInfoLike4Page(final int pageNo, final int pageSize, final String dataId, final String group, final String tenant, final Map configAdvanceInfo) { @@ -1137,25 +867,24 @@ public Page findConfigInfoLike4Page(final int pageNo, final int page if (StringUtils.isNotBlank(configTags)) { String[] tagArr = configTags.split(","); context.putWhereParameter(FieldConstant.TAG_ARR, tagArr); - ConfigTagsRelationMapper configTagsRelationMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_TAGS_RELATION); + ConfigTagsRelationMapper configTagsRelationMapper = mapperManager.findMapper( + dataSourceService.getDataSourceType(), TableConstant.CONFIG_TAGS_RELATION); sqlCountRows = configTagsRelationMapper.findConfigInfoLike4PageCountRows(context); sqlFetchRows = configTagsRelationMapper.findConfigInfoLike4PageFetchRows(context); } else { - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO); sqlCountRows = configInfoMapper.findConfigInfoLike4PageCountRows(context); sqlFetchRows = configInfoMapper.findConfigInfoLike4PageFetchRows(context); } try { - Page page = helper - .fetchPageLimit(sqlCountRows, sqlFetchRows, pageNo, pageSize, CONFIG_INFO_ROW_MAPPER); + Page page = helper.fetchPageLimit(sqlCountRows, sqlFetchRows, pageNo, pageSize, + CONFIG_INFO_ROW_MAPPER); for (ConfigInfo configInfo : page.getPageItems()) { - Pair pair = EncryptionHandler - .decryptHandler(configInfo.getDataId(), configInfo.getEncryptedDataKey(), - configInfo.getContent()); + Pair pair = EncryptionHandler.decryptHandler(configInfo.getDataId(), + configInfo.getEncryptedDataKey(), configInfo.getContent()); configInfo.setContent(pair.getSecond()); } return page; @@ -1165,42 +894,11 @@ public Page findConfigInfoLike4Page(final int pageNo, final int page } } - @Override - public Page findConfigInfoBaseLike(final int pageNo, final int pageSize, final String dataId, - final String group, final String content) throws IOException { - if (StringUtils.isBlank(dataId) && StringUtils.isBlank(group)) { - throw new IOException("invalid param"); - } - MapperContext context = new MapperContext((pageNo - 1) * pageSize, pageSize); - - if (!StringUtils.isBlank(dataId)) { - context.putWhereParameter(FieldConstant.DATA_ID, generateLikeArgument(dataId)); - } - if (!StringUtils.isBlank(group)) { - context.putWhereParameter(FieldConstant.GROUP_ID, generateLikeArgument(group)); - } - if (!StringUtils.isBlank(content)) { - context.putWhereParameter(FieldConstant.CONTENT, generateLikeArgument(content)); - } - - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); - MapperResult sqlCountRows = configInfoMapper.findConfigInfoBaseLikeCountRows(context); - MapperResult sqlFetchRows = configInfoMapper.findConfigInfoBaseLikeFetchRows(context); - PaginationHelper helper = createPaginationHelper(); - try { - return helper.fetchPageLimit(sqlCountRows, sqlFetchRows, pageNo, pageSize, CONFIG_INFO_BASE_ROW_MAPPER); - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } - } - @Override public List findChangeConfig(final Timestamp startTime, long lastMaxId, final int pageSize) { try { - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO); MapperContext context = new MapperContext(); context.putWhereParameter(FieldConstant.START_TIME, startTime); @@ -1208,64 +906,20 @@ public List findChangeConfig(final Timestamp startTime, long context.putWhereParameter(FieldConstant.LAST_MAX_ID, lastMaxId); MapperResult mapperResult = configInfoMapper.findChangeConfig(context); - List> list = jt - .queryForList(mapperResult.getSql(), mapperResult.getParamList().toArray()); - return convertChangeConfig(list); + return jt.query(mapperResult.getSql(), mapperResult.getParamList().toArray(), + CONFIG_INFO_WRAPPER_ROW_MAPPER); } catch (DataAccessException e) { LogUtil.FATAL_LOG.error("[db-error] " + e, e); throw e; } } - @Override - public Page findChangeConfig(final String dataId, final String group, final String tenant, - final String appName, final Timestamp startTime, final Timestamp endTime, final int pageNo, - final int pageSize, final long lastMaxId) { - String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - - MapperContext context = new MapperContext((pageNo - 1) * pageSize, pageSize); - if (!StringUtils.isBlank(dataId)) { - context.putWhereParameter(FieldConstant.DATA_ID, generateLikeArgument(dataId)); - } - if (!StringUtils.isBlank(group)) { - context.putWhereParameter(FieldConstant.GROUP_ID, generateLikeArgument(group)); - } - - if (!StringUtils.isBlank(tenantTmp)) { - context.putWhereParameter(FieldConstant.TENANT, tenantTmp); - } - - if (!StringUtils.isBlank(appName)) { - context.putWhereParameter(FieldConstant.APP_NAME, appName); - } - if (startTime != null) { - context.putWhereParameter(FieldConstant.START_TIME, startTime); - } - if (endTime != null) { - context.putWhereParameter(FieldConstant.END_TIME, endTime); - } - - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); - MapperResult sqlCountRows = configInfoMapper.findChangeConfigCountRows(context); - MapperResult sqlFetchRows = configInfoMapper.findChangeConfigFetchRows(context); - - PaginationHelper helper = createPaginationHelper(); - try { - return helper.fetchPageLimit(sqlCountRows, sqlFetchRows, pageNo, pageSize, CONFIG_INFO_WRAPPER_ROW_MAPPER); - - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } - } - @Override public List selectTagByConfig(String dataId, String group, String tenant) { - ConfigTagsRelationMapper configTagsRelationMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_TAGS_RELATION); - String sql = configTagsRelationMapper - .select(Collections.singletonList("tag_name"), Arrays.asList("data_id", "group_id", "tenant_id")); + ConfigTagsRelationMapper configTagsRelationMapper = mapperManager.findMapper( + dataSourceService.getDataSourceType(), TableConstant.CONFIG_TAGS_RELATION); + String sql = configTagsRelationMapper.select(Collections.singletonList("tag_name"), + Arrays.asList("data_id", "group_id", "tenant_id")); try { return jt.queryForList(sql, new Object[] {dataId, group, tenant}, String.class); } catch (EmptyResultDataAccessException e) { @@ -1288,8 +942,8 @@ public List findConfigInfosByIds(final String ids) { for (int i = 0; i < idArr.length; i++) { paramList.add(Long.parseLong(idArr[i])); } - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO); MapperContext context = new MapperContext(); context.putWhereParameter(FieldConstant.IDS, paramList); MapperResult mapperResult = configInfoMapper.findConfigInfosByIds(context); @@ -1309,11 +963,11 @@ public ConfigAdvanceInfo findConfigAdvanceInfo(final String dataId, final String final String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; try { List configTagList = this.selectTagByConfig(dataId, group, tenant); - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); - ConfigAdvanceInfo configAdvance = this.jt.queryForObject(configInfoMapper.select(Arrays - .asList("gmt_create", "gmt_modified", "src_user", "src_ip", "c_desc", "c_use", "effect", "type", - "c_schema"), Arrays.asList("data_id", "group_id", "tenant_id")), + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO); + ConfigAdvanceInfo configAdvance = this.jt.queryForObject(configInfoMapper.select( + Arrays.asList("gmt_create", "gmt_modified", "src_user", "src_ip", "c_desc", "c_use", "effect", + "type", "c_schema"), Arrays.asList("data_id", "group_id", "tenant_id")), new Object[] {dataId, group, tenantTmp}, CONFIG_ADVANCE_INFO_ROW_MAPPER); if (configTagList != null && !configTagList.isEmpty()) { StringBuilder configTagsTmp = new StringBuilder(); @@ -1340,10 +994,10 @@ public ConfigAllInfo findConfigAllInfo(final String dataId, final String group, final String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; try { List configTagList = this.selectTagByConfig(dataId, group, tenant); - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); - ConfigAllInfo configAdvance = this.jt.queryForObject(configInfoMapper.select(Arrays - .asList("id", "data_id", "group_id", "tenant_id", "app_name", "content", "md5", "gmt_create", + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO); + ConfigAllInfo configAdvance = this.jt.queryForObject(configInfoMapper.select( + Arrays.asList("id", "data_id", "group_id", "tenant_id", "app_name", "content", "md5", "gmt_create", "gmt_modified", "src_user", "src_ip", "c_desc", "c_use", "effect", "type", "c_schema", "encrypted_data_key"), Arrays.asList("data_id", "group_id", "tenant_id")), new Object[] {dataId, group, tenantTmp}, CONFIG_ALL_INFO_ROW_MAPPER); @@ -1367,78 +1021,6 @@ public ConfigAllInfo findConfigAllInfo(final String dataId, final String group, } } - @Override - public List convertDeletedConfig(List> list) { - List configs = new ArrayList<>(); - for (Map map : list) { - String dataId = (String) map.get("data_id"); - String group = (String) map.get("group_id"); - String tenant = (String) map.get("tenant_id"); - ConfigInfo config = new ConfigInfo(); - config.setDataId(dataId); - config.setGroup(group); - config.setTenant(tenant); - configs.add(config); - } - return configs; - } - - @Override - public List convertChangeConfig(List> list) { - List configs = new ArrayList<>(); - for (Map map : list) { - Long id = ((java.lang.Number) map.get("id")).longValue(); - String dataId = (String) map.get("data_id"); - String group = (String) map.get("group_id"); - String tenant = (String) map.get("tenant_id"); - String md5 = (String) map.get("md5"); - long mTime = ((LocalDateTime) map.get("gmt_modified")).toInstant(ZoneOffset.ofHours(8)).toEpochMilli(); - ConfigInfoWrapper config = new ConfigInfoWrapper(); - config.setId(id); - config.setDataId(dataId); - config.setGroup(group); - config.setMd5(md5); - config.setTenant(tenant); - config.setLastModified(mTime); - configs.add(config); - } - return configs; - } - - @Override - public List listAllGroupKeyMd5() { - final int pageSize = 10000; - int totalCount = configInfoCount(); - int pageCount = (int) Math.ceil(totalCount * 1.0 / pageSize); - List allConfigInfo = new ArrayList<>(); - for (int pageNo = 1; pageNo <= pageCount; pageNo++) { - List configInfoList = listGroupKeyMd5ByPage(pageNo, pageSize); - allConfigInfo.addAll(configInfoList); - } - return allConfigInfo; - } - - @Override - public List listGroupKeyMd5ByPage(int pageNo, int pageSize) { - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); - String sqlCountRows = configInfoMapper.count(null); - MapperContext context = new MapperContext((pageNo - 1) * pageSize, pageSize); - - MapperResult sqlFetchRows = configInfoMapper.listGroupKeyMd5ByPageFetchRows(context); - PaginationHelper helper = createPaginationHelper(); - try { - Page page = helper - .fetchPageLimit(sqlCountRows, sqlFetchRows.getSql(), sqlFetchRows.getParamList().toArray(), pageNo, - pageSize, CONFIG_INFO_WRAPPER_ROW_MAPPER); - - return page.getPageItems(); - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } - } - @Override public ConfigInfoStateWrapper findConfigInfoState(final String dataId, final String group, final String tenant) { String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; @@ -1454,30 +1036,12 @@ public ConfigInfoStateWrapper findConfigInfoState(final String dataId, final Str } } - @Override - public ConfigInfoWrapper queryConfigInfo(final String dataId, final String group, final String tenant) { - String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - try { - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); - return this.jt.queryForObject(configInfoMapper.select(Arrays - .asList("id", "data_id", "group_id", "tenant_id", "app_name", "content", "type", "gmt_modified", - "md5", "encrypted_data_key"), Arrays.asList("data_id", "group_id", "tenant_id")), - new Object[] {dataId, group, tenantTmp}, CONFIG_INFO_WRAPPER_ROW_MAPPER); - } catch (EmptyResultDataAccessException e) { - return null; - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } - } - @Override public List findAllConfigInfo4Export(final String dataId, final String group, final String tenant, final String appName, final List ids) { String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO); MapperContext context = new MapperContext(); if (!CollectionUtils.isEmpty(ids)) { context.putWhereParameter(FieldConstant.IDS, ids); @@ -1495,8 +1059,8 @@ public List findAllConfigInfo4Export(final String dataId, final S } MapperResult mapperResult = configInfoMapper.findAllConfigInfo4Export(context); try { - return this.jt - .query(mapperResult.getSql(), mapperResult.getParamList().toArray(), CONFIG_ALL_INFO_ROW_MAPPER); + return this.jt.query(mapperResult.getSql(), mapperResult.getParamList().toArray(), + CONFIG_ALL_INFO_ROW_MAPPER); } catch (CannotGetJdbcConnectionException e) { LogUtil.FATAL_LOG.error("[db-error] " + e, e); throw e; @@ -1510,11 +1074,11 @@ public List queryConfigInfoByNamespace(String tenant) { } String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; try { - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); - return this.jt.query(configInfoMapper - .select(Arrays.asList("data_id", "group_id", "tenant_id", "app_name", "type"), - Collections.singletonList("tenant_id")), new Object[] {tenantTmp}, + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO); + return this.jt.query( + configInfoMapper.select(Arrays.asList("data_id", "group_id", "tenant_id", "app_name", "type"), + Collections.singletonList("tenant_id")), new Object[] {tenantTmp}, CONFIG_INFO_WRAPPER_ROW_MAPPER); } catch (EmptyResultDataAccessException e) { // Indicates that the data does not exist, returns null. return Collections.EMPTY_LIST; @@ -1524,25 +1088,4 @@ public List queryConfigInfoByNamespace(String tenant) { } } - @Override - @Deprecated - public Page findAllConfigInfoBase(final int pageNo, final int pageSize) { - final int startRow = (pageNo - 1) * pageSize; - ConfigInfoMapper configInfoMapper = mapperManager - .findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); - String sqlCountRows = configInfoMapper.count(null); - MapperResult sqlFetchRows = configInfoMapper - .findAllConfigInfoBaseFetchRows(new MapperContext(startRow, pageSize)); - - PaginationHelper helper = createPaginationHelper(); - - try { - return helper - .fetchPageLimit(sqlCountRows, sqlFetchRows.getSql(), sqlFetchRows.getParamList().toArray(), pageNo, - pageSize, CONFIG_INFO_BASE_ROW_MAPPER); - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } - } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoTagPersistServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoTagPersistServiceImpl.java index d2e13db70e5..d304ede1b72 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoTagPersistServiceImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoTagPersistServiceImpl.java @@ -40,7 +40,6 @@ import com.alibaba.nacos.plugin.datasource.model.MapperResult; import com.alibaba.nacos.sys.env.EnvUtil; import org.springframework.context.annotation.Conditional; -import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.CannotGetJdbcConnectionException; import org.springframework.jdbc.core.JdbcTemplate; @@ -93,11 +92,14 @@ public ConfigInfoStateWrapper findConfigInfo4TagState(final String dataId, final ConfigInfoTagMapper configInfoTagMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO_TAG); String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - - return this.jt.queryForObject( - configInfoTagMapper.select(Arrays.asList("id", "data_id", "group_id", "tenant_id", "gmt_modified"), - Arrays.asList("data_id", "group_id", "tenant_id", "tag_id")), - new Object[] {dataId, group, tenantTmp, tag}, CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER); + try { + return this.jt.queryForObject( + configInfoTagMapper.select(Arrays.asList("id", "data_id", "group_id", "tenant_id", "gmt_modified"), + Arrays.asList("data_id", "group_id", "tenant_id", "tag_id")), + new Object[] {dataId, group, tenantTmp, tag}, CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER); + } catch (EmptyResultDataAccessException e) { + return null; + } } private ConfigOperateResult getTagOperateResult(String dataId, String group, String tenant, String tag) { @@ -137,9 +139,10 @@ public ConfigOperateResult addConfigInfo4Tag(ConfigInfo configInfo, String tag, @Override public ConfigOperateResult insertOrUpdateTag(final ConfigInfo configInfo, final String tag, final String srcIp, final String srcUser) { - try { + if (findConfigInfo4TagState(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant(), tag) + == null) { return addConfigInfo4Tag(configInfo, tag, srcIp, srcUser); - } catch (DataIntegrityViolationException ive) { // Unique constraint conflict + } else { return updateConfigInfo4Tag(configInfo, tag, srcIp, srcUser); } } @@ -147,9 +150,10 @@ public ConfigOperateResult insertOrUpdateTag(final ConfigInfo configInfo, final @Override public ConfigOperateResult insertOrUpdateTagCas(final ConfigInfo configInfo, final String tag, final String srcIp, final String srcUser) { - try { + if (findConfigInfo4TagState(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant(), tag) + == null) { return addConfigInfo4Tag(configInfo, tag, srcIp, srcUser); - } catch (DataIntegrityViolationException ive) { // Unique constraint conflict + } else { return updateConfigInfo4TagCas(configInfo, tag, srcIp, srcUser); } } @@ -259,7 +263,7 @@ public int configInfoTagCount() { String sql = configInfoTagMapper.count(null); Integer result = jt.queryForObject(sql, Integer.class); if (result == null) { - throw new IllegalArgumentException("configInfoBetaCount error"); + throw new IllegalArgumentException("configInfoTagCount error"); } return result; } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalHistoryConfigInfoPersistServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalHistoryConfigInfoPersistServiceImpl.java index baece006663..cc4560e9af9 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalHistoryConfigInfoPersistServiceImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalHistoryConfigInfoPersistServiceImpl.java @@ -40,6 +40,7 @@ import com.alibaba.nacos.sys.env.EnvUtil; import org.springframework.context.annotation.Conditional; import org.springframework.dao.DataAccessException; +import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.support.TransactionTemplate; @@ -136,7 +137,7 @@ public void removeConfigHistory(final Timestamp startTime, final int limitSize) HistoryConfigInfoMapper historyConfigInfoMapper = mapperManager.findMapper( dataSourceService.getDataSourceType(), TableConstant.HIS_CONFIG_INFO); MapperContext context = new MapperContext(); - context.putWhereParameter(FieldConstant.GMT_MODIFIED, startTime); + context.putWhereParameter(FieldConstant.START_TIME, startTime); context.putWhereParameter(FieldConstant.LIMIT_SIZE, limitSize); MapperResult mapperResult = historyConfigInfoMapper.removeConfigHistory(context); PaginationHelper paginationHelper = createPaginationHelper(); @@ -204,10 +205,13 @@ public ConfigHistoryInfo detailConfigHistory(Long nid) { ConfigHistoryInfo historyInfo = jt.queryForObject(sqlFetchRows, new Object[] {nid}, HISTORY_DETAIL_ROW_MAPPER); return historyInfo; + } catch (EmptyResultDataAccessException emptyResultDataAccessException) { + return null; } catch (DataAccessException e) { LogUtil.FATAL_LOG.error("[detail-config-history] error, nid:{}", new Object[] {nid}, e); throw e; } + } @Override @@ -221,6 +225,8 @@ public ConfigHistoryInfo detailPreviousConfigHistory(Long id) { ConfigHistoryInfo historyInfo = jt.queryForObject(sqlFetchRows.getSql(), sqlFetchRows.getParamList().toArray(), HISTORY_DETAIL_ROW_MAPPER); return historyInfo; + } catch (EmptyResultDataAccessException emptyResultDataAccessException) { + return null; } catch (DataAccessException e) { LogUtil.FATAL_LOG.error("[detail-previous-config-history] error, id:{}", new Object[] {id}, e); throw e; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/utils/DiskUtil.java b/config/src/main/java/com/alibaba/nacos/config/server/utils/DiskUtil.java deleted file mode 100644 index 10c881c0638..00000000000 --- a/config/src/main/java/com/alibaba/nacos/config/server/utils/DiskUtil.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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.config.server.utils; - -import com.alibaba.nacos.config.server.constant.Constants; -import com.alibaba.nacos.sys.env.EnvUtil; -import org.apache.commons.io.FileUtils; - -import java.io.File; -import java.io.IOException; - -/** - * Disk util. - * - * @author jiuRen - */ -public class DiskUtil { - - public static void saveHeartBeatToDisk(String heartBeatTime) throws IOException { - FileUtils.writeStringToFile(heartBeatFile(), heartBeatTime, Constants.ENCODE); - } - - public static void removeHeartHeat() { - FileUtils.deleteQuietly(heartBeatFile()); - } - - public static File heartBeatFile() { - return new File(EnvUtil.getNacosHome(), "status" + File.separator + "heartBeat.txt"); - } - -} diff --git a/config/src/test/java/com/alibaba/nacos/config/server/manager/TaskManagerTest.java b/config/src/test/java/com/alibaba/nacos/config/server/manager/TaskManagerTest.java index fc4f21f2282..7cd1000946b 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/manager/TaskManagerTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/manager/TaskManagerTest.java @@ -29,6 +29,7 @@ import javax.management.ObjectName; import java.lang.management.ManagementFactory; +import java.util.Date; import java.util.concurrent.TimeUnit; import static org.junit.Assert.assertEquals; @@ -119,7 +120,7 @@ public void testGetTaskInfos() throws InterruptedException { taskManager.addProcessor("test", testTaskProcessor); when(testTaskProcessor.process(abstractTask)).thenReturn(true); taskManager.addTask("test", abstractTask); - assertEquals("test:Thu Jan 01 08:00:00 CST 1970" + Constants.NACOS_LINE_SEPARATOR, taskManager.getTaskInfos()); + assertEquals("test:" + new Date(0) + Constants.NACOS_LINE_SEPARATOR, taskManager.getTaskInfos()); TimeUnit.MILLISECONDS.sleep(150); assertEquals("test:finished" + Constants.NACOS_LINE_SEPARATOR, taskManager.getTaskInfos()); } @@ -127,7 +128,8 @@ public void testGetTaskInfos() throws InterruptedException { @Test public void testInit() throws Exception { taskManager.init(); - ObjectName oName = new ObjectName(TaskManagerTest.class.getName() + ":type=" + TaskManager.class.getSimpleName()); + ObjectName oName = new ObjectName( + TaskManagerTest.class.getName() + ":type=" + TaskManager.class.getSimpleName()); assertTrue(ManagementFactory.getPlatformMBeanServer().isRegistered(oName)); } } diff --git a/config/src/test/java/com/alibaba/nacos/config/server/paramcheck/ConfigListenerHttpParamExtractorTest.java b/config/src/test/java/com/alibaba/nacos/config/server/paramcheck/ConfigListenerHttpParamExtractorTest.java new file mode 100644 index 00000000000..4576cbdeb63 --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/paramcheck/ConfigListenerHttpParamExtractorTest.java @@ -0,0 +1,118 @@ +/* + * Copyright 1999-2023 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.config.server.paramcheck; + +import com.alibaba.nacos.common.utils.StringUtils; +import com.alibaba.nacos.config.server.model.ConfigInfo; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +import javax.servlet.http.HttpServletRequest; +import java.util.Arrays; +import java.util.List; + +import static com.alibaba.nacos.api.common.Constants.LINE_SEPARATOR; +import static com.alibaba.nacos.api.common.Constants.WORD_SEPARATOR; +import static org.mockito.ArgumentMatchers.eq; + +@RunWith(MockitoJUnitRunner.class) + +public class ConfigListenerHttpParamExtractorTest { + + ConfigListenerHttpParamExtractor configListenerHttpParamExtractor; + + @Mock + HttpServletRequest httpServletRequest; + + @Test + public void testNormal() { + String listenerConfigsString = getListenerConfigsString(); + Mockito.when(httpServletRequest.getParameter(eq("Listening-Configs"))).thenReturn(listenerConfigsString); + configListenerHttpParamExtractor = new ConfigListenerHttpParamExtractor(); + configListenerHttpParamExtractor.extractParam(httpServletRequest); + } + + @Test + public void testError() { + String listenerConfigsString = getErrorListenerConfigsString(); + Mockito.when(httpServletRequest.getParameter(eq("Listening-Configs"))).thenReturn(listenerConfigsString); + configListenerHttpParamExtractor = new ConfigListenerHttpParamExtractor(); + try { + configListenerHttpParamExtractor.extractParam(httpServletRequest); + Assert.assertTrue(false); + } catch (Throwable throwable) { + throwable.printStackTrace(); + Assert.assertTrue(throwable instanceof IllegalArgumentException); + } + } + + private String getListenerConfigsString() { + ConfigInfo configInfo1 = new ConfigInfo(); + configInfo1.setDataId("2345678901"); + configInfo1.setGroup("1234445"); + configInfo1.setMd5("234567"); + configInfo1.setTenant("222345"); + ConfigInfo configInfo2 = new ConfigInfo(); + configInfo2.setDataId("2345678902"); + configInfo2.setGroup("1234445"); + configInfo2.setMd5(null); + configInfo2.setTenant(null); + ConfigInfo configInfo3 = new ConfigInfo(); + configInfo3.setDataId("2345678903"); + configInfo3.setGroup("1234445"); + configInfo3.setMd5("12345"); + configInfo3.setTenant(null); + ConfigInfo configInfo4 = new ConfigInfo(); + configInfo4.setDataId("234567844"); + configInfo4.setGroup("1234445"); + configInfo4.setMd5("12345"); + configInfo4.setTenant(null); + List configInfoList = Arrays.asList(configInfo4, configInfo3, configInfo2, configInfo1); + StringBuilder sb = new StringBuilder(); + for (ConfigInfo configInfo : configInfoList) { + sb.append(configInfo.getDataId()).append(WORD_SEPARATOR); + sb.append(configInfo.getGroup()).append(WORD_SEPARATOR); + if (StringUtils.isBlank(configInfo.getTenant())) { + sb.append(configInfo.getMd5()).append(LINE_SEPARATOR); + } else { + sb.append(configInfo.getMd5()).append(WORD_SEPARATOR); + sb.append(configInfo.getTenant()).append(LINE_SEPARATOR); + } + } + + return sb.toString(); + + } + + private String getErrorListenerConfigsString() { + ConfigInfo configInfo1 = new ConfigInfo(); + configInfo1.setDataId("2345678901"); + + List configInfoList = Arrays.asList(configInfo1); + StringBuilder sb = new StringBuilder(); + for (ConfigInfo configInfo : configInfoList) { + sb.append(configInfo.getDataId()).append(WORD_SEPARATOR); + } + + return sb.toString(); + + } +} \ No newline at end of file diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/ConfigSubServiceTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/ConfigSubServiceTest.java new file mode 100644 index 00000000000..a83cc60f358 --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/ConfigSubServiceTest.java @@ -0,0 +1,303 @@ +/* + * Copyright 1999-2022 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.config.server.service; + +import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException; +import com.alibaba.nacos.common.http.HttpRestResult; +import com.alibaba.nacos.common.http.client.NacosAsyncRestTemplate; +import com.alibaba.nacos.common.http.client.NacosRestTemplate; +import com.alibaba.nacos.common.http.param.Header; +import com.alibaba.nacos.common.http.param.Query; +import com.alibaba.nacos.common.utils.JacksonUtils; +import com.alibaba.nacos.config.server.model.ListenerCheckResult; +import com.alibaba.nacos.config.server.model.SampleResult; +import com.alibaba.nacos.config.server.service.notify.HttpClientManager; +import com.alibaba.nacos.core.cluster.Member; +import com.alibaba.nacos.core.cluster.ServerMemberManager; +import com.alibaba.nacos.sys.env.EnvUtil; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletionService; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; + +@RunWith(SpringJUnit4ClassRunner.class) +public class ConfigSubServiceTest { + + private ConfigSubService configSubService; + + @Mock + ServerMemberManager serverMemberManager; + + MockedStatic envUtilMockedStatic; + + MockedStatic httpClientManagerMockedStatic; + + @Mock + NacosRestTemplate nacosRestTemplate; + + @Mock + NacosAsyncRestTemplate nacosAsyncRestTemplate; + + @Before + public void startUP() { + + httpClientManagerMockedStatic = Mockito.mockStatic(HttpClientManager.class); + envUtilMockedStatic = Mockito.mockStatic(EnvUtil.class); + configSubService = new ConfigSubService(serverMemberManager); + envUtilMockedStatic.when(() -> EnvUtil.getContextPath()).thenReturn("/nacos"); + envUtilMockedStatic.when(() -> EnvUtil.getProperty(anyString(), anyString())).thenReturn("mock string"); + EnvUtil.setContextPath("/nacos"); + httpClientManagerMockedStatic.when(() -> HttpClientManager.getNacosRestTemplate()) + .thenReturn(nacosRestTemplate); + httpClientManagerMockedStatic.when(() -> HttpClientManager.getNacosAsyncRestTemplate()) + .thenReturn(nacosAsyncRestTemplate); + } + + @After + public void after() { + if (!envUtilMockedStatic.isClosed()) { + envUtilMockedStatic.close(); + } + httpClientManagerMockedStatic.close(); + } + + @Test + public void testGetCollectSampleResult() throws Exception { + envUtilMockedStatic.close(); + EnvUtil.setContextPath("/nacos"); + ConfigurableEnvironment environment = Mockito.mock(ConfigurableEnvironment.class); + EnvUtil.setEnvironment(environment); + Mockito.when(environment.getProperty(anyString(), anyString())).thenReturn("/nacos"); + + Map mockedMembers = new HashMap<>(); + mockedMembers.put("127.0.0.1", createMember("127.0.0.1")); + mockedMembers.put("127.0.0.2", createMember("127.0.0.2")); + mockedMembers.put("127.0.0.3", createMember("127.0.0.3")); + //mock server member + Mockito.when(serverMemberManager.allMembers()).thenReturn(mockedMembers.values()); + Mockito.when(serverMemberManager.getServerList()).thenReturn(mockedMembers); + String dataId = "dataid1234"; + String group = "group34567"; + String tenant = "tenant456789"; + int sampleTimes = 3; + //cant mock static method cross thread,so cant verify return obj here. + configSubService.getCollectSampleResult(dataId, group, tenant, sampleTimes); + configSubService.getCollectSampleResultByIp("127.0.0.1", 3); + configSubService.getCheckHasListenerResult(dataId, group, tenant, 3); + } + + @Test + public void testRunSingleJob() throws Exception { + Map params = new HashMap<>(); + params.put("dataId", "d1"); + params.put("group", "g1"); + params.put("tenant", "t1"); + + HttpRestResult httpRestResult = new HttpRestResult<>(); + httpRestResult.setCode(200); + httpRestResult.setMessage("success"); + + SampleResult sampleResult1 = new SampleResult(); + Map listener1 = new HashMap<>(); + listener1.put("config1", "md51123"); + listener1.put("config11", "md5123123"); + sampleResult1.setLisentersGroupkeyStatus(listener1); + String mockJsonString = JacksonUtils.toJson(sampleResult1); + httpRestResult.setData(mockJsonString); + //mock success + Mockito.when(nacosRestTemplate.get(anyString(), any(Header.class), eq(Query.EMPTY), eq(String.class))) + .thenReturn(httpRestResult); + String url = "url"; + SampleResult returnObj = (SampleResult) ConfigSubService.runSingleJob("127.0.0.1", params, url, + SampleResult.class); + Assert.assertEquals(sampleResult1.getLisentersGroupkeyStatus(), returnObj.getLisentersGroupkeyStatus()); + //mock fail response + httpRestResult.setCode(500); + Mockito.when(nacosRestTemplate.get(anyString(), any(Header.class), eq(Query.EMPTY), eq(String.class))) + .thenReturn(httpRestResult); + SampleResult returnObj500 = (SampleResult) ConfigSubService.runSingleJob("127.0.0.1", params, url, + SampleResult.class); + Assert.assertEquals(null, returnObj500); + + //mock get url throw exception + Mockito.when(nacosRestTemplate.get(anyString(), any(Header.class), eq(Query.EMPTY), eq(String.class))) + .thenThrow(new NacosRuntimeException(500, "timeout")); + SampleResult returnObjTimeout = (SampleResult) ConfigSubService.runSingleJob("127.0.0.1", params, url, + SampleResult.class); + Assert.assertEquals(null, returnObjTimeout); + + } + + @Test + public void testClusterListenerJob() throws Exception { + Map mockedMembers = new HashMap<>(); + mockedMembers.put("127.0.0.1", createMember("127.0.0.1")); + mockedMembers.put("127.0.0.2", createMember("127.0.0.2")); + mockedMembers.put("127.0.0.3", createMember("127.0.0.3")); + //mock server member + Mockito.when(serverMemberManager.allMembers()).thenReturn(mockedMembers.values()); + Mockito.when(serverMemberManager.getServerList()).thenReturn(mockedMembers); + + CompletionService mockService = Mockito.mock(CompletionService.class); + //mock all success + Mockito.when(mockService.poll(anyLong(), any(TimeUnit.class))) + .thenReturn(createSampleResultFuture(true, true), createSampleResultFuture(true, true), + createSampleResultFuture(true, true)); + Map params = new HashMap<>(); + ConfigSubService.ClusterListenerJob clusterListenerJob = new ConfigSubService.ClusterListenerJob(params, + mockService, serverMemberManager); + List sampleResults = clusterListenerJob.runJobs(); + Assert.assertEquals(3, sampleResults.size()); + + //mock success with exception + Mockito.when(mockService.poll(anyLong(), any(TimeUnit.class))) + .thenReturn(createSampleResultFuture(true, true), createSampleResultFuture(false, false)) + .thenThrow(new NacosRuntimeException(500, "13")); + Map params2 = new HashMap<>(); + ConfigSubService.ClusterListenerJob clusterListenerJob2 = new ConfigSubService.ClusterListenerJob(params2, + mockService, serverMemberManager); + List sampleResults2 = clusterListenerJob2.runJobs(); + Assert.assertEquals(1, sampleResults2.size()); + Assert.assertEquals(false, sampleResults2.get(0).getLisentersGroupkeyStatus().isEmpty()); + + } + + @Test + public void testMergeSampleResult() throws Exception { + SampleResult sampleResult1 = new SampleResult(); + Map listener1 = new HashMap<>(); + listener1.put("config1", "md51123"); + listener1.put("config11", "md5123123"); + sampleResult1.setLisentersGroupkeyStatus(listener1); + SampleResult sampleResult2 = new SampleResult(); + Map listener2 = new HashMap<>(); + listener2.put("config22", "md51123"); + listener2.put("config2", "md5123123"); + sampleResult2.setLisentersGroupkeyStatus(listener2); + List sampleResults = new ArrayList<>(); + sampleResults.add(sampleResult2); + SampleResult sampleResult3 = new SampleResult(); + Map listener3 = new HashMap<>(); + listener3.put("config33", "md51123"); + listener3.put("config3", "md5123123"); + sampleResult3.setLisentersGroupkeyStatus(listener3); + sampleResults.add(sampleResult3); + //sampleResult ips is null + SampleResult sampleResultMerge1 = configSubService.mergeSampleResult(sampleResult1, sampleResults); + Assert.assertEquals(6, sampleResultMerge1.getLisentersGroupkeyStatus().size()); + + SampleResult sampleResultMerge2 = configSubService.mergeSampleResult(new SampleResult(), sampleResults); + Assert.assertEquals(4, sampleResultMerge2.getLisentersGroupkeyStatus().size()); + } + + @Test + public void testMergeListenerCheckResult() throws Exception { + ListenerCheckResult sampleResult2 = new ListenerCheckResult(); + sampleResult2.setHasListener(true); + sampleResult2.setCode(200); + List sampleResults = new ArrayList(); + sampleResults.add(sampleResult2); + ListenerCheckResult sampleResult3 = new ListenerCheckResult(); + sampleResult3.setHasListener(false); + sampleResult3.setCode(200); + sampleResults.add(sampleResult3); + ListenerCheckResult sampleResult1 = new ListenerCheckResult(); + //one ip return true + ListenerCheckResult sampleResultMerge1 = configSubService.mergeListenerCheckResult(sampleResult1, sampleResults, + 2); + Assert.assertEquals(200, sampleResultMerge1.getCode()); + Assert.assertEquals(true, sampleResultMerge1.isHasListener()); + //all ip return false,but not equals member size + sampleResult2.setHasListener(false); + sampleResult3.setHasListener(false); + sampleResult1.setHasListener(false); + ListenerCheckResult sampleResultMerge2 = configSubService.mergeListenerCheckResult(sampleResult1, sampleResults, + 3); + Assert.assertEquals(201, sampleResultMerge2.getCode()); + Assert.assertEquals(false, sampleResultMerge2.isHasListener()); + + } + + private Future createSampleResultFuture(boolean success, boolean lisentersGroupkeyStatus) { + Future future = new Future() { + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return false; + } + + @Override + public boolean isCancelled() { + return false; + } + + @Override + public boolean isDone() { + return success ? true : false; + } + + @Override + public SampleResult get() { + + return success ? createSampleResult() : null; + } + + @Override + public SampleResult get(long timeout, TimeUnit unit) { + return success ? createSampleResult() : null; + } + + SampleResult createSampleResult() { + SampleResult sampleResult = new SampleResult(); + if (lisentersGroupkeyStatus) { + Map listener = new HashMap<>(); + listener.put("config1", "md51123"); + listener.put("config2", "md5123123"); + sampleResult.setLisentersGroupkeyStatus(listener); + } + return sampleResult; + } + }; + return future; + } + + Member createMember(String ip) { + Member member = new Member(); + member.setIp(ip); + member.setPort(8848); + return member; + } +} diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpChangeConfigWorkerTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpChangeConfigWorkerTest.java new file mode 100644 index 00000000000..3ea6f2b3216 --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpChangeConfigWorkerTest.java @@ -0,0 +1,333 @@ +/* + * 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.config.server.service.dump; + +import com.alibaba.nacos.common.utils.MD5Utils; +import com.alibaba.nacos.config.server.model.ConfigInfoWrapper; +import com.alibaba.nacos.config.server.service.ConfigCacheService; +import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskService; +import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskServiceFactory; +import com.alibaba.nacos.config.server.service.dump.disk.ConfigRocksDbDiskService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; +import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService; +import com.alibaba.nacos.config.server.utils.GroupKey; +import com.alibaba.nacos.config.server.utils.PropertyUtil; +import com.alibaba.nacos.persistence.datasource.DataSourceService; +import com.alibaba.nacos.persistence.datasource.DynamicDataSource; +import com.alibaba.nacos.plugin.datasource.constants.CommonConstant; +import com.alibaba.nacos.sys.env.EnvUtil; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +import java.io.File; +import java.lang.reflect.Field; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class DumpChangeConfigWorkerTest { + + @Mock + DynamicDataSource dynamicDataSource; + + @Mock + DataSourceService dataSourceService; + + @Mock + ConfigInfoPersistService configInfoPersistService; + + @Mock + HistoryConfigInfoPersistService historyConfigInfoPersistService; + + DumpChangeConfigWorker dumpChangeConfigWorker; + + MockedStatic dynamicDataSourceMockedStatic; + + MockedStatic envUtilMockedStatic; + + @Before + public void init() throws Exception { + dynamicDataSourceMockedStatic = Mockito.mockStatic(DynamicDataSource.class); + envUtilMockedStatic = Mockito.mockStatic(EnvUtil.class); + when(EnvUtil.getNacosHome()).thenReturn(System.getProperty("user.home") + File.separator + "tmp"); + when(EnvUtil.getProperty(eq(CommonConstant.NACOS_PLUGIN_DATASOURCE_LOG), eq(Boolean.class), + eq(false))).thenReturn(false); + dynamicDataSourceMockedStatic.when(DynamicDataSource::getInstance).thenReturn(dynamicDataSource); + + Field[] declaredFields = ConfigDiskServiceFactory.class.getDeclaredFields(); + for (Field filed : declaredFields) { + if (filed.getName().equals("configDiskService")) { + filed.setAccessible(true); + filed.set(null, createDiskService()); + } + } + + dumpChangeConfigWorker = new DumpChangeConfigWorker(configInfoPersistService, historyConfigInfoPersistService, + new Timestamp(System.currentTimeMillis())); + } + + protected ConfigDiskService createDiskService() { + return new ConfigRocksDbDiskService(); + } + + @After + public void after() throws IllegalAccessException { + dynamicDataSourceMockedStatic.close(); + envUtilMockedStatic.close(); + ConfigDiskServiceFactory.getInstance().clearAll(); + ConfigDiskServiceFactory.getInstance().clearAllBatch(); + ConfigDiskServiceFactory.getInstance().clearAllBeta(); + ConfigDiskServiceFactory.getInstance().clearAllTag(); + + Field[] declaredFields = ConfigDiskServiceFactory.class.getDeclaredFields(); + for (Field filed : declaredFields) { + if (filed.getName().equals("configDiskService")) { + filed.setAccessible(true); + filed.set(null, null); + } + } + } + + @Test + public void testDumpChangeIfOff() { + PropertyUtil.setDumpChangeOn(false); + dumpChangeConfigWorker.run(); + Mockito.verify(historyConfigInfoPersistService, times(0)).findDeletedConfig(any(), anyLong(), anyInt()); + } + + @Test + public void testDumpChangeOfDeleteConfigs() { + PropertyUtil.setDumpChangeOn(true); + dumpChangeConfigWorker.setPageSize(3); + //mock delete first page + List firstPageDeleted = new ArrayList<>(); + Timestamp startTime = dumpChangeConfigWorker.startTime; + String dataIdPrefix = "d12345"; + + firstPageDeleted.add(createConfigInfoWrapper(dataIdPrefix, 1, startTime.getTime() + 1)); + firstPageDeleted.add(createConfigInfoWrapper(dataIdPrefix, 2, startTime.getTime() + 2)); + firstPageDeleted.add(createConfigInfoWrapper(dataIdPrefix, 3, startTime.getTime() + 3)); + //pre set cache for id1 + preSetCache(dataIdPrefix, 1, System.currentTimeMillis()); + Assert.assertEquals("encrykey" + 1, + ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataIdPrefix + 1, "group" + 1, "tenant" + 1)) + .getConfigCache().getEncryptedDataKey()); + Mockito.when(historyConfigInfoPersistService.findDeletedConfig(eq(startTime), eq(0L), eq(3))) + .thenReturn(firstPageDeleted); + //mock delete config query is null + Mockito.when( + configInfoPersistService.findConfigInfoState(eq(dataIdPrefix + 1), eq("group" + 1), eq("tenant" + 1))) + .thenReturn(null); + Mockito.when( + configInfoPersistService.findConfigInfoState(eq(dataIdPrefix + 2), eq("group" + 2), eq("tenant" + 2))) + .thenReturn(null); + dumpChangeConfigWorker.run(); + + //expect delete page return pagesize and will select second page + Mockito.verify(historyConfigInfoPersistService, times(1)).findDeletedConfig(eq(startTime), eq(3L), eq(3)); + //expect cache to be cleared. + Assert.assertNull( + ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataIdPrefix + 1, "group" + 1, "tenant" + 1))); + } + + @Test + public void testDumpChangeOfChangedConfigsNewTimestampOverride() { + PropertyUtil.setDumpChangeOn(true); + dumpChangeConfigWorker.setPageSize(3); + //mock delete first page + + Timestamp startTime = dumpChangeConfigWorker.startTime; + String dataIdPrefix = "dataId6789087"; + //pre set cache for id1 with old timestamp + preSetCache(dataIdPrefix, 1, startTime.getTime() - 1); + + Assert.assertEquals(startTime.getTime() - 1, + ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataIdPrefix + 1, "group" + 1, "tenant" + 1)) + .getConfigCache().getLastModifiedTs()); + List firstChanged = new ArrayList<>(); + firstChanged.add(createConfigInfoWrapper(dataIdPrefix, 1, startTime.getTime() + 1)); + + Mockito.when(configInfoPersistService.findChangeConfig(eq(startTime), eq(0L), eq(3))).thenReturn(firstChanged); + + //mock change config query obj + //1 timestamp-new&content-new + ConfigInfoWrapper configInfoWrapperNewForId1 = createConfigInfoWrapper(dataIdPrefix, 1, + startTime.getTime() + 2); + configInfoWrapperNewForId1.setContent("content" + System.currentTimeMillis()); + Mockito.when(configInfoPersistService.findConfigInfo(eq(dataIdPrefix + 1), eq("group" + 1), eq("tenant" + 1))) + .thenReturn(configInfoWrapperNewForId1); + + dumpChangeConfigWorker.run(); + + //expect cache to be cleared. + Assert.assertEquals(startTime.getTime() + 2, + ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataIdPrefix + 1, "group" + 1, "tenant" + 1)) + .getConfigCache().getLastModifiedTs()); + Assert.assertEquals(MD5Utils.md5Hex(configInfoWrapperNewForId1.getContent(), "UTF-8"), + ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataIdPrefix + 1, "group" + 1, "tenant" + 1)) + .getConfigCache().getMd5Utf8()); + } + + @Test + public void testDumpChangeOfChangedConfigsNewTimestampEqualMd5() { + PropertyUtil.setDumpChangeOn(true); + dumpChangeConfigWorker.setPageSize(3); + //mock delete first page + + Timestamp startTime = dumpChangeConfigWorker.startTime; + String dataIdPrefix = "dataIdnewtimestamp"; + //pre set cache for id1 with old timestamp + preSetCache(dataIdPrefix, 1, startTime.getTime() - 1); + + Assert.assertEquals(startTime.getTime() - 1, + ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataIdPrefix + 1, "group" + 1, "tenant" + 1)) + .getConfigCache().getLastModifiedTs()); + List firstChanged = new ArrayList<>(); + firstChanged.add(createConfigInfoWrapper(dataIdPrefix, 1, startTime.getTime() + 1)); + + Mockito.when(configInfoPersistService.findChangeConfig(eq(startTime), eq(0L), eq(3))).thenReturn(firstChanged); + + //mock change config query obj + //1 timestamp-new&content-old + ConfigInfoWrapper configInfoWrapperNewForId1 = createConfigInfoWrapper(dataIdPrefix, 1, + startTime.getTime() + 2); + Mockito.when(configInfoPersistService.findConfigInfo(eq(dataIdPrefix + 1), eq("group" + 1), eq("tenant" + 1))) + .thenReturn(configInfoWrapperNewForId1); + + dumpChangeConfigWorker.run(); + + //expect cache + Assert.assertEquals(startTime.getTime() + 2, + ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataIdPrefix + 1, "group" + 1, "tenant" + 1)) + .getConfigCache().getLastModifiedTs()); + Assert.assertEquals(MD5Utils.md5Hex(configInfoWrapperNewForId1.getContent(), "UTF-8"), + ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataIdPrefix + 1, "group" + 1, "tenant" + 1)) + .getConfigCache().getMd5Utf8()); + + } + + @Test + public void testDumpChangeOfChangedConfigsOldTimestamp() { + PropertyUtil.setDumpChangeOn(true); + dumpChangeConfigWorker.setPageSize(3); + //mock delete first page + + Timestamp startTime = dumpChangeConfigWorker.startTime; + String dataIdPrefix = "dataIdOldTimestamp"; + + //pre set cache for id1 with old timestamp + preSetCache(dataIdPrefix, 1, startTime.getTime() - 1); + + Assert.assertEquals(startTime.getTime() - 1, + ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataIdPrefix + 1, "group" + 1, "tenant" + 1)) + .getConfigCache().getLastModifiedTs()); + List firstChanged = new ArrayList<>(); + firstChanged.add(createConfigInfoWrapper(dataIdPrefix, 1, startTime.getTime() - 2)); + + Mockito.when(configInfoPersistService.findChangeConfig(eq(startTime), eq(0L), eq(3))).thenReturn(firstChanged); + + //mock change config query obj + //1 timestamp-new&content-new + ConfigInfoWrapper configInfoWrapperNewForId1 = createConfigInfoWrapper(dataIdPrefix, 1, + startTime.getTime() - 2); + configInfoWrapperNewForId1.setContent("content" + System.currentTimeMillis()); + Mockito.when(configInfoPersistService.findConfigInfo(eq(dataIdPrefix + 1), eq("group" + 1), eq("tenant" + 1))) + .thenReturn(configInfoWrapperNewForId1); + + dumpChangeConfigWorker.run(); + + //expect cache to be cleared. + Assert.assertEquals(startTime.getTime() - 1, + ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataIdPrefix + 1, "group" + 1, "tenant" + 1)) + .getConfigCache().getLastModifiedTs()); + Assert.assertEquals(MD5Utils.md5Hex("content" + 1, "UTF-8"), + ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataIdPrefix + 1, "group" + 1, "tenant" + 1)) + .getConfigCache().getMd5Utf8()); + + } + + @Test + public void testDumpChangeOfChangedConfigsEqualsTimestampMd5Update() { + PropertyUtil.setDumpChangeOn(true); + dumpChangeConfigWorker.setPageSize(3); + //mock delete first page + + Timestamp startTime = dumpChangeConfigWorker.startTime; + String dataIdPrefix = "dataIdEqualsTimestampMd5Update"; + + //pre set cache for id1 with old timestamp + preSetCache(dataIdPrefix, 1, startTime.getTime() - 1); + + Assert.assertEquals(startTime.getTime() - 1, + ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataIdPrefix + 1, "group" + 1, "tenant" + 1)) + .getConfigCache().getLastModifiedTs()); + List firstChanged = new ArrayList<>(); + firstChanged.add(createConfigInfoWrapper(dataIdPrefix, 1, startTime.getTime() - 1)); + + Mockito.when(configInfoPersistService.findChangeConfig(eq(startTime), eq(0L), eq(3))).thenReturn(firstChanged); + + //mock change config query obj + //1 timestamp-new&content-new + ConfigInfoWrapper configInfoWrapperNewForId1 = createConfigInfoWrapper(dataIdPrefix, 1, + startTime.getTime() - 1); + configInfoWrapperNewForId1.setContent("content" + System.currentTimeMillis()); + Mockito.when(configInfoPersistService.findConfigInfo(eq(dataIdPrefix + 1), eq("group" + 1), eq("tenant" + 1))) + .thenReturn(configInfoWrapperNewForId1); + + dumpChangeConfigWorker.run(); + + //expect cache to be cleared. + Assert.assertEquals(startTime.getTime() - 1, + ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataIdPrefix + 1, "group" + 1, "tenant" + 1)) + .getConfigCache().getLastModifiedTs()); + Assert.assertEquals(MD5Utils.md5Hex(configInfoWrapperNewForId1.getContent(), "UTF-8"), + ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataIdPrefix + 1, "group" + 1, "tenant" + 1)) + .getConfigCache().getMd5Utf8()); + + } + + private void preSetCache(String dataIdPrefix, long id, long timeStamp) { + ConfigCacheService.dumpWithMd5(dataIdPrefix + id, "group" + id, "tenant" + id, "content" + id, + MD5Utils.md5Hex("content" + id, "UTF-8"), timeStamp, "json", "encrykey" + id); + } + + private ConfigInfoWrapper createConfigInfoWrapper(String dataIdPreFix, long id, long timeStamp) { + ConfigInfoWrapper configInfoWrapper = new ConfigInfoWrapper(); + configInfoWrapper.setDataId(dataIdPreFix + id); + configInfoWrapper.setGroup("group" + id); + configInfoWrapper.setTenant("tenant" + id); + configInfoWrapper.setContent("content" + id); + configInfoWrapper.setId(id); + configInfoWrapper.setLastModified(timeStamp); + return configInfoWrapper; + } +} diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpProcessorTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpProcessorTest.java index 8a79163d827..fedeea11e23 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpProcessorTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpProcessorTest.java @@ -86,11 +86,11 @@ public void init() throws Exception { when(EnvUtil.getProperty(eq(CommonConstant.NACOS_PLUGIN_DATASOURCE_LOG), eq(Boolean.class), eq(false))).thenReturn(false); dynamicDataSourceMockedStatic.when(DynamicDataSource::getInstance).thenReturn(dynamicDataSource); - + when(dynamicDataSource.getDataSource()).thenReturn(dataSourceService); - + dumpService = new ExternalDumpService(configInfoPersistService, null, null, null, configInfoBetaPersistService, - configInfoTagPersistService, null); + configInfoTagPersistService, null, null); dumpProcessor = new DumpProcessor(configInfoPersistService, configInfoBetaPersistService, configInfoTagPersistService); Field[] declaredFields = ConfigDiskServiceFactory.class.getDeclaredFields(); diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpServiceTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpServiceTest.java index 467dfb55e26..2fb6ee20681 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpServiceTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpServiceTest.java @@ -16,37 +16,214 @@ package com.alibaba.nacos.config.server.service.dump; +import com.alibaba.nacos.config.server.manager.TaskManager; +import com.alibaba.nacos.config.server.model.ConfigInfoChanged; +import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent; +import com.alibaba.nacos.config.server.service.dump.task.DumpTask; +import com.alibaba.nacos.config.server.service.merge.MergeDatumService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoAggrPersistService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoBetaPersistService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService; +import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService; +import com.alibaba.nacos.config.server.utils.ConfigExecutor; +import com.alibaba.nacos.config.server.utils.GroupKey; +import com.alibaba.nacos.core.cluster.ServerMemberManager; +import com.alibaba.nacos.core.namespace.repository.NamespacePersistService; +import com.alibaba.nacos.persistence.datasource.DataSourceService; import com.alibaba.nacos.persistence.datasource.DynamicDataSource; -import org.junit.BeforeClass; -import org.junit.Ignore; +import com.alibaba.nacos.sys.env.EnvUtil; +import org.junit.After; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.util.ReflectionTestUtils; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; + @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest -@SpringBootApplication(scanBasePackages = "com.alibaba.nacos") -@WebAppConfiguration -@Ignore public class DumpServiceTest { - @Autowired - DumpService service; + @Mock + ConfigInfoPersistService configInfoPersistService; + + @Mock + + NamespacePersistService namespacePersistService; + + @Mock + HistoryConfigInfoPersistService historyConfigInfoPersistService; + + @Mock + ConfigInfoAggrPersistService configInfoAggrPersistService; + + @Mock + ConfigInfoBetaPersistService configInfoBetaPersistService; + + @Mock + ConfigInfoTagPersistService configInfoTagPersistService; + + @Mock + MergeDatumService mergeDatumService; + + @Mock + ServerMemberManager memberManager; + + @Mock + private DataSourceService dataSourceService; + + MockedStatic envUtilMockedStatic; + + MockedStatic configExecutorMocked; + + private DumpService dumpService; + + @Mock + private TaskManager dumpTaskMgr; + + private static final String BETA_TABLE_NAME = "config_info_beta"; + + private static final String TAG_TABLE_NAME = "config_info_tag"; - @BeforeClass - public static void setUp() { + @Before + public void setUp() { + envUtilMockedStatic = Mockito.mockStatic(EnvUtil.class); + ReflectionTestUtils.setField(DynamicDataSource.getInstance(), "localDataSourceService", dataSourceService); + ReflectionTestUtils.setField(DynamicDataSource.getInstance(), "basicDataSourceService", dataSourceService); + dumpService = new ExternalDumpService(configInfoPersistService, namespacePersistService, + historyConfigInfoPersistService, configInfoAggrPersistService, configInfoBetaPersistService, + configInfoTagPersistService, mergeDatumService, memberManager); + configExecutorMocked = Mockito.mockStatic(ConfigExecutor.class); - ReflectionTestUtils.setField(DynamicDataSource.getInstance(), "localDataSourceService", null); - ReflectionTestUtils.setField(DynamicDataSource.getInstance(), "basicDataSourceService", null); + } + + @After + public void after() { + envUtilMockedStatic.close(); + configExecutorMocked.close(); } @Test - public void init() throws Throwable { - service.init(); + public void dumpRequest() throws Throwable { + String dataId = "12345667dataId"; + String group = "234445group"; + DumpRequest dumpRequest = DumpRequest.create(dataId, group, "testtenant", System.currentTimeMillis(), + "127.0.0.1"); + // TaskManager dumpTaskMgr; + ReflectionTestUtils.setField(dumpService, "dumpTaskMgr", dumpTaskMgr); + Mockito.doNothing().when(dumpTaskMgr).addTask(any(), any()); + dumpService.dump(dumpRequest); + Mockito.verify(dumpTaskMgr, times(1)) + .addTask(eq(GroupKey.getKeyTenant(dataId, group, dumpRequest.getTenant())), any(DumpTask.class)); + dumpRequest.setBeta(true); + dumpService.dump(dumpRequest); + Mockito.verify(dumpTaskMgr, times(1)) + .addTask(eq(GroupKey.getKeyTenant(dataId, group, dumpRequest.getTenant()) + "+beta"), + any(DumpTask.class)); + dumpRequest.setBeta(false); + dumpRequest.setBatch(true); + dumpService.dump(dumpRequest); + Mockito.verify(dumpTaskMgr, times(1)) + .addTask(eq(GroupKey.getKeyTenant(dataId, group, dumpRequest.getTenant()) + "+batch"), + any(DumpTask.class)); + dumpRequest.setBatch(false); + dumpRequest.setTag("testTag111"); + dumpService.dump(dumpRequest); + Mockito.verify(dumpTaskMgr, times(1)).addTask( + eq(GroupKey.getKeyTenant(dataId, group, dumpRequest.getTenant()) + "+tag+" + dumpRequest.getTag()), + any(DumpTask.class)); + + } + + @Test + public void dumpOperate() throws Throwable { + configExecutorMocked.when( + () -> ConfigExecutor.scheduleConfigTask(any(Runnable.class), anyInt(), anyInt(), any(TimeUnit.class))) + .thenAnswer(invocation -> null); + configExecutorMocked.when( + () -> ConfigExecutor.scheduleConfigChangeTask(any(Runnable.class), anyInt(), any(TimeUnit.class))) + .thenAnswer(invocation -> null); + Mockito.when(namespacePersistService.isExistTable(BETA_TABLE_NAME)).thenReturn(true); + Mockito.when(namespacePersistService.isExistTable(TAG_TABLE_NAME)).thenReturn(true); + ConfigInfoChanged hasDatum = new ConfigInfoChanged(); + hasDatum.setDataId("hasDatumdataId1"); + hasDatum.setTenant("tenant1"); + hasDatum.setGroup("group1"); + ConfigInfoChanged noDatum = new ConfigInfoChanged(); + noDatum.setDataId("dataId1"); + noDatum.setTenant("tenant1"); + noDatum.setGroup("group1"); + List configList = configInfoAggrPersistService.findAllAggrGroup(); + configList.add(hasDatum); + configList.add(noDatum); + Mockito.when(configInfoAggrPersistService.findAllAggrGroup()).thenReturn(configList); + List> result = new ArrayList<>(); + result.add(Arrays.asList(hasDatum)); + result.add(Arrays.asList(noDatum)); + Mockito.when(mergeDatumService.splitList(anyList(), anyInt())).thenReturn(result); + Mockito.doNothing().when(mergeDatumService).executeConfigsMerge(anyList()); + dumpService.dumpOperate(); + + // expect dump formal,beta,tag to be invoked. + Mockito.verify(configInfoPersistService, times(1)).findConfigMaxId(); + Mockito.verify(configInfoBetaPersistService, times(1)).configInfoBetaCount(); + Mockito.verify(configInfoTagPersistService, times(1)).configInfoTagCount(); + + Mockito.verify(mergeDatumService, times(2)).executeConfigsMerge(anyList()); + + // expect dump formal,beta,tag,history clear,config change task to be scheduled. + // expect config clear history task be scheduled. + configExecutorMocked.verify( + () -> ConfigExecutor.scheduleConfigTask(any(DumpService.DumpAllProcessorRunner.class), anyLong(), + anyLong(), eq(TimeUnit.MINUTES)), times(1)); + configExecutorMocked.verify( + () -> ConfigExecutor.scheduleConfigTask(any(DumpService.DumpAllBetaProcessorRunner.class), anyLong(), + anyLong(), eq(TimeUnit.MINUTES)), times(1)); + configExecutorMocked.verify( + () -> ConfigExecutor.scheduleConfigTask(any(DumpService.DumpAllTagProcessorRunner.class), anyLong(), + anyLong(), eq(TimeUnit.MINUTES)), times(1)); + configExecutorMocked.verify( + () -> ConfigExecutor.scheduleConfigChangeTask(any(DumpChangeConfigWorker.class), anyLong(), + eq(TimeUnit.MILLISECONDS)), times(1)); + configExecutorMocked.verify( + () -> ConfigExecutor.scheduleConfigTask(any(DumpService.ConfigHistoryClear.class), anyLong(), anyLong(), + eq(TimeUnit.MINUTES)), times(1)); } + + @Test + public void clearHistory() { + envUtilMockedStatic.when(() -> EnvUtil.getProperty(eq("nacos.config.retention.days"))).thenReturn("10"); + Mockito.when(memberManager.isFirstIp()).thenReturn(true); + dumpService.clearConfigHistory(); + Mockito.verify(historyConfigInfoPersistService, times(1)).removeConfigHistory(any(Timestamp.class), anyInt()); + } + + @Test + public void testHandleConfigDataChange() { + ConfigDataChangeEvent configDataChangeEvent = new ConfigDataChangeEvent("dataId", "group", + System.currentTimeMillis()); + ReflectionTestUtils.setField(dumpService, "dumpTaskMgr", dumpTaskMgr); + Mockito.doNothing().when(dumpTaskMgr).addTask(any(), any()); + + dumpService.handleConfigDataChange(configDataChangeEvent); + Mockito.verify(dumpTaskMgr, times(1)).addTask( + eq(GroupKey.getKeyTenant(configDataChangeEvent.dataId, configDataChangeEvent.group, + configDataChangeEvent.tenant)), any(DumpTask.class)); + } + } diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/processor/DumpAllProcessorTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/processor/DumpAllProcessorTest.java index a97c03b243a..e7f6857a0c8 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/processor/DumpAllProcessorTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/processor/DumpAllProcessorTest.java @@ -33,6 +33,7 @@ import com.alibaba.nacos.plugin.datasource.constants.CommonConstant; import com.alibaba.nacos.sys.env.EnvUtil; import junit.framework.TestCase; +import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -43,39 +44,38 @@ import org.mockito.junit.MockitoJUnitRunner; import java.io.IOException; -import java.util.ArrayList; -import java.util.stream.Collectors; -import java.util.stream.Stream; +import java.util.Arrays; +import java.util.List; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class DumpAllProcessorTest extends TestCase { - + @Mock DynamicDataSource dynamicDataSource; - + @Mock DataSourceService dataSourceService; - + @Mock ConfigInfoBetaPersistService configInfoBetaPersistService; - + @Mock ConfigInfoTagPersistService configInfoTagPersistService; - + DumpAllProcessor dumpAllProcessor; - + ExternalDumpService dumpService; - + MockedStatic dynamicDataSourceMockedStatic; - + @Mock ConfigInfoPersistService configInfoPersistService; - + MockedStatic envUtilMockedStatic; - + @Before public void init() throws Exception { dynamicDataSourceMockedStatic = Mockito.mockStatic(DynamicDataSource.class); @@ -85,17 +85,23 @@ public void init() throws Exception { when(EnvUtil.getProperty(eq(CommonConstant.NACOS_PLUGIN_DATASOURCE_LOG), eq(Boolean.class), eq(false))).thenReturn(false); dynamicDataSourceMockedStatic.when(DynamicDataSource::getInstance).thenReturn(dynamicDataSource); - + when(dynamicDataSource.getDataSource()).thenReturn(dataSourceService); - + dumpService = new ExternalDumpService(configInfoPersistService, null, null, null, configInfoBetaPersistService, - configInfoTagPersistService, null); - + configInfoTagPersistService, null, null); + dumpAllProcessor = new DumpAllProcessor(configInfoPersistService); } - + + @After + public void after() throws Exception { + dynamicDataSourceMockedStatic.close(); + envUtilMockedStatic.close(); + } + private static int newConfigCount = 1; - + private ConfigInfoWrapper createNewConfig(int id) { ConfigInfoWrapper configInfoWrapper = new ConfigInfoWrapper(); String dataId = "dataIdTime" + newConfigCount; @@ -110,7 +116,7 @@ private ConfigInfoWrapper createNewConfig(int id) { newConfigCount++; return configInfoWrapper; } - + @Test public void testDumpAll() throws IOException { ConfigInfoWrapper configInfoWrapper1 = createNewConfig(1); @@ -122,16 +128,16 @@ public void testDumpAll() throws IOException { page.setTotalCount(2); page.setPagesAvailable(2); page.setPageNumber(1); - ArrayList list = Stream.of(configInfoWrapper1, configInfoWrapper2) - .collect(Collectors.toCollection(ArrayList::new)); + List list = Arrays.asList(configInfoWrapper1, configInfoWrapper2); page.setPageItems(list); - + Mockito.when(configInfoPersistService.findConfigMaxId()).thenReturn(2L); - Mockito.when(configInfoPersistService.findAllConfigInfoFragment(0, 1000)) - .thenReturn(page); - - String groupKey1 = GroupKey2.getKey(configInfoWrapper1.getDataId(), configInfoWrapper1.getGroup(), configInfoWrapper1.getTenant()); - String groupKey2 = GroupKey2.getKey(configInfoWrapper2.getDataId(), configInfoWrapper2.getGroup(), configInfoWrapper2.getTenant()); + Mockito.when(configInfoPersistService.findAllConfigInfoFragment(0, 1000)).thenReturn(page); + + String groupKey1 = GroupKey2.getKey(configInfoWrapper1.getDataId(), configInfoWrapper1.getGroup(), + configInfoWrapper1.getTenant()); + String groupKey2 = GroupKey2.getKey(configInfoWrapper2.getDataId(), configInfoWrapper2.getGroup(), + configInfoWrapper2.getTenant()); // For config 1, assign a latter time, to make sure that it would be updated. // For config 2, assign an earlier time, to make sure that it is not be updated. String md51 = MD5Utils.md5Hex(configInfoWrapper1.getContent(), "UTF-8"); @@ -139,41 +145,42 @@ public void testDumpAll() throws IOException { long latterTimestamp = timestamp + 999; long earlierTimestamp = timestamp - 999; String encryptedDataKey = "testEncryptedDataKey"; - ConfigCacheService.updateMd5(groupKey1, md51, latterTimestamp, encryptedDataKey); - ConfigCacheService.updateMd5(groupKey2, md52, earlierTimestamp, encryptedDataKey); - + ConfigCacheService.dumpWithMd5(configInfoWrapper1.getDataId(), configInfoWrapper1.getGroup(), + configInfoWrapper1.getTenant(), configInfoWrapper1.getContent(), md51, latterTimestamp, "json", + encryptedDataKey); + ConfigCacheService.dumpWithMd5(configInfoWrapper2.getDataId(), configInfoWrapper2.getGroup(), + configInfoWrapper2.getTenant(), configInfoWrapper2.getContent(), md52, earlierTimestamp, "json", + encryptedDataKey); + DumpAllTask dumpAllTask = new DumpAllTask(); boolean process = dumpAllProcessor.process(dumpAllTask); Assert.assertTrue(process); - + //Check cache - CacheItem contentCache1 = ConfigCacheService.getContentCache(GroupKey2.getKey( - configInfoWrapper1.getDataId(), - configInfoWrapper1.getGroup(), - configInfoWrapper1.getTenant())); + CacheItem contentCache1 = ConfigCacheService.getContentCache( + GroupKey2.getKey(configInfoWrapper1.getDataId(), configInfoWrapper1.getGroup(), + configInfoWrapper1.getTenant())); Assert.assertEquals(md51, contentCache1.getConfigCache().getMd5Utf8()); // check if config1 is updated Assert.assertTrue(timestamp < contentCache1.getConfigCache().getLastModifiedTs()); //check disk - String contentFromDisk1 = ConfigDiskServiceFactory.getInstance().getContent( - configInfoWrapper1.getDataId(), - configInfoWrapper1.getGroup(), - configInfoWrapper1.getTenant()); + String contentFromDisk1 = ConfigDiskServiceFactory.getInstance() + .getContent(configInfoWrapper1.getDataId(), configInfoWrapper1.getGroup(), + configInfoWrapper1.getTenant()); Assert.assertEquals(configInfoWrapper1.getContent(), contentFromDisk1); - + //Check cache - CacheItem contentCache2 = ConfigCacheService.getContentCache(GroupKey2.getKey( - configInfoWrapper2.getDataId(), - configInfoWrapper2.getGroup(), - configInfoWrapper2.getTenant())); - Assert.assertEquals(MD5Utils.md5Hex(configInfoWrapper2.getContent(), "UTF-8"), contentCache2.getConfigCache().getMd5Utf8()); + CacheItem contentCache2 = ConfigCacheService.getContentCache( + GroupKey2.getKey(configInfoWrapper2.getDataId(), configInfoWrapper2.getGroup(), + configInfoWrapper2.getTenant())); + Assert.assertEquals(MD5Utils.md5Hex(configInfoWrapper2.getContent(), "UTF-8"), + contentCache2.getConfigCache().getMd5Utf8()); // check if config2 is updated Assert.assertEquals(timestamp, contentCache2.getConfigCache().getLastModifiedTs()); //check disk - String contentFromDisk2 = ConfigDiskServiceFactory.getInstance().getContent( - configInfoWrapper2.getDataId(), - configInfoWrapper2.getGroup(), - configInfoWrapper2.getTenant()); + String contentFromDisk2 = ConfigDiskServiceFactory.getInstance() + .getContent(configInfoWrapper2.getDataId(), configInfoWrapper2.getGroup(), + configInfoWrapper2.getTenant()); Assert.assertEquals(configInfoWrapper2.getContent(), contentFromDisk2); } } diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/merge/MergeDatumServiceTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/merge/MergeDatumServiceTest.java new file mode 100644 index 00000000000..4cc30a0431f --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/merge/MergeDatumServiceTest.java @@ -0,0 +1,237 @@ +/* + * Copyright 1999-2023 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.config.server.service.merge; + +import com.alibaba.nacos.config.server.manager.TaskManager; +import com.alibaba.nacos.config.server.model.ConfigInfoAggr; +import com.alibaba.nacos.config.server.model.ConfigInfoChanged; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoAggrPersistService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService; +import com.alibaba.nacos.consistency.cp.CPProtocol; +import com.alibaba.nacos.core.distributed.ProtocolManager; +import com.alibaba.nacos.persistence.configuration.DatasourceConfiguration; +import com.alibaba.nacos.persistence.datasource.DataSourceService; +import com.alibaba.nacos.persistence.datasource.DynamicDataSource; +import com.alibaba.nacos.persistence.model.Page; +import com.alibaba.nacos.sys.env.EnvUtil; +import com.alibaba.nacos.sys.utils.ApplicationUtils; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.util.ReflectionTestUtils; + +import java.util.ArrayList; +import java.util.List; + +import static com.alibaba.nacos.persistence.constants.PersistenceConstant.CONFIG_MODEL_RAFT_GROUP; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; + +@RunWith(SpringJUnit4ClassRunner.class) +public class MergeDatumServiceTest { + + @Mock + ConfigInfoPersistService configInfoPersistService; + + @Mock + ConfigInfoAggrPersistService configInfoAggrPersistService; + + @Mock + ConfigInfoTagPersistService configInfoTagPersistService; + + @Mock + ProtocolManager protocolManager; + + @Mock + private DataSourceService dataSourceService; + + MockedStatic envUtilMockedStatic; + + MockedStatic applicationUtilsMockedStaticc; + + private MergeDatumService mergeDatumService; + + @Before + public void setUp() { + envUtilMockedStatic = Mockito.mockStatic(EnvUtil.class); + applicationUtilsMockedStaticc = Mockito.mockStatic(ApplicationUtils.class); + applicationUtilsMockedStaticc.when(() -> ApplicationUtils.getBean(eq(ProtocolManager.class))) + .thenReturn(protocolManager); + + ReflectionTestUtils.setField(DynamicDataSource.getInstance(), "localDataSourceService", dataSourceService); + ReflectionTestUtils.setField(DynamicDataSource.getInstance(), "basicDataSourceService", dataSourceService); + mergeDatumService = new MergeDatumService(configInfoPersistService, configInfoAggrPersistService, + configInfoTagPersistService); + + } + + @After + public void after() { + envUtilMockedStatic.close(); + applicationUtilsMockedStaticc.close(); + } + + @Test + public void testSplitList() { + String dataId = "dataID"; + int count = 5; + List configList = new ArrayList<>(); + configList.add(create(dataId, 0)); + configList.add(create(dataId, 1)); + configList.add(create(dataId, 2)); + configList.add(create(dataId, 3)); + configList.add(create(dataId, 4)); + configList.add(create(dataId, 5)); + configList.add(create(dataId, 6)); + configList.add(create(dataId, 7)); + configList.add(create(dataId, 8)); + + List> lists = mergeDatumService.splitList(configList, count); + int originalCount = configList.size(); + int actualCount = 0; + for (int i = 0; i < lists.size(); i++) { + List indexList = lists.get(i); + for (int j = 0; j < indexList.size(); j++) { + ConfigInfoChanged configInfoChanged = indexList.get(j); + actualCount++; + Assert.assertEquals(configInfoChanged, configList.get((j * count) + i)); + } + } + + Assert.assertEquals(originalCount, actualCount); + + } + + private ConfigInfoChanged create(String dataID, int i) { + ConfigInfoChanged hasDatum = new ConfigInfoChanged(); + hasDatum.setDataId(dataID + i); + hasDatum.setTenant("tenant1"); + hasDatum.setGroup("group1"); + return hasDatum; + } + + @Test + public void executeMergeConfigTask() { + envUtilMockedStatic.when(() -> EnvUtil.getProperty(eq("nacos.config.retention.days"))).thenReturn("10"); + ConfigInfoChanged hasDatum = new ConfigInfoChanged(); + hasDatum.setDataId("hasDatumdataId1"); + hasDatum.setTenant("tenant1"); + hasDatum.setGroup("group1"); + ConfigInfoChanged noDatum = new ConfigInfoChanged(); + noDatum.setDataId("dataId1"); + noDatum.setTenant("tenant1"); + noDatum.setGroup("group1"); + List configInfoList = new ArrayList<>(); + configInfoList.add(hasDatum); + configInfoList.add(noDatum); + + when(configInfoAggrPersistService.aggrConfigInfoCount(eq(hasDatum.getDataId()), eq(hasDatum.getGroup()), + eq(hasDatum.getTenant()))).thenReturn(2); + Page datumPage = new Page<>(); + ConfigInfoAggr configInfoAggr1 = new ConfigInfoAggr(); + configInfoAggr1.setContent("12344"); + ConfigInfoAggr configInfoAggr2 = new ConfigInfoAggr(); + configInfoAggr2.setContent("12345666"); + datumPage.getPageItems().add(configInfoAggr1); + datumPage.getPageItems().add(configInfoAggr2); + + when(configInfoAggrPersistService.findConfigInfoAggrByPage(eq(hasDatum.getDataId()), eq(hasDatum.getGroup()), + eq(hasDatum.getTenant()), anyInt(), anyInt())).thenReturn(datumPage); + + when(configInfoAggrPersistService.aggrConfigInfoCount(eq(noDatum.getDataId()), eq(noDatum.getGroup()), + eq(noDatum.getTenant()))).thenReturn(0); + + mergeDatumService.executeMergeConfigTask(configInfoList, 1000); + } + + @Test + public void testAddMergeTaskExternalModel() { + String dataId = "dataId12345"; + String group = "group123"; + String tenant = "tenant1234"; + String clientIp = "127.0.0.1"; + DatasourceConfiguration.setEmbeddedStorage(false); + TaskManager mockTasker = Mockito.mock(TaskManager.class); + ReflectionTestUtils.setField(mergeDatumService, "mergeTasks", mockTasker); + mergeDatumService.addMergeTask(dataId, group, tenant, clientIp); + Mockito.verify(mockTasker, times(1)).addTask(anyString(), any(MergeDataTask.class)); + } + + @Test + public void testAddMergeTaskEmbeddedAndStandAloneModel() { + + DatasourceConfiguration.setEmbeddedStorage(true); + envUtilMockedStatic.when(() -> EnvUtil.getStandaloneMode()).thenReturn(true); + TaskManager mockTasker = Mockito.mock(TaskManager.class); + ReflectionTestUtils.setField(mergeDatumService, "mergeTasks", mockTasker); + String dataId = "dataId12345"; + String group = "group123"; + String tenant = "tenant1234"; + String clientIp = "127.0.0.1"; + mergeDatumService.addMergeTask(dataId, group, tenant, clientIp); + Mockito.verify(mockTasker, times(1)).addTask(anyString(), any(MergeDataTask.class)); + } + + @Test + public void testAddMergeTaskEmbeddedAndClusterModelLeader() { + + DatasourceConfiguration.setEmbeddedStorage(true); + envUtilMockedStatic.when(() -> EnvUtil.getStandaloneMode()).thenReturn(false); + TaskManager mockTasker = Mockito.mock(TaskManager.class); + ReflectionTestUtils.setField(mergeDatumService, "mergeTasks", mockTasker); + //mock is leader + CPProtocol cpProtocol = Mockito.mock(CPProtocol.class); + when(protocolManager.getCpProtocol()).thenReturn(cpProtocol); + when(cpProtocol.isLeader(eq(CONFIG_MODEL_RAFT_GROUP))).thenReturn(true); + String dataId = "dataId12345"; + String group = "group123"; + String tenant = "tenant1234"; + String clientIp = "127.0.0.1"; + mergeDatumService.addMergeTask(dataId, group, tenant, clientIp); + Mockito.verify(mockTasker, times(1)).addTask(anyString(), any(MergeDataTask.class)); + } + + @Test + public void testAddMergeTaskEmbeddedAndClusterModelNotLeader() { + + DatasourceConfiguration.setEmbeddedStorage(true); + envUtilMockedStatic.when(() -> EnvUtil.getStandaloneMode()).thenReturn(false); + TaskManager mockTasker = Mockito.mock(TaskManager.class); + ReflectionTestUtils.setField(mergeDatumService, "mergeTasks", mockTasker); + //mock not leader + CPProtocol cpProtocol = Mockito.mock(CPProtocol.class); + when(protocolManager.getCpProtocol()).thenReturn(cpProtocol); + when(cpProtocol.isLeader(eq(CONFIG_MODEL_RAFT_GROUP))).thenReturn(false); + String dataId = "dataId12345"; + String group = "group123"; + String tenant = "tenant1234"; + String clientIp = "127.0.0.1"; + mergeDatumService.addMergeTask(dataId, group, tenant, clientIp); + Mockito.verify(mockTasker, times(0)).addTask(anyString(), any(MergeDataTask.class)); + } +} diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/merge/MergeTaskProcessorTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/merge/MergeTaskProcessorTest.java new file mode 100644 index 00000000000..b5163cc6436 --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/merge/MergeTaskProcessorTest.java @@ -0,0 +1,240 @@ +/* + * Copyright 1999-2023 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.config.server.service.merge; + +import com.alibaba.nacos.common.notify.Event; +import com.alibaba.nacos.common.notify.NotifyCenter; +import com.alibaba.nacos.common.notify.listener.Subscriber; +import com.alibaba.nacos.config.server.model.ConfigInfo; +import com.alibaba.nacos.config.server.model.ConfigInfoAggr; +import com.alibaba.nacos.config.server.model.ConfigOperateResult; +import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoAggrPersistService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService; +import com.alibaba.nacos.persistence.datasource.DataSourceService; +import com.alibaba.nacos.persistence.datasource.DynamicDataSource; +import com.alibaba.nacos.persistence.model.Page; +import com.alibaba.nacos.sys.env.EnvUtil; +import com.alibaba.nacos.sys.utils.InetUtils; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.util.ReflectionTestUtils; + +import java.util.concurrent.atomic.AtomicReference; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; + +@RunWith(SpringJUnit4ClassRunner.class) + +public class MergeTaskProcessorTest { + + @Mock + ConfigInfoPersistService configInfoPersistService; + + @Mock + ConfigInfoAggrPersistService configInfoAggrPersistService; + + @Mock + ConfigInfoTagPersistService configInfoTagPersistService; + + @Mock + private DataSourceService dataSourceService; + + @Mock + private MergeDatumService mergeDatumService; + + MockedStatic envUtilMockedStatic; + + MergeTaskProcessor mergeTaskProcessor; + + MockedStatic inetUtilsMockedStatic; + + @Before + public void setUp() { + envUtilMockedStatic = Mockito.mockStatic(EnvUtil.class); + inetUtilsMockedStatic = Mockito.mockStatic(InetUtils.class); + ReflectionTestUtils.setField(DynamicDataSource.getInstance(), "localDataSourceService", dataSourceService); + ReflectionTestUtils.setField(DynamicDataSource.getInstance(), "basicDataSourceService", dataSourceService); + mergeTaskProcessor = new MergeTaskProcessor(configInfoPersistService, configInfoAggrPersistService, + configInfoTagPersistService, mergeDatumService); + inetUtilsMockedStatic.when(InetUtils::getSelfIP).thenReturn("127.0.0.1"); + + } + + @Before + public void after() { + envUtilMockedStatic.close(); + inetUtilsMockedStatic.close(); + } + + /** + * test aggr has datum and merge it expect: 1.config to be inserted 2.config data change event to be published + */ + @Test + public void testMergerExistAggrConfig() throws InterruptedException { + String dataId = "dataId12345"; + String group = "group123"; + String tenant = "tenant1234"; + when(configInfoAggrPersistService.aggrConfigInfoCount(eq(dataId), eq(group), eq(tenant))).thenReturn(2); + Page datumPage = new Page<>(); + ConfigInfoAggr configInfoAggr1 = new ConfigInfoAggr(); + configInfoAggr1.setContent("12344"); + ConfigInfoAggr configInfoAggr2 = new ConfigInfoAggr(); + configInfoAggr2.setContent("12345666"); + datumPage.getPageItems().add(configInfoAggr1); + datumPage.getPageItems().add(configInfoAggr2); + + when(configInfoAggrPersistService.findConfigInfoAggrByPage(eq(dataId), eq(group), eq(tenant), anyInt(), + anyInt())).thenReturn(datumPage); + + when(configInfoPersistService.insertOrUpdate(eq(null), eq(null), any(ConfigInfo.class), eq(null))).thenReturn( + new ConfigOperateResult()); + + AtomicReference reference = new AtomicReference<>(); + NotifyCenter.registerSubscriber(new Subscriber() { + + @Override + public void onEvent(Event event) { + ConfigDataChangeEvent event1 = (ConfigDataChangeEvent) event; + if (event1.dataId.equals(dataId) && event1.group.equals(group) && tenant.equals(event1.tenant)) { + reference.set((ConfigDataChangeEvent) event); + } + } + + @Override + public Class subscribeType() { + return ConfigDataChangeEvent.class; + } + }); + + MergeDataTask mergeDataTask = new MergeDataTask(dataId, group, tenant, "127.0.0.1"); + mergeTaskProcessor.process(mergeDataTask); + + Mockito.verify(configInfoPersistService, times(1)) + .insertOrUpdate(eq(null), eq(null), any(ConfigInfo.class), eq(null)); + Thread.sleep(1000L); + Assert.assertTrue(reference.get() != null); + + } + + /** + * test aggr has datum and remove it. + */ + @Test + public void testMergerNotExistAggrConfig() throws InterruptedException { + String dataId = "dataId12345"; + String group = "group123"; + String tenant = "tenant1234"; + when(configInfoAggrPersistService.aggrConfigInfoCount(eq(dataId), eq(group), eq(tenant))).thenReturn(0); + + AtomicReference reference = new AtomicReference<>(); + NotifyCenter.registerSubscriber(new Subscriber() { + + @Override + public void onEvent(Event event) { + ConfigDataChangeEvent event1 = (ConfigDataChangeEvent) event; + if (event1.dataId.equals(dataId) && event1.group.equals(group) && tenant.equals(event1.tenant)) { + reference.set((ConfigDataChangeEvent) event); + } + } + + @Override + public Class subscribeType() { + return ConfigDataChangeEvent.class; + } + }); + + MergeDataTask mergeDataTask = new MergeDataTask(dataId, group, tenant, "127.0.0.1"); + Mockito.doNothing().when(configInfoPersistService) + .removeConfigInfo(eq(dataId), eq(group), eq(tenant), eq("127.0.0.1"), eq(null)); + //Mockito.doNothing().when(configInfoTagPersistService).removeConfigInfoTag(eq(dataId), eq(group), eq(tenant),eq(),eq("127.0.0.1"),eq(null)); + mergeTaskProcessor.process(mergeDataTask); + Mockito.verify(configInfoPersistService, times(1)) + .removeConfigInfo(eq(dataId), eq(group), eq(tenant), eq("127.0.0.1"), eq(null)); + Thread.sleep(1000L); + Assert.assertTrue(reference.get() != null); + } + + /** + * test aggr has no datum and remove it tag. + */ + @Test + public void testTagMergerNotExistAggrConfig() throws InterruptedException { + String dataId = "dataId12345"; + String group = "group123"; + String tenant = "tenant1234"; + String tag = "23456789"; + when(configInfoAggrPersistService.aggrConfigInfoCount(eq(dataId), eq(group), eq(tenant))).thenReturn(0); + + AtomicReference reference = new AtomicReference<>(); + NotifyCenter.registerSubscriber(new Subscriber() { + + @Override + public void onEvent(Event event) { + ConfigDataChangeEvent event1 = (ConfigDataChangeEvent) event; + if (event1.dataId.equals(dataId) && event1.group.equals(group) && tenant.equals(event1.tenant) + && tag.equals(event1.tag)) { + reference.set((ConfigDataChangeEvent) event); + } + } + + @Override + public Class subscribeType() { + return ConfigDataChangeEvent.class; + } + }); + + MergeDataTask mergeDataTask = new MergeDataTask(dataId, group, tenant, tag, "127.0.0.1"); + + Mockito.doNothing().when(configInfoTagPersistService) + .removeConfigInfoTag(eq(dataId), eq(group), eq(tenant), eq(tag), eq("127.0.0.1"), eq(null)); + mergeTaskProcessor.process(mergeDataTask); + Mockito.verify(configInfoTagPersistService, times(1)) + .removeConfigInfoTag(eq(dataId), eq(group), eq(tenant), eq(tag), eq("127.0.0.1"), eq(null)); + Thread.sleep(1000L); + Assert.assertTrue(reference.get() != null); + } + + /** + * test aggr has no datum and remove it tag. + */ + @Test + public void testTagMergerError() throws InterruptedException { + String dataId = "dataId12345"; + String group = "group123"; + String tenant = "tenant1234"; + when(configInfoAggrPersistService.aggrConfigInfoCount(eq(dataId), eq(group), eq(tenant))).thenThrow( + new NullPointerException()); + + MergeDataTask mergeDataTask = new MergeDataTask(dataId, group, tenant, "127.0.0.1"); + + mergeTaskProcessor.process(mergeDataTask); + Mockito.verify(mergeDatumService, times(1)).addMergeTask(eq(dataId), eq(group), eq(tenant), eq("127.0.0.1")); + + } +} diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/notify/AsyncNotifyServiceTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/notify/AsyncNotifyServiceTest.java new file mode 100644 index 00000000000..d0191492937 --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/notify/AsyncNotifyServiceTest.java @@ -0,0 +1,233 @@ +/* + * 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.config.server.service.notify; + +import com.alibaba.nacos.api.config.remote.request.cluster.ConfigChangeClusterSyncRequest; +import com.alibaba.nacos.api.config.remote.response.cluster.ConfigChangeClusterSyncResponse; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.remote.RequestCallBack; +import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent; +import com.alibaba.nacos.config.server.remote.ConfigClusterRpcClientProxy; +import com.alibaba.nacos.config.server.service.notify.AsyncNotifyService.AsyncRpcNotifyCallBack; +import com.alibaba.nacos.config.server.utils.ConfigExecutor; +import com.alibaba.nacos.core.cluster.Member; +import com.alibaba.nacos.core.cluster.NodeState; +import com.alibaba.nacos.core.cluster.ServerMemberManager; +import com.alibaba.nacos.sys.env.EnvUtil; +import com.alibaba.nacos.sys.utils.InetUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.util.ReflectionTestUtils; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.concurrent.TimeUnit; + +import static com.alibaba.nacos.config.server.service.notify.AsyncNotifyService.HEALTHY_CHECK_STATUS; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; + +/** + * AsyncNotifyServiceTest. + * + * @author shiyiyue + */ +@RunWith(SpringJUnit4ClassRunner.class) +public class AsyncNotifyServiceTest { + + @Mock + ServerMemberManager serverMemberManager; + + @Mock + private ConfigClusterRpcClientProxy configClusterRpcClientProxy; + + MockedStatic envUtilMocked; + + MockedStatic configExecutorMocked; + + MockedStatic inetUtilsMocked; + + @Before + public void setUp() { + envUtilMocked = Mockito.mockStatic(EnvUtil.class); + configExecutorMocked = Mockito.mockStatic(ConfigExecutor.class); + inetUtilsMocked = Mockito.mockStatic(InetUtils.class); + inetUtilsMocked.when(InetUtils::getSelfIP).thenReturn("127.0.0.1"); + } + + @After + public void after() { + envUtilMocked.close(); + inetUtilsMocked.close(); + configExecutorMocked.close(); + } + + @Test + public void testSyncConfigChangeCallback() { + long timeStamp = System.currentTimeMillis(); + Member member1 = new Member(); + member1.setIp("testip1" + timeStamp); + member1.setState(NodeState.UP); + AsyncNotifyService asyncNotifyService = new AsyncNotifyService(serverMemberManager); + ReflectionTestUtils.setField(asyncNotifyService, "configClusterRpcClientProxy", configClusterRpcClientProxy); + String dataId = "testDataId" + timeStamp; + String group = "testGroup"; + AsyncNotifyService.NotifySingleRpcTask notifySingleRpcTask = new AsyncNotifyService.NotifySingleRpcTask(dataId, + group, null, null, 0, false, false, member1); + configExecutorMocked.when( + () -> ConfigExecutor.scheduleAsyncNotify(any(Runnable.class), anyLong(), any(TimeUnit.class))) + .thenAnswer(invocation -> null); + + notifySingleRpcTask.setBatch(true); + notifySingleRpcTask.setTag("test"); + notifySingleRpcTask.setBeta(false); + AsyncRpcNotifyCallBack asyncRpcNotifyCallBack = new AsyncRpcNotifyCallBack(asyncNotifyService, + notifySingleRpcTask); + ConfigChangeClusterSyncResponse successResponse = new ConfigChangeClusterSyncResponse(); + //1. success response + asyncRpcNotifyCallBack.onResponse(successResponse); + //2. fail response + successResponse.setResultCode(500); + asyncRpcNotifyCallBack.onResponse(successResponse); + //3. exception + asyncRpcNotifyCallBack.onException(new NacosException()); + + // expect schedule twice fail or exception response. + configExecutorMocked.verify( + () -> ConfigExecutor.scheduleAsyncNotify(any(AsyncNotifyService.AsyncRpcTask.class), anyLong(), + any(TimeUnit.class)), times(2)); + } + + /** + * test HandleConfigDataChangeEvent. expect create a AsyncRpcTask and execute in ConfigExecutor. + */ + @Test + public void testHandleConfigDataChangeEvent() { + long timeStamp = System.currentTimeMillis(); + + List memberList = new ArrayList<>(); + // member1 success + Member member1 = new Member(); + member1.setIp("testip1" + timeStamp); + member1.setState(NodeState.UP); + memberList.add(member1); + // member2 exception + Member member2 = new Member(); + member2.setIp("testip2" + timeStamp); + member2.setState(NodeState.UP); + memberList.add(member2); + // member3 unhealth + Member member3 = new Member(); + member3.setIp("testip3" + timeStamp); + member3.setState(NodeState.DOWN); + memberList.add(member3); + + Mockito.when(serverMemberManager.allMembersWithoutSelf()).thenReturn(memberList); + + configExecutorMocked.when( + () -> ConfigExecutor.scheduleAsyncNotify(any(Runnable.class), anyLong(), any(TimeUnit.class))) + .thenAnswer(invocation -> null); + String dataId = "testDataId" + timeStamp; + String group = "testGroup"; + AsyncNotifyService asyncNotifyService = new AsyncNotifyService(serverMemberManager); + asyncNotifyService.handleConfigDataChangeEvent( + new ConfigDataChangeEvent(dataId, group, System.currentTimeMillis())); + + // expect schedule twice fail or exception response. + configExecutorMocked.verify( + () -> ConfigExecutor.executeAsyncNotify(any(AsyncNotifyService.AsyncRpcTask.class)), times(1)); + + } + + @Test + public void testExecuteAsyncRpcTask() throws Exception { + long timeStamp = System.currentTimeMillis(); + String dataId = "testDataId" + timeStamp; + String group = "testGroup"; + + List memberList = new ArrayList<>(); + // member1 success + Member member1 = new Member(); + member1.setIp("testip1" + timeStamp); + member1.setState(NodeState.UP); + memberList.add(member1); + // member2 exception + Member member2 = new Member(); + member2.setIp("testip2" + timeStamp); + member2.setState(NodeState.UP); + memberList.add(member2); + // member3 unhealth + Member member3 = new Member(); + member3.setIp("testip3" + timeStamp); + member3.setState(NodeState.DOWN); + memberList.add(member3); + Queue rpcQueue = new LinkedList<>(); + + for (Member member : memberList) { + // grpc report data change only + rpcQueue.add( + new AsyncNotifyService.NotifySingleRpcTask(dataId, group, null, null, System.currentTimeMillis(), + false, false, member)); + } + + AsyncNotifyService asyncNotifyService = new AsyncNotifyService(serverMemberManager); + + ReflectionTestUtils.setField(asyncNotifyService, "configClusterRpcClientProxy", configClusterRpcClientProxy); + Mockito.when(serverMemberManager.allMembersWithoutSelf()).thenReturn(memberList); + Mockito.when(serverMemberManager.hasMember(eq(member1.getAddress()))).thenReturn(true); + Mockito.when(serverMemberManager.hasMember(eq(member2.getAddress()))).thenReturn(true); + Mockito.when(serverMemberManager.hasMember(eq(member3.getAddress()))).thenReturn(true); + Mockito.when(serverMemberManager.stateCheck(eq(member1.getAddress()), eq(HEALTHY_CHECK_STATUS))) + .thenReturn(true); + Mockito.when(serverMemberManager.stateCheck(eq(member2.getAddress()), eq(HEALTHY_CHECK_STATUS))) + .thenReturn(true); + // mock stateCheck fail before notify member3 + Mockito.when(serverMemberManager.stateCheck(eq(member3.getAddress()), eq(HEALTHY_CHECK_STATUS))) + .thenReturn(false); + //mock syncConfigChange exception when notify member2 + Mockito.doThrow(new NacosException()).when(configClusterRpcClientProxy) + .syncConfigChange(eq(member2), any(ConfigChangeClusterSyncRequest.class), any(RequestCallBack.class)); + configExecutorMocked.when( + () -> ConfigExecutor.scheduleAsyncNotify(any(Runnable.class), anyLong(), any(TimeUnit.class))) + .thenAnswer(invocation -> null); + + asyncNotifyService.executeAsyncRpcTask(rpcQueue); + + Mockito.verify(configClusterRpcClientProxy, times(1)) + .syncConfigChange(eq(member1), any(ConfigChangeClusterSyncRequest.class), any(RequestCallBack.class)); + Mockito.verify(configClusterRpcClientProxy, times(1)) + .syncConfigChange(eq(member2), any(ConfigChangeClusterSyncRequest.class), any(RequestCallBack.class)); + Mockito.verify(configClusterRpcClientProxy, times(0)) + .syncConfigChange(eq(member3), any(ConfigChangeClusterSyncRequest.class), any(RequestCallBack.class)); + + //verify scheduleAsyncNotify member2 & member3 in task when syncConfigChange fail + configExecutorMocked.verify( + () -> ConfigExecutor.scheduleAsyncNotify(any(AsyncNotifyService.AsyncRpcTask.class), anyLong(), + any(TimeUnit.class)), times(2)); + + } +} diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/ConfigRowMapperInjectorTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/ConfigRowMapperInjectorTest.java new file mode 100644 index 00000000000..35df8476961 --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/ConfigRowMapperInjectorTest.java @@ -0,0 +1,472 @@ +/* + * 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.config.server.service.repository; + +import com.alibaba.nacos.config.server.model.ConfigAdvanceInfo; +import com.alibaba.nacos.config.server.model.ConfigAllInfo; +import com.alibaba.nacos.config.server.model.ConfigHistoryInfo; +import com.alibaba.nacos.config.server.model.ConfigInfo; +import com.alibaba.nacos.config.server.model.ConfigInfo4Beta; +import com.alibaba.nacos.config.server.model.ConfigInfo4Tag; +import com.alibaba.nacos.config.server.model.ConfigInfoAggr; +import com.alibaba.nacos.config.server.model.ConfigInfoBase; +import com.alibaba.nacos.config.server.model.ConfigInfoBetaWrapper; +import com.alibaba.nacos.config.server.model.ConfigInfoChanged; +import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; +import com.alibaba.nacos.config.server.model.ConfigInfoTagWrapper; +import com.alibaba.nacos.config.server.model.ConfigInfoWrapper; +import com.alibaba.nacos.config.server.model.ConfigKey; +import com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.ConfigHistoryDetailRowMapper; +import com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.ConfigInfo4BetaRowMapper; +import com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.ConfigInfoBetaWrapperRowMapper; +import com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.ConfigInfoChangedRowMapper; +import com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.ConfigInfoStateWrapperRowMapper; +import com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.ConfigInfoTagWrapperRowMapper; +import com.alibaba.nacos.persistence.repository.RowMapperManager; +import com.mysql.cj.jdbc.result.ResultSetImpl; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.sql.SQLException; +import java.sql.Timestamp; + +import static org.mockito.ArgumentMatchers.eq; + +@RunWith(SpringJUnit4ClassRunner.class) +public class ConfigRowMapperInjectorTest { + + @Test + public void testInit() { + ConfigRowMapperInjector configRowMapperInjector = new ConfigRowMapperInjector(); + Assert.assertEquals(ConfigRowMapperInjector.CONFIG_INFO_WRAPPER_ROW_MAPPER, RowMapperManager.getRowMapper( + ConfigRowMapperInjector.CONFIG_INFO_WRAPPER_ROW_MAPPER.getClass().getCanonicalName())); + } + + @Test + public void testConfigInfoTagWrapperRowMapper() throws SQLException { + ConfigInfoTagWrapper preConfig = new ConfigInfoTagWrapper(); + preConfig.setDataId("testDataId"); + preConfig.setGroup("group_id11"); + preConfig.setTenant("tenant_id11111"); + preConfig.setId(1243567898L); + preConfig.setTag("tag345678"); + preConfig.setLastModified(System.currentTimeMillis()); + preConfig.setAppName("app_name11111"); + preConfig.setType("type55555"); + preConfig.setContent("content1123434t"); + preConfig.setMd5("md54567"); + preConfig.setEncryptedDataKey("encrypted_data_key1324"); + ResultSetImpl resultSet = Mockito.mock(ResultSetImpl.class); + Mockito.when(resultSet.getString(eq("data_id"))).thenReturn(preConfig.getDataId()); + Mockito.when(resultSet.getString(eq("group_id"))).thenReturn(preConfig.getGroup()); + Mockito.when(resultSet.getString(eq("tenant_id"))).thenReturn(preConfig.getTenant()); + Mockito.when(resultSet.getString(eq("app_name"))).thenReturn(preConfig.getAppName()); + Mockito.when(resultSet.getString(eq("type"))).thenReturn(preConfig.getType()); + Mockito.when(resultSet.getTimestamp(eq("gmt_modified"))).thenReturn(new Timestamp(preConfig.getLastModified())); + Mockito.when(resultSet.getString(eq("content"))).thenReturn(preConfig.getContent()); + Mockito.when(resultSet.getLong(eq("id"))).thenReturn(preConfig.getId()); + Mockito.when(resultSet.getString(eq("md5"))).thenReturn(preConfig.getMd5()); + Mockito.when(resultSet.getString(eq("encrypted_data_key"))).thenReturn(preConfig.getEncryptedDataKey()); + Mockito.when(resultSet.getString(eq("tag_id"))).thenReturn(preConfig.getTag()); + ConfigInfoTagWrapperRowMapper configInfoWrapperRowMapper = new ConfigInfoTagWrapperRowMapper(); + ConfigInfoTagWrapper configInfoWrapper = configInfoWrapperRowMapper.mapRow(resultSet, 10); + Assert.assertEquals(preConfig, configInfoWrapper); + Assert.assertEquals(preConfig.getTag(), configInfoWrapper.getTag()); + } + + @Test + public void testConfigInfo4BetaRowMapper() throws SQLException { + ConfigInfo4Beta preConfig = new ConfigInfo4Beta(); + preConfig.setDataId("testDataId"); + preConfig.setGroup("group_id11"); + preConfig.setTenant("tenant_id11111"); + preConfig.setId(1243567898L); + preConfig.setAppName("app_name11111"); + preConfig.setType("type55555"); + preConfig.setContent("content1123434t"); + preConfig.setMd5("md54567"); + preConfig.setEncryptedDataKey("encrypted_data_key1324"); + preConfig.setBetaIps("127.0.0.1,127.0.0.2"); + ResultSetImpl resultSet = Mockito.mock(ResultSetImpl.class); + Mockito.when(resultSet.getString(eq("data_id"))).thenReturn(preConfig.getDataId()); + Mockito.when(resultSet.getString(eq("group_id"))).thenReturn(preConfig.getGroup()); + Mockito.when(resultSet.getString(eq("tenant_id"))).thenReturn(preConfig.getTenant()); + Mockito.when(resultSet.getString(eq("app_name"))).thenReturn(preConfig.getAppName()); + Mockito.when(resultSet.getString(eq("type"))).thenReturn(preConfig.getType()); + Mockito.when(resultSet.getString(eq("content"))).thenReturn(preConfig.getContent()); + Mockito.when(resultSet.getString(eq("beta_ips"))).thenReturn(preConfig.getBetaIps()); + Mockito.when(resultSet.getLong(eq("id"))).thenReturn(preConfig.getId()); + Mockito.when(resultSet.getString(eq("md5"))).thenReturn(preConfig.getMd5()); + Mockito.when(resultSet.getString(eq("encrypted_data_key"))).thenReturn(preConfig.getEncryptedDataKey()); + ConfigInfo4BetaRowMapper configInfoWrapperRowMapper = new ConfigInfo4BetaRowMapper(); + ConfigInfo4Beta configInfoWrapper = configInfoWrapperRowMapper.mapRow(resultSet, 10); + Assert.assertEquals(preConfig, configInfoWrapper); + Assert.assertEquals(preConfig.getBetaIps(), configInfoWrapper.getBetaIps()); + } + + @Test + public void testConfigInfoBetaWrapperRowMapper() throws SQLException { + ConfigInfoBetaWrapper preConfig = new ConfigInfoBetaWrapper(); + preConfig.setDataId("testDataId"); + preConfig.setGroup("group_id11"); + preConfig.setTenant("tenant_id11111"); + preConfig.setId(1243567898L); + preConfig.setLastModified(System.currentTimeMillis()); + preConfig.setAppName("app_name11111"); + preConfig.setType("type55555"); + preConfig.setContent("content1123434t"); + preConfig.setMd5("md54567"); + preConfig.setEncryptedDataKey("encrypted_data_key1324"); + ResultSetImpl resultSet = Mockito.mock(ResultSetImpl.class); + Mockito.when(resultSet.getString(eq("data_id"))).thenReturn(preConfig.getDataId()); + Mockito.when(resultSet.getString(eq("group_id"))).thenReturn(preConfig.getGroup()); + Mockito.when(resultSet.getString(eq("tenant_id"))).thenReturn(preConfig.getTenant()); + Mockito.when(resultSet.getString(eq("app_name"))).thenReturn(preConfig.getAppName()); + Mockito.when(resultSet.getString(eq("type"))).thenReturn(preConfig.getType()); + Mockito.when(resultSet.getTimestamp(eq("gmt_modified"))).thenReturn(new Timestamp(preConfig.getLastModified())); + Mockito.when(resultSet.getString(eq("content"))).thenReturn(preConfig.getContent()); + Mockito.when(resultSet.getLong(eq("id"))).thenReturn(preConfig.getId()); + Mockito.when(resultSet.getString(eq("md5"))).thenReturn(preConfig.getMd5()); + Mockito.when(resultSet.getString(eq("encrypted_data_key"))).thenReturn(preConfig.getEncryptedDataKey()); + ConfigInfoBetaWrapperRowMapper configInfoWrapperRowMapper = new ConfigInfoBetaWrapperRowMapper(); + ConfigInfoBetaWrapper configInfoWrapper = configInfoWrapperRowMapper.mapRow(resultSet, 10); + Assert.assertEquals(preConfig, configInfoWrapper); + } + + @Test + public void testConfigAdvanceInfoRowMapper() throws SQLException { + ConfigAdvanceInfo preConfig = new ConfigAdvanceInfo(); + preConfig.setModifyTime(System.currentTimeMillis()); + preConfig.setCreateTime(System.currentTimeMillis()); + preConfig.setCreateUser("user12345"); + preConfig.setCreateIp("1267890"); + preConfig.setDesc("desc23"); + preConfig.setUse("us345t"); + preConfig.setEffect("effect233"); + preConfig.setType("type132435"); + preConfig.setSchema("scheme344"); + ResultSetImpl resultSet = Mockito.mock(ResultSetImpl.class); + Mockito.when(resultSet.getString(eq("src_ip"))).thenReturn(preConfig.getCreateIp()); + Mockito.when(resultSet.getString(eq("type"))).thenReturn(preConfig.getType()); + Mockito.when(resultSet.getString(eq("c_desc"))).thenReturn(preConfig.getDesc()); + Mockito.when(resultSet.getString(eq("effect"))).thenReturn(preConfig.getEffect()); + Mockito.when(resultSet.getString(eq("src_user"))).thenReturn(preConfig.getCreateUser()); + Mockito.when(resultSet.getTimestamp(eq("gmt_modified"))).thenReturn(new Timestamp(preConfig.getModifyTime())); + Mockito.when(resultSet.getTimestamp(eq("gmt_create"))).thenReturn(new Timestamp(preConfig.getCreateTime())); + Mockito.when(resultSet.getString(eq("c_use"))).thenReturn(preConfig.getUse()); + Mockito.when(resultSet.getString(eq("c_schema"))).thenReturn(preConfig.getSchema()); + ConfigRowMapperInjector.ConfigAdvanceInfoRowMapper configInfoWrapperRowMapper = new ConfigRowMapperInjector.ConfigAdvanceInfoRowMapper(); + ConfigAdvanceInfo configInfoWrapper = configInfoWrapperRowMapper.mapRow(resultSet, 10); + Assert.assertEquals(preConfig, configInfoWrapper); + } + + @Test + public void testConfigAllInfoRowMapper() throws SQLException { + ConfigAllInfo preConfig = new ConfigAllInfo(); + preConfig.setDataId("testDataId"); + preConfig.setGroup("group_id11"); + preConfig.setTenant("tenant_id11111"); + preConfig.setModifyTime(System.currentTimeMillis()); + preConfig.setId(1243567898L); + preConfig.setAppName("app_name11111"); + preConfig.setType("type55555"); + preConfig.setContent("content1123434t"); + preConfig.setMd5("md54567"); + preConfig.setEncryptedDataKey("encrypted_data_key1324"); + ResultSetImpl resultSet = Mockito.mock(ResultSetImpl.class); + + Mockito.when(resultSet.getString(eq("data_id"))).thenReturn(preConfig.getDataId()); + Mockito.when(resultSet.getString(eq("group_id"))).thenReturn(preConfig.getGroup()); + Mockito.when(resultSet.getString(eq("tenant_id"))).thenReturn(preConfig.getTenant()); + Mockito.when(resultSet.getString(eq("app_name"))).thenReturn(preConfig.getAppName()); + Mockito.when(resultSet.getString(eq("type"))).thenReturn(preConfig.getType()); + Mockito.when(resultSet.getString(eq("content"))).thenReturn(preConfig.getContent()); + Mockito.when(resultSet.getTimestamp(eq("gmt_modified"))).thenReturn(new Timestamp(preConfig.getModifyTime())); + + Mockito.when(resultSet.getLong(eq("id"))).thenReturn(preConfig.getId()); + Mockito.when(resultSet.getString(eq("md5"))).thenReturn(preConfig.getMd5()); + Mockito.when(resultSet.getString(eq("encrypted_data_key"))).thenReturn(preConfig.getEncryptedDataKey()); + ConfigRowMapperInjector.ConfigAllInfoRowMapper configInfoWrapperRowMapper = new ConfigRowMapperInjector.ConfigAllInfoRowMapper(); + + ConfigAllInfo configInfoWrapper = configInfoWrapperRowMapper.mapRow(resultSet, 10); + Assert.assertEquals(preConfig, configInfoWrapper); + } + + @Test + public void testConfigInfoRowMapper() throws SQLException { + + ConfigInfo preConfig = new ConfigInfo(); + preConfig.setDataId("testDataId"); + preConfig.setGroup("group_id11"); + preConfig.setTenant("tenant_id11111"); + preConfig.setId(1243567898L); + preConfig.setAppName("app_name11111"); + preConfig.setType("type55555"); + preConfig.setContent("content1123434t"); + preConfig.setMd5("md54567"); + preConfig.setEncryptedDataKey("encrypted_data_key1324"); + ResultSetImpl resultSet = Mockito.mock(ResultSetImpl.class); + Mockito.when(resultSet.getString(eq("data_id"))).thenReturn(preConfig.getDataId()); + Mockito.when(resultSet.getString(eq("group_id"))).thenReturn(preConfig.getGroup()); + Mockito.when(resultSet.getString(eq("tenant_id"))).thenReturn(preConfig.getTenant()); + Mockito.when(resultSet.getString(eq("app_name"))).thenReturn(preConfig.getAppName()); + Mockito.when(resultSet.getString(eq("type"))).thenReturn(preConfig.getType()); + Mockito.when(resultSet.getString(eq("content"))).thenReturn(preConfig.getContent()); + Mockito.when(resultSet.getLong(eq("id"))).thenReturn(preConfig.getId()); + Mockito.when(resultSet.getString(eq("md5"))).thenReturn(preConfig.getMd5()); + Mockito.when(resultSet.getString(eq("encrypted_data_key"))).thenReturn(preConfig.getEncryptedDataKey()); + ConfigRowMapperInjector.ConfigInfoRowMapper configInfoWrapperRowMapper = new ConfigRowMapperInjector.ConfigInfoRowMapper(); + ConfigInfo configInfoWrapper = configInfoWrapperRowMapper.mapRow(resultSet, 10); + Assert.assertEquals(preConfig, configInfoWrapper); + } + + @Test + public void testConfigInfoWrapperRowMapper() throws SQLException { + + ConfigInfoWrapper preConfig = new ConfigInfoWrapper(); + preConfig.setDataId("testDataId"); + preConfig.setGroup("group_id11"); + preConfig.setTenant("tenant_id11111"); + preConfig.setLastModified(System.currentTimeMillis()); + preConfig.setId(1243567898L); + preConfig.setAppName("app_name11111"); + preConfig.setType("type55555"); + preConfig.setContent("content1123434t"); + preConfig.setMd5("md54567"); + preConfig.setEncryptedDataKey("encrypted_data_key1324"); + ResultSetImpl resultSet = Mockito.mock(ResultSetImpl.class); + Mockito.when(resultSet.getString(eq("data_id"))).thenReturn(preConfig.getDataId()); + Mockito.when(resultSet.getString(eq("group_id"))).thenReturn(preConfig.getGroup()); + Mockito.when(resultSet.getString(eq("tenant_id"))).thenReturn(preConfig.getTenant()); + Mockito.when(resultSet.getString(eq("app_name"))).thenReturn(preConfig.getAppName()); + Mockito.when(resultSet.getString(eq("type"))).thenReturn(preConfig.getType()); + Mockito.when(resultSet.getString(eq("content"))).thenReturn(preConfig.getContent()); + Mockito.when(resultSet.getLong(eq("id"))).thenReturn(preConfig.getId()); + Mockito.when(resultSet.getTimestamp(eq("gmt_modified"))).thenReturn(new Timestamp(preConfig.getLastModified())); + Mockito.when(resultSet.getString(eq("md5"))).thenReturn(preConfig.getMd5()); + Mockito.when(resultSet.getString(eq("encrypted_data_key"))).thenReturn(preConfig.getEncryptedDataKey()); + ConfigRowMapperInjector.ConfigInfoWrapperRowMapper configInfoWrapperRowMapper = new ConfigRowMapperInjector.ConfigInfoWrapperRowMapper(); + ConfigInfoWrapper configInfoWrapper = configInfoWrapperRowMapper.mapRow(resultSet, 10); + Assert.assertEquals(preConfig, configInfoWrapper); + + } + + @Test + public void testConfigInfo4TagRowMapper() throws SQLException { + + ConfigInfo4Tag preConfig = new ConfigInfo4Tag(); + preConfig.setDataId("testDataId"); + preConfig.setGroup("group_id11"); + preConfig.setTenant("tenant_id11111"); + preConfig.setId(1243567898L); + preConfig.setAppName("app_name11111"); + preConfig.setType("type55555"); + preConfig.setContent("content1123434t"); + preConfig.setMd5("md54567"); + preConfig.setEncryptedDataKey("encrypted_data_key1324"); + preConfig.setTag("tag567890"); + ResultSetImpl resultSet = Mockito.mock(ResultSetImpl.class); + Mockito.when(resultSet.getString(eq("data_id"))).thenReturn(preConfig.getDataId()); + Mockito.when(resultSet.getString(eq("group_id"))).thenReturn(preConfig.getGroup()); + Mockito.when(resultSet.getString(eq("tenant_id"))).thenReturn(preConfig.getTenant()); + Mockito.when(resultSet.getString(eq("app_name"))).thenReturn(preConfig.getAppName()); + Mockito.when(resultSet.getString(eq("type"))).thenReturn(preConfig.getType()); + Mockito.when(resultSet.getString(eq("content"))).thenReturn(preConfig.getContent()); + Mockito.when(resultSet.getLong(eq("id"))).thenReturn(preConfig.getId()); + Mockito.when(resultSet.getString(eq("tag_id"))).thenReturn(preConfig.getTag()); + Mockito.when(resultSet.getString(eq("md5"))).thenReturn(preConfig.getMd5()); + Mockito.when(resultSet.getString(eq("encrypted_data_key"))).thenReturn(preConfig.getEncryptedDataKey()); + ConfigRowMapperInjector.ConfigInfo4TagRowMapper configInfoWrapperRowMapper = new ConfigRowMapperInjector.ConfigInfo4TagRowMapper(); + ConfigInfo4Tag configInfoWrapper = configInfoWrapperRowMapper.mapRow(resultSet, 10); + Assert.assertEquals(preConfig, configInfoWrapper); + + } + + @Test + public void testConfigInfoBaseRowMapper() throws SQLException { + + ConfigInfoBase preConfig = new ConfigInfoBase(); + preConfig.setDataId("testDataId"); + preConfig.setGroup("group_id11"); + preConfig.setId(1243567898L); + preConfig.setContent("content1123434t"); + ResultSetImpl resultSet = Mockito.mock(ResultSetImpl.class); + Mockito.when(resultSet.getString(eq("data_id"))).thenReturn(preConfig.getDataId()); + Mockito.when(resultSet.getString(eq("group_id"))).thenReturn(preConfig.getGroup()); + Mockito.when(resultSet.getString(eq("content"))).thenReturn(preConfig.getContent()); + Mockito.when(resultSet.getLong(eq("id"))).thenReturn(preConfig.getId()); + ConfigRowMapperInjector.ConfigInfoBaseRowMapper configInfoWrapperRowMapper = new ConfigRowMapperInjector.ConfigInfoBaseRowMapper(); + ConfigInfoBase configInfoWrapper = configInfoWrapperRowMapper.mapRow(resultSet, 10); + Assert.assertEquals(preConfig, configInfoWrapper); + + } + + @Test + public void testConfigInfoAggrRowMapper() throws SQLException { + + ConfigInfoAggr preConfig = new ConfigInfoAggr(); + preConfig.setDataId("testDataId"); + preConfig.setGroup("group_id11"); + preConfig.setContent("content1123434t"); + preConfig.setDatumId("datum4567890"); + preConfig.setTenant("tenang34567890"); + preConfig.setAppName("app3456789"); + ResultSetImpl resultSet = Mockito.mock(ResultSetImpl.class); + Mockito.when(resultSet.getString(eq("data_id"))).thenReturn(preConfig.getDataId()); + Mockito.when(resultSet.getString(eq("group_id"))).thenReturn(preConfig.getGroup()); + Mockito.when(resultSet.getString(eq("tenant_id"))).thenReturn(preConfig.getTenant()); + Mockito.when(resultSet.getString(eq("datum_id"))).thenReturn(preConfig.getDatumId()); + Mockito.when(resultSet.getString(eq("content"))).thenReturn(preConfig.getContent()); + Mockito.when(resultSet.getString(eq("app"))).thenReturn(preConfig.getAppName()); + ConfigRowMapperInjector.ConfigInfoAggrRowMapper configInfoWrapperRowMapper = new ConfigRowMapperInjector.ConfigInfoAggrRowMapper(); + + ConfigInfoAggr configInfoWrapper = configInfoWrapperRowMapper.mapRow(resultSet, 10); + Assert.assertEquals(preConfig, configInfoWrapper); + + } + + @Test + public void testConfigInfoChangedRowMapper() throws SQLException { + + ConfigInfoChanged preConfig = new ConfigInfoChanged(); + preConfig.setDataId("testDataId"); + preConfig.setGroup("group_id11"); + preConfig.setTenant("tenang34567890"); + ResultSetImpl resultSet = Mockito.mock(ResultSetImpl.class); + Mockito.when(resultSet.getString(eq("data_id"))).thenReturn(preConfig.getDataId()); + Mockito.when(resultSet.getString(eq("group_id"))).thenReturn(preConfig.getGroup()); + Mockito.when(resultSet.getString(eq("tenant_id"))).thenReturn(preConfig.getTenant()); + ConfigInfoChangedRowMapper configInfoWrapperRowMapper = new ConfigInfoChangedRowMapper(); + ConfigInfoChanged configInfoWrapper = configInfoWrapperRowMapper.mapRow(resultSet, 10); + Assert.assertEquals(preConfig, configInfoWrapper); + + } + + @Test + public void testConfigHistoryRowMapper() throws SQLException { + + ConfigHistoryInfo preConfig = new ConfigHistoryInfo(); + preConfig.setDataId("testDataId"); + preConfig.setGroup("group_id11"); + preConfig.setTenant("tenant_id11111"); + preConfig.setId(1243567898L); + preConfig.setAppName("app_name11111"); + preConfig.setSrcIp("srciprtyui"); + preConfig.setSrcUser("234567890user"); + preConfig.setOpType("D2345678"); + preConfig.setCreatedTime(new Timestamp(System.currentTimeMillis())); + preConfig.setLastModifiedTime(new Timestamp(System.currentTimeMillis())); + ResultSetImpl resultSet = Mockito.mock(ResultSetImpl.class); + Mockito.when(resultSet.getString(eq("data_id"))).thenReturn(preConfig.getDataId()); + Mockito.when(resultSet.getString(eq("group_id"))).thenReturn(preConfig.getGroup()); + Mockito.when(resultSet.getString(eq("tenant_id"))).thenReturn(preConfig.getTenant()); + Mockito.when(resultSet.getString(eq("app_name"))).thenReturn(preConfig.getAppName()); + Mockito.when(resultSet.getString(eq("op_type"))).thenReturn(preConfig.getOpType()); + Mockito.when(resultSet.getString(eq("src_user"))).thenReturn(preConfig.getSrcUser()); + Mockito.when(resultSet.getLong(eq("nid"))).thenReturn(preConfig.getId()); + Mockito.when(resultSet.getString(eq("src_ip"))).thenReturn(preConfig.getSrcIp()); + Mockito.when(resultSet.getTimestamp(eq("gmt_modified"))).thenReturn(preConfig.getLastModifiedTime()); + Mockito.when(resultSet.getTimestamp(eq("gmt_create"))).thenReturn(preConfig.getCreatedTime()); + ConfigRowMapperInjector.ConfigHistoryRowMapper configInfoWrapperRowMapper = new ConfigRowMapperInjector.ConfigHistoryRowMapper(); + + ConfigHistoryInfo configInfoWrapper = configInfoWrapperRowMapper.mapRow(resultSet, 10); + Assert.assertEquals(preConfig, configInfoWrapper); + + } + + @Test + public void testConfigHistoryDetailRowMapper() throws SQLException { + + ConfigHistoryInfo preConfig = new ConfigHistoryInfo(); + preConfig.setDataId("testDataId"); + preConfig.setGroup("group_id11"); + preConfig.setTenant("tenant_id11111"); + preConfig.setId(1243567898L); + preConfig.setAppName("app_name11111"); + preConfig.setContent("content2345678"); + preConfig.setMd5("md5234567890"); + preConfig.setSrcIp("srciprtyui"); + preConfig.setSrcUser("234567890user"); + preConfig.setOpType("D2345678"); + preConfig.setCreatedTime(new Timestamp(System.currentTimeMillis())); + preConfig.setLastModifiedTime(new Timestamp(System.currentTimeMillis())); + preConfig.setContent("content1123434t"); + preConfig.setMd5("md54567"); + preConfig.setEncryptedDataKey("key3456789"); + ResultSetImpl resultSet = Mockito.mock(ResultSetImpl.class); + Mockito.when(resultSet.getString(eq("data_id"))).thenReturn(preConfig.getDataId()); + Mockito.when(resultSet.getString(eq("group_id"))).thenReturn(preConfig.getGroup()); + Mockito.when(resultSet.getString(eq("tenant_id"))).thenReturn(preConfig.getTenant()); + Mockito.when(resultSet.getString(eq("app_name"))).thenReturn(preConfig.getAppName()); + Mockito.when(resultSet.getString(eq("op_type"))).thenReturn(preConfig.getOpType()); + Mockito.when(resultSet.getString(eq("src_user"))).thenReturn(preConfig.getSrcUser()); + Mockito.when(resultSet.getString(eq("content"))).thenReturn(preConfig.getContent()); + Mockito.when(resultSet.getString(eq("md5"))).thenReturn(preConfig.getMd5()); + Mockito.when(resultSet.getString(eq("encrypted_data_key"))).thenReturn(preConfig.getEncryptedDataKey()); + Mockito.when(resultSet.getLong(eq("nid"))).thenReturn(preConfig.getId()); + Mockito.when(resultSet.getString(eq("src_ip"))).thenReturn(preConfig.getSrcIp()); + Mockito.when(resultSet.getTimestamp(eq("gmt_modified"))).thenReturn(preConfig.getLastModifiedTime()); + Mockito.when(resultSet.getTimestamp(eq("gmt_create"))).thenReturn(preConfig.getCreatedTime()); + + ConfigHistoryDetailRowMapper configInfoWrapperRowMapper = new ConfigHistoryDetailRowMapper(); + ConfigHistoryInfo configInfoWrapper = configInfoWrapperRowMapper.mapRow(resultSet, 10); + Assert.assertEquals(preConfig, configInfoWrapper); + + } + + @Test + public void testConfigInfoStateWrapperRowMapper() throws SQLException { + + ConfigInfoStateWrapper preConfig = new ConfigInfoStateWrapper(); + preConfig.setDataId("testDataId"); + preConfig.setGroup("group_id11"); + preConfig.setTenant("tenant_id11111"); + preConfig.setId(1243567898L); + ResultSetImpl resultSet = Mockito.mock(ResultSetImpl.class); + Mockito.when(resultSet.getString(eq("data_id"))).thenReturn(preConfig.getDataId()); + Mockito.when(resultSet.getString(eq("group_id"))).thenReturn(preConfig.getGroup()); + Mockito.when(resultSet.getString(eq("tenant_id"))).thenReturn(preConfig.getTenant()); + Mockito.when(resultSet.getTimestamp(eq("gmt_modified"))).thenReturn(new Timestamp(preConfig.getLastModified())); + + Mockito.when(resultSet.getLong(eq("id"))).thenReturn(preConfig.getId()); + ConfigInfoStateWrapperRowMapper configInfoWrapperRowMapper = new ConfigInfoStateWrapperRowMapper(); + ConfigInfoStateWrapper configInfoWrapper = configInfoWrapperRowMapper.mapRow(resultSet, 10); + Assert.assertEquals(preConfig, configInfoWrapper); + + } + + @Test + public void testConfigKeyRowMapper() throws SQLException { + ConfigKey preConfig = new ConfigKey(); + preConfig.setDataId("testDataId"); + preConfig.setGroup("group_id11"); + preConfig.setAppName("appertyui4567"); + ResultSetImpl resultSet = Mockito.mock(ResultSetImpl.class); + Mockito.when(resultSet.getString(eq("data_id"))).thenReturn(preConfig.getDataId()); + Mockito.when(resultSet.getString(eq("group_id"))).thenReturn(preConfig.getGroup()); + Mockito.when(resultSet.getString(eq("app_name"))).thenReturn(preConfig.getAppName()); + ConfigRowMapperInjector.ConfigKeyRowMapper configInfoWrapperRowMapper = new ConfigRowMapperInjector.ConfigKeyRowMapper(); + + ConfigKey configInfoWrapper = configInfoWrapperRowMapper.mapRow(resultSet, 10); + Assert.assertEquals(preConfig, configInfoWrapper); + + } + +} diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoAggrPersistServiceImplTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoAggrPersistServiceImplTest.java new file mode 100644 index 00000000000..c6607c3c98e --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoAggrPersistServiceImplTest.java @@ -0,0 +1,247 @@ +/* + * 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.config.server.service.repository.embedded; + +import com.alibaba.nacos.config.server.model.ConfigInfoAggr; +import com.alibaba.nacos.config.server.model.ConfigInfoChanged; +import com.alibaba.nacos.persistence.datasource.DataSourceService; +import com.alibaba.nacos.persistence.datasource.DynamicDataSource; +import com.alibaba.nacos.persistence.model.Page; +import com.alibaba.nacos.persistence.repository.embedded.EmbeddedStorageContextHolder; +import com.alibaba.nacos.persistence.repository.embedded.operate.DatabaseOperate; +import com.alibaba.nacos.sys.env.EnvUtil; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_AGGR_ROW_MAPPER; +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_CHANGED_ROW_MAPPER; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +/** + * test for embedded config aggr. + * @author shiyiyue + */ +@RunWith(SpringJUnit4ClassRunner.class) +public class EmbeddedConfigInfoAggrPersistServiceImplTest { + + private EmbeddedConfigInfoAggrPersistServiceImpl embededConfigInfoAggrPersistService; + + @Mock + private DataSourceService dataSourceService; + + MockedStatic envUtilMockedStatic; + + MockedStatic embeddedStorageContextHolderMockedStatic; + + MockedStatic dynamicDataSourceMockedStatic; + + @Mock + DynamicDataSource dynamicDataSource; + + @Mock + DatabaseOperate databaseOperate; + + @Before + public void before() { + embeddedStorageContextHolderMockedStatic = Mockito.mockStatic(EmbeddedStorageContextHolder.class); + dynamicDataSourceMockedStatic = Mockito.mockStatic(DynamicDataSource.class); + envUtilMockedStatic = Mockito.mockStatic(EnvUtil.class); + when(DynamicDataSource.getInstance()).thenReturn(dynamicDataSource); + when(dynamicDataSource.getDataSource()).thenReturn(dataSourceService); + when(dataSourceService.getDataSourceType()).thenReturn("derby"); + envUtilMockedStatic.when(() -> EnvUtil.getProperty(anyString(), eq(Boolean.class), eq(false))) + .thenReturn(false); + embededConfigInfoAggrPersistService = new EmbeddedConfigInfoAggrPersistServiceImpl(databaseOperate); + } + + @After + public void after() { + dynamicDataSourceMockedStatic.close(); + envUtilMockedStatic.close(); + embeddedStorageContextHolderMockedStatic.close(); + } + + @Test + public void testAddAggrConfigInfoOfEqualContent() { + String dataId = "dataId111"; + String group = "group"; + String tenant = "tenant"; + String datumId = "datumId"; + String appName = "appname1234"; + String content = "content1234"; + + //mock query datumId and equal with current content param. + String existContent = "content1234"; + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, datumId}), + eq(String.class))).thenReturn(existContent); + //mock insert success + Mockito.when(databaseOperate.update(any(List.class))).thenReturn(true); + + boolean result = embededConfigInfoAggrPersistService.addAggrConfigInfo(dataId, group, tenant, datumId, appName, + content); + Assert.assertTrue(result); + } + + @Test + public void testAddAggrConfigInfoOfAddNewContent() { + String dataId = "dataId111"; + String group = "group"; + String tenant = "tenant"; + String datumId = "datumId"; + String appName = "appname1234"; + String content = "content1234"; + + //mock query datumId and return null. + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, datumId}), + eq(String.class))).thenReturn(null); + //mock insert success + Mockito.when(databaseOperate.update(any(List.class))).thenReturn(true); + + //execute + boolean result = embededConfigInfoAggrPersistService.addAggrConfigInfo(dataId, group, tenant, datumId, appName, + content); + Assert.assertTrue(result); + } + + @Test + public void testAddAggrConfigInfoOfUpdateNotEqualContent() { + String dataId = "dataId111"; + String group = "group"; + String tenant = "tenant"; + String datumId = "datumId"; + String appName = "appname1234"; + String content = "content1234"; + + //mock query datumId + String existContent = "existContent111"; + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, datumId}), + eq(String.class))).thenReturn(existContent); + //mock update success,return 1 + Mockito.when(databaseOperate.update(any(List.class))).thenReturn(true); + + //mock update content + boolean result = embededConfigInfoAggrPersistService.addAggrConfigInfo(dataId, group, tenant, datumId, appName, + content); + Assert.assertTrue(result); + + } + + @Test + public void testBatchPublishAggrSuccess() { + + String dataId = "dataId111"; + String group = "group"; + String tenant = "tenant"; + //mock query datumId and equal with current content param. + Mockito.when( + databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, "d1"}), eq(String.class))) + .thenReturn("c1"); + Mockito.when( + databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, "d2"}), eq(String.class))) + .thenReturn("c2"); + Mockito.when( + databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, "d3"}), eq(String.class))) + .thenReturn("c3"); + Mockito.when(databaseOperate.update(any(List.class))).thenReturn(true); + + Map datumMap = new HashMap<>(); + datumMap.put("d1", "c1"); + datumMap.put("d2", "c2"); + datumMap.put("d3", "c3"); + String appName = "appname1234"; + boolean result = embededConfigInfoAggrPersistService.batchPublishAggr(dataId, group, tenant, datumMap, appName); + Assert.assertTrue(result); + } + + @Test + public void testAggrConfigInfoCount() { + String dataId = "dataId11122"; + String group = "group"; + String tenant = "tenant"; + + //mock select count of aggr. + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant}), eq(Integer.class))) + .thenReturn(new Integer(101)); + int result = embededConfigInfoAggrPersistService.aggrConfigInfoCount(dataId, group, tenant); + Assert.assertEquals(101, result); + + } + + @Test + public void testFindConfigInfoAggrByPage() { + String dataId = "dataId111"; + String group = "group"; + String tenant = "tenant"; + + //mock query count. + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant}), eq(Integer.class))) + .thenReturn(101); + //mock query page list + List configInfoAggrs = new ArrayList<>(); + configInfoAggrs.add(new ConfigInfoAggr()); + configInfoAggrs.add(new ConfigInfoAggr()); + configInfoAggrs.add(new ConfigInfoAggr()); + + Mockito.when(databaseOperate.queryMany(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_AGGR_ROW_MAPPER))).thenReturn(configInfoAggrs); + int pageNo = 1; + int pageSize = 120; + Page configInfoAggrByPage = embededConfigInfoAggrPersistService.findConfigInfoAggrByPage(dataId, + group, tenant, pageNo, pageSize); + Assert.assertEquals(101, configInfoAggrByPage.getTotalCount()); + Assert.assertEquals(configInfoAggrs, configInfoAggrByPage.getPageItems()); + + } + + @Test + public void testFindAllAggrGroup() { + List configList = new ArrayList<>(); + configList.add(create("dataId", 0)); + configList.add(create("dataId", 1)); + //mock return list + Mockito.when(databaseOperate.queryMany(anyString(), eq(new Object[] {}), eq(CONFIG_INFO_CHANGED_ROW_MAPPER))) + .thenReturn(configList); + + List allAggrGroup = embededConfigInfoAggrPersistService.findAllAggrGroup(); + Assert.assertEquals(configList, allAggrGroup); + + } + + private ConfigInfoChanged create(String dataID, int i) { + ConfigInfoChanged hasDatum = new ConfigInfoChanged(); + hasDatum.setDataId(dataID + i); + hasDatum.setTenant("tenant1"); + hasDatum.setGroup("group1"); + return hasDatum; + } + +} diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoBetaPersistServiceImplTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoBetaPersistServiceImplTest.java new file mode 100644 index 00000000000..9a8c859b5d6 --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoBetaPersistServiceImplTest.java @@ -0,0 +1,331 @@ +/* + * 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.config.server.service.repository.embedded; + +import com.alibaba.nacos.common.utils.MD5Utils; +import com.alibaba.nacos.config.server.constant.Constants; +import com.alibaba.nacos.config.server.model.ConfigInfo; +import com.alibaba.nacos.config.server.model.ConfigInfoBetaWrapper; +import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; +import com.alibaba.nacos.config.server.model.ConfigOperateResult; +import com.alibaba.nacos.persistence.datasource.DataSourceService; +import com.alibaba.nacos.persistence.datasource.DynamicDataSource; +import com.alibaba.nacos.persistence.model.Page; +import com.alibaba.nacos.persistence.repository.embedded.EmbeddedStorageContextHolder; +import com.alibaba.nacos.persistence.repository.embedded.operate.DatabaseOperate; +import com.alibaba.nacos.sys.env.EnvUtil; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; + +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_BETA_WRAPPER_ROW_MAPPER; +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; + +/** + * test for embedded config beta. + * + * @author shiyiyue + */ +@RunWith(SpringJUnit4ClassRunner.class) +public class EmbeddedConfigInfoBetaPersistServiceImplTest { + + private EmbeddedConfigInfoBetaPersistServiceImpl embeddedConfigInfoBetaPersistService; + + @Mock + private DataSourceService dataSourceService; + + MockedStatic envUtilMockedStatic; + + MockedStatic embeddedStorageContextHolderMockedStatic; + + MockedStatic dynamicDataSourceMockedStatic; + + @Mock + DynamicDataSource dynamicDataSource; + + @Mock + DatabaseOperate databaseOperate; + + @Before + public void before() { + embeddedStorageContextHolderMockedStatic = Mockito.mockStatic(EmbeddedStorageContextHolder.class); + dynamicDataSourceMockedStatic = Mockito.mockStatic(DynamicDataSource.class); + envUtilMockedStatic = Mockito.mockStatic(EnvUtil.class); + when(DynamicDataSource.getInstance()).thenReturn(dynamicDataSource); + when(dynamicDataSource.getDataSource()).thenReturn(dataSourceService); + when(dataSourceService.getDataSourceType()).thenReturn("derby"); + envUtilMockedStatic.when(() -> EnvUtil.getProperty(anyString(), eq(Boolean.class), eq(false))) + .thenReturn(false); + embeddedConfigInfoBetaPersistService = new EmbeddedConfigInfoBetaPersistServiceImpl(databaseOperate); + } + + @After + public void after() { + dynamicDataSourceMockedStatic.close(); + envUtilMockedStatic.close(); + embeddedStorageContextHolderMockedStatic.close(); + } + + @Test + public void testInsertOrUpdateBetaOfUpdate() { + String dataId = "betaDataId113"; + String group = "group"; + String tenant = "tenant"; + //mock exist beta + ConfigInfoStateWrapper mockedConfigInfoStateWrapper = new ConfigInfoStateWrapper(); + mockedConfigInfoStateWrapper.setDataId(dataId); + mockedConfigInfoStateWrapper.setGroup(group); + mockedConfigInfoStateWrapper.setTenant(tenant); + mockedConfigInfoStateWrapper.setId(123456L); + mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))) + .thenReturn(mockedConfigInfoStateWrapper, mockedConfigInfoStateWrapper); + //execute + String betaIps = "betaips..."; + String srcIp = "srcUp..."; + String srcUser = "srcUser..."; + String appName = "appname"; + String content = "content111"; + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key34567"); + ConfigOperateResult configOperateResult = embeddedConfigInfoBetaPersistService.insertOrUpdateBeta(configInfo, + betaIps, srcIp, srcUser); + //expect return obj + Assert.assertEquals(mockedConfigInfoStateWrapper.getId(), configOperateResult.getId()); + Assert.assertEquals(mockedConfigInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + //verify update to be invoked + embeddedStorageContextHolderMockedStatic.verify( + () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(configInfo.getContent()), + eq(configInfo.getMd5()), eq(betaIps), eq(srcIp), eq(srcUser), any(Timestamp.class), + eq(configInfo.getAppName()), eq(configInfo.getEncryptedDataKey()), eq(dataId), eq(group), + eq(tenant)), times(1)); + + } + + @Test + public void testInsertOrUpdateBetaOfAdd() { + String dataId = "betaDataId113"; + String group = "group113"; + String tenant = "tenant113"; + //mock exist beta + ConfigInfoStateWrapper mockedConfigInfoStateWrapper = new ConfigInfoStateWrapper(); + mockedConfigInfoStateWrapper.setDataId(dataId); + mockedConfigInfoStateWrapper.setGroup(group); + mockedConfigInfoStateWrapper.setTenant(tenant); + mockedConfigInfoStateWrapper.setId(123456L); + mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(null).thenReturn(mockedConfigInfoStateWrapper); + + String betaIps = "betaips..."; + String srcIp = "srcUp..."; + String srcUser = "srcUser..."; + String appName = "appname"; + String content = "content111"; + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key34567"); + //execute + ConfigOperateResult configOperateResult = embeddedConfigInfoBetaPersistService.insertOrUpdateBeta(configInfo, + betaIps, srcIp, srcUser); + //expect return obj + Assert.assertEquals(mockedConfigInfoStateWrapper.getId(), configOperateResult.getId()); + Assert.assertEquals(mockedConfigInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + //verify add to be invoked + embeddedStorageContextHolderMockedStatic.verify( + () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(dataId), eq(group), eq(tenant), + eq(configInfo.getAppName()), eq(configInfo.getContent()), eq(configInfo.getMd5()), eq(betaIps), + eq(srcIp), eq(srcUser), any(Timestamp.class), any(Timestamp.class), + eq(configInfo.getEncryptedDataKey())), times(1)); + } + + @Test + public void testInsertOrUpdateBetaCasOfUpdate() { + String dataId = "betaDataId113"; + String group = "group"; + String tenant = "tenant"; + //mock exist beta + ConfigInfoStateWrapper mockedConfigInfoStateWrapper = new ConfigInfoStateWrapper(); + mockedConfigInfoStateWrapper.setDataId(dataId); + mockedConfigInfoStateWrapper.setGroup(group); + mockedConfigInfoStateWrapper.setTenant(tenant); + mockedConfigInfoStateWrapper.setId(123456L); + mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))) + .thenReturn(mockedConfigInfoStateWrapper, mockedConfigInfoStateWrapper); + + //execute + + String appName = "appname"; + String content = "content111"; + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key34567"); + configInfo.setMd5("casMd5"); + //mock cas update + Mockito.when(databaseOperate.blockUpdate()).thenReturn(true); + String betaIps = "betaips..."; + String srcIp = "srcUp..."; + String srcUser = "srcUser..."; + ConfigOperateResult configOperateResult = embeddedConfigInfoBetaPersistService.insertOrUpdateBetaCas(configInfo, + betaIps, srcIp, srcUser); + //expect return obj + Assert.assertEquals(mockedConfigInfoStateWrapper.getId(), configOperateResult.getId()); + Assert.assertEquals(mockedConfigInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + //verify cas update to be invoked + embeddedStorageContextHolderMockedStatic.verify( + () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(configInfo.getContent()), + eq(MD5Utils.md5Hex(content, Constants.PERSIST_ENCODE)), eq(betaIps), eq(srcIp), eq(srcUser), + any(Timestamp.class), eq(appName), eq(dataId), eq(group), eq(tenant), eq(configInfo.getMd5())), + times(1)); + + } + + @Test + public void testInsertOrUpdateBetaCasOfAdd() { + String dataId = "betaDataId113"; + String group = "group113"; + String tenant = "tenant113"; + //mock exist beta + ConfigInfoStateWrapper mockedConfigInfoStateWrapper = new ConfigInfoStateWrapper(); + mockedConfigInfoStateWrapper.setDataId(dataId); + mockedConfigInfoStateWrapper.setGroup(group); + mockedConfigInfoStateWrapper.setTenant(tenant); + mockedConfigInfoStateWrapper.setId(123456L); + mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(null).thenReturn(mockedConfigInfoStateWrapper); + + String betaIps = "betaips..."; + String srcIp = "srcUp..."; + String srcUser = "srcUser..."; + String appName = "appname"; + String content = "content111"; + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key34567"); + //execute + ConfigOperateResult configOperateResult = embeddedConfigInfoBetaPersistService.insertOrUpdateBetaCas(configInfo, + betaIps, srcIp, srcUser); + //expect return obj + Assert.assertEquals(mockedConfigInfoStateWrapper.getId(), configOperateResult.getId()); + Assert.assertEquals(mockedConfigInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + //verify add to be invoked + embeddedStorageContextHolderMockedStatic.verify( + () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(dataId), eq(group), eq(tenant), + eq(configInfo.getAppName()), eq(configInfo.getContent()), eq(configInfo.getMd5()), eq(betaIps), + eq(srcIp), eq(srcUser), any(Timestamp.class), any(Timestamp.class), + eq(configInfo.getEncryptedDataKey())), times(1)); + + } + + @Test + public void testRemoveConfigInfo4Beta() { + String dataId = "dataId456789"; + String group = "group4567"; + String tenant = "tenant56789o0"; + //mock exist beta + ConfigInfoStateWrapper mockedConfigInfoStateWrapper = new ConfigInfoStateWrapper(); + mockedConfigInfoStateWrapper.setDataId(dataId); + mockedConfigInfoStateWrapper.setGroup(group); + mockedConfigInfoStateWrapper.setTenant(tenant); + mockedConfigInfoStateWrapper.setId(123456L); + mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(mockedConfigInfoStateWrapper); + //mock remove ok + Mockito.when(databaseOperate.update(any(List.class))).thenReturn(true); + + embeddedConfigInfoBetaPersistService.removeConfigInfo4Beta(dataId, group, tenant); + //verity + embeddedStorageContextHolderMockedStatic.verify( + () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(dataId), eq(group), eq(tenant)), + times(1)); + + } + + @Test + public void testFindConfigInfo4Beta() { + String dataId = "dataId456789"; + String group = "group4567"; + String tenant = "tenant56789o0"; + //mock exist beta + ConfigInfoBetaWrapper mockedConfigInfoStateWrapper = new ConfigInfoBetaWrapper(); + mockedConfigInfoStateWrapper.setDataId(dataId); + mockedConfigInfoStateWrapper.setGroup(group); + mockedConfigInfoStateWrapper.setTenant(tenant); + mockedConfigInfoStateWrapper.setId(123456L); + mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_BETA_WRAPPER_ROW_MAPPER))).thenReturn(mockedConfigInfoStateWrapper); + ConfigInfoBetaWrapper configInfo4BetaReturn = embeddedConfigInfoBetaPersistService.findConfigInfo4Beta(dataId, + group, tenant); + Assert.assertEquals(mockedConfigInfoStateWrapper, configInfo4BetaReturn); + + } + + @Test + public void testConfigInfoBetaCount() { + Mockito.when(databaseOperate.queryOne(anyString(), eq(Integer.class))).thenReturn(101); + int returnCount = embeddedConfigInfoBetaPersistService.configInfoBetaCount(); + Assert.assertEquals(101, returnCount); + } + + @Test + public void testFindAllConfigInfoBetaForDumpAll() { + //mock count + Mockito.when(databaseOperate.queryOne(anyString(), eq(Integer.class))).thenReturn(12345); + + //mock page list + List mockList = new ArrayList<>(); + mockList.add(new ConfigInfoBetaWrapper()); + mockList.add(new ConfigInfoBetaWrapper()); + mockList.add(new ConfigInfoBetaWrapper()); + mockList.get(0).setLastModified(System.currentTimeMillis()); + mockList.get(1).setLastModified(System.currentTimeMillis()); + mockList.get(2).setLastModified(System.currentTimeMillis()); + + Mockito.when( + databaseOperate.queryMany(anyString(), eq(new Object[] {}), eq(CONFIG_INFO_BETA_WRAPPER_ROW_MAPPER))) + .thenReturn(mockList); + + int pageNo = 1; + int pageSize = 101; + Mockito.when(databaseOperate.queryOne(anyString(), eq(Integer.class))).thenReturn(101); + //execute & expect + Page pageReturn = embeddedConfigInfoBetaPersistService.findAllConfigInfoBetaForDumpAll( + pageNo, pageSize); + Assert.assertEquals(mockList, pageReturn.getPageItems()); + Assert.assertEquals(101, pageReturn.getTotalCount()); + + } + +} diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoTagPersistServiceImplTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoTagPersistServiceImplTest.java new file mode 100644 index 00000000000..90466e04f4e --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoTagPersistServiceImplTest.java @@ -0,0 +1,317 @@ +/* + * 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.config.server.service.repository.embedded; + +import com.alibaba.nacos.common.utils.MD5Utils; +import com.alibaba.nacos.config.server.constant.Constants; +import com.alibaba.nacos.config.server.model.ConfigInfo; +import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; +import com.alibaba.nacos.config.server.model.ConfigInfoTagWrapper; +import com.alibaba.nacos.config.server.model.ConfigOperateResult; +import com.alibaba.nacos.persistence.datasource.DataSourceService; +import com.alibaba.nacos.persistence.datasource.DynamicDataSource; +import com.alibaba.nacos.persistence.model.Page; +import com.alibaba.nacos.persistence.repository.embedded.EmbeddedStorageContextHolder; +import com.alibaba.nacos.persistence.repository.embedded.operate.DatabaseOperate; +import com.alibaba.nacos.sys.env.EnvUtil; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER; +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_TAG_WRAPPER_ROW_MAPPER; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; + +/** + * test for embedded config tag. + * @author shiyiyue + */ +@RunWith(SpringJUnit4ClassRunner.class) +public class EmbeddedConfigInfoTagPersistServiceImplTest { + + private EmbeddedConfigInfoTagPersistServiceImpl embeddedConfigInfoTagPersistService; + + @Mock + private DataSourceService dataSourceService; + + MockedStatic envUtilMockedStatic; + + MockedStatic embeddedStorageContextHolderMockedStatic; + + MockedStatic dynamicDataSourceMockedStatic; + + @Mock + DynamicDataSource dynamicDataSource; + + @Mock + DatabaseOperate databaseOperate; + + @Before + public void before() { + embeddedStorageContextHolderMockedStatic = Mockito.mockStatic(EmbeddedStorageContextHolder.class); + dynamicDataSourceMockedStatic = Mockito.mockStatic(DynamicDataSource.class); + envUtilMockedStatic = Mockito.mockStatic(EnvUtil.class); + when(DynamicDataSource.getInstance()).thenReturn(dynamicDataSource); + when(dynamicDataSource.getDataSource()).thenReturn(dataSourceService); + when(dataSourceService.getDataSourceType()).thenReturn("derby"); + envUtilMockedStatic.when(() -> EnvUtil.getProperty(anyString(), eq(Boolean.class), eq(false))) + .thenReturn(false); + embeddedConfigInfoTagPersistService = new EmbeddedConfigInfoTagPersistServiceImpl(databaseOperate); + } + + @After + public void after() { + dynamicDataSourceMockedStatic.close(); + envUtilMockedStatic.close(); + embeddedStorageContextHolderMockedStatic.close(); + } + + @Test + public void testInsertOrUpdateTagOfAdd() { + String dataId = "dataId111222"; + String group = "group"; + String tenant = "tenant"; + String appName = "appname1234"; + String content = "c12345"; + + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key23456"); + //mock query config state empty and return obj after insert + ConfigInfoStateWrapper configInfoStateWrapper = new ConfigInfoStateWrapper(); + configInfoStateWrapper.setLastModified(System.currentTimeMillis()); + configInfoStateWrapper.setId(234567890L); + String tag = "tag123"; + + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, tag}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(null).thenReturn(configInfoStateWrapper); + + String srcIp = "ip345678"; + String srcUser = "user1234567"; + ConfigOperateResult configOperateResult = embeddedConfigInfoTagPersistService.insertOrUpdateTag(configInfo, tag, + srcIp, srcUser); + + //mock insert invoked. + embeddedStorageContextHolderMockedStatic.verify( + () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(dataId), eq(group), eq(tenant), + eq(tag), eq(appName), eq(content), eq(MD5Utils.md5Hex(content, Constants.PERSIST_ENCODE)), + eq(srcIp), eq(srcUser), any(Timestamp.class), any(Timestamp.class)), times(1)); + Assert.assertEquals(configInfoStateWrapper.getId(), configOperateResult.getId()); + Assert.assertEquals(configInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + + } + + @Test + public void testInsertOrUpdateTagOfUpdate() { + String dataId = "dataId111222"; + String group = "group"; + String tenant = "tenant"; + String appName = "appname1234"; + String content = "c12345"; + + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key23456"); + //mock query config state and return obj after update + ConfigInfoStateWrapper configInfoStateWrapper = new ConfigInfoStateWrapper(); + configInfoStateWrapper.setLastModified(System.currentTimeMillis()); + configInfoStateWrapper.setId(234567890L); + String tag = "tag123"; + + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, tag}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(new ConfigInfoStateWrapper()) + .thenReturn(configInfoStateWrapper); + String srcIp = "ip345678"; + String srcUser = "user1234567"; + ConfigOperateResult configOperateResult = embeddedConfigInfoTagPersistService.insertOrUpdateTag(configInfo, tag, + srcIp, srcUser); + //verify update to be invoked + embeddedStorageContextHolderMockedStatic.verify( + () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(content), + eq(MD5Utils.md5Hex(content, Constants.PERSIST_ENCODE)), eq(srcIp), eq(srcUser), + any(Timestamp.class), eq(appName), eq(dataId), eq(group), eq(tenant), eq(tag)), times(1)); + Assert.assertEquals(configInfoStateWrapper.getId(), configOperateResult.getId()); + Assert.assertEquals(configInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + + } + + @Test + public void testInsertOrUpdateTagCasOfAdd() { + String dataId = "dataId111222"; + String group = "group"; + String tenant = "tenant"; + String appName = "appname1234"; + String content = "c12345"; + + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key23456"); + configInfo.setMd5("casMd5"); + //mock query config state empty and return obj after insert + ConfigInfoStateWrapper configInfoStateWrapper = new ConfigInfoStateWrapper(); + configInfoStateWrapper.setLastModified(System.currentTimeMillis()); + configInfoStateWrapper.setId(234567890L); + String tag = "tag123"; + + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, tag}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(null).thenReturn(configInfoStateWrapper); + + String srcIp = "ip345678"; + String srcUser = "user1234567"; + ConfigOperateResult configOperateResult = embeddedConfigInfoTagPersistService.insertOrUpdateTagCas(configInfo, + tag, srcIp, srcUser); + //verify insert to be invoked + //mock insert invoked. + embeddedStorageContextHolderMockedStatic.verify( + () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(dataId), eq(group), eq(tenant), + eq(tag), eq(appName), eq(content), eq(MD5Utils.md5Hex(content, Constants.PERSIST_ENCODE)), + eq(srcIp), eq(srcUser), any(Timestamp.class), any(Timestamp.class)), times(1)); + Assert.assertEquals(configInfoStateWrapper.getId(), configOperateResult.getId()); + Assert.assertEquals(configInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + + } + + @Test + public void testInsertOrUpdateTagCasOfUpdate() { + String dataId = "dataId111222"; + String group = "group"; + String tenant = "tenant"; + String appName = "appname1234"; + String content = "c12345"; + + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key23456"); + configInfo.setMd5("casMd5"); + //mock query config state and return obj after update + ConfigInfoStateWrapper configInfoStateWrapper = new ConfigInfoStateWrapper(); + configInfoStateWrapper.setLastModified(System.currentTimeMillis()); + configInfoStateWrapper.setId(234567890L); + String tag = "tag123"; + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, tag}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(new ConfigInfoStateWrapper()) + .thenReturn(configInfoStateWrapper); + String srcIp = "ip345678"; + String srcUser = "user1234567"; + + //mock cas update return 1 + Mockito.when(databaseOperate.blockUpdate()).thenReturn(true); + ConfigOperateResult configOperateResult = embeddedConfigInfoTagPersistService.insertOrUpdateTagCas(configInfo, + tag, srcIp, srcUser); + //verify update to be invoked + embeddedStorageContextHolderMockedStatic.verify( + () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(content), + eq(MD5Utils.md5Hex(content, Constants.PERSIST_ENCODE)), eq(srcIp), eq(srcUser), + any(Timestamp.class), eq(appName), eq(dataId), eq(group), eq(tenant), eq(tag), + eq(configInfo.getMd5())), times(1)); + Assert.assertEquals(configInfoStateWrapper.getId(), configOperateResult.getId()); + Assert.assertEquals(configInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + } + + @Test + public void testRemoveConfigInfoTag() { + String dataId = "dataId1112222"; + String group = "group22"; + String tenant = "tenant2"; + String tag = "tag123345"; + String srcIp = "ip345678"; + String srcUser = "user1234567"; + embeddedConfigInfoTagPersistService.removeConfigInfoTag(dataId, group, tenant, tag, srcIp, srcUser); + //verify delete sql invoked. + embeddedStorageContextHolderMockedStatic.verify( + () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(dataId), eq(group), eq(tenant), + eq(tag)), times(1)); + } + + @Test + public void testFindConfigInfo4Tag() { + String dataId = "dataId1112222"; + String group = "group22"; + String tenant = "tenant2"; + String tag = "tag123345"; + + //mock query tag return obj + ConfigInfoTagWrapper configInfoTagWrapperMocked = new ConfigInfoTagWrapper(); + configInfoTagWrapperMocked.setLastModified(System.currentTimeMillis()); + + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, tag}), + eq(CONFIG_INFO_TAG_WRAPPER_ROW_MAPPER))).thenReturn(configInfoTagWrapperMocked); + + ConfigInfoTagWrapper configInfo4TagReturn = embeddedConfigInfoTagPersistService.findConfigInfo4Tag(dataId, + group, tenant, tag); + Assert.assertEquals(configInfoTagWrapperMocked, configInfo4TagReturn); + } + + @Test + public void testConfigInfoTagCount() { + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + + //mock count + Mockito.when(databaseOperate.queryOne(anyString(), eq(Integer.class))).thenReturn(308); + //execute & verify + int count = embeddedConfigInfoTagPersistService.configInfoTagCount(); + Assert.assertEquals(308, count); + } + + @Test + public void testFindAllConfigInfoTagForDumpAll() { + + //mock count + Mockito.when(databaseOperate.queryOne(anyString(), eq(Integer.class))).thenReturn(308); + List mockTagList = new ArrayList<>(); + mockTagList.add(new ConfigInfoTagWrapper()); + mockTagList.add(new ConfigInfoTagWrapper()); + mockTagList.add(new ConfigInfoTagWrapper()); + mockTagList.get(0).setLastModified(System.currentTimeMillis()); + mockTagList.get(1).setLastModified(System.currentTimeMillis()); + mockTagList.get(2).setLastModified(System.currentTimeMillis()); + //mock query list + Mockito.when( + databaseOperate.queryMany(anyString(), eq(new Object[] {}), eq(CONFIG_INFO_TAG_WRAPPER_ROW_MAPPER))) + .thenReturn(mockTagList); + int pageNo = 3; + int pageSize = 100; + //execute & verify + Page returnTagPage = embeddedConfigInfoTagPersistService.findAllConfigInfoTagForDumpAll( + pageNo, pageSize); + Assert.assertEquals(308, returnTagPage.getTotalCount()); + Assert.assertEquals(mockTagList, returnTagPage.getPageItems()); + } + + @Test + public void testFindConfigInfoTags() { + String dataId = "dataId1112222"; + String group = "group22"; + String tenant = "tenant2"; + List mockedTags = Arrays.asList("tags1", "tags11", "tags111"); + Mockito.when(databaseOperate.queryMany(anyString(), eq(new Object[] {dataId, group, tenant}), eq(String.class))) + .thenReturn(mockedTags); + List configInfoTags = embeddedConfigInfoTagPersistService.findConfigInfoTags(dataId, group, tenant); + Assert.assertEquals(mockedTags, configInfoTags); + } +} diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedHistoryConfigInfoPersistServiceImplTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedHistoryConfigInfoPersistServiceImplTest.java new file mode 100644 index 00000000000..a63c8d5632d --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedHistoryConfigInfoPersistServiceImplTest.java @@ -0,0 +1,254 @@ +/* + * 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.config.server.service.repository.embedded; + +import com.alibaba.nacos.config.server.model.ConfigHistoryInfo; +import com.alibaba.nacos.config.server.model.ConfigInfo; +import com.alibaba.nacos.config.server.model.ConfigInfoWrapper; +import com.alibaba.nacos.persistence.datasource.DataSourceService; +import com.alibaba.nacos.persistence.datasource.DynamicDataSource; +import com.alibaba.nacos.persistence.model.Page; +import com.alibaba.nacos.persistence.repository.embedded.EmbeddedStorageContextHolder; +import com.alibaba.nacos.persistence.repository.embedded.operate.DatabaseOperate; +import com.alibaba.nacos.sys.env.EnvUtil; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.math.BigInteger; +import java.sql.Timestamp; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneOffset; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.HISTORY_DETAIL_ROW_MAPPER; +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.HISTORY_LIST_ROW_MAPPER; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; + +/** + * test for embedded config history. + * + * @author shiyiyue + */ +@RunWith(SpringJUnit4ClassRunner.class) +public class EmbeddedHistoryConfigInfoPersistServiceImplTest { + + private EmbeddedHistoryConfigInfoPersistServiceImpl embeddedHistoryConfigInfoPersistService; + + @Mock + private DataSourceService dataSourceService; + + MockedStatic envUtilMockedStatic; + + MockedStatic embeddedStorageContextHolderMockedStatic; + + MockedStatic dynamicDataSourceMockedStatic; + + @Mock + DynamicDataSource dynamicDataSource; + + @Mock + DatabaseOperate databaseOperate; + + @Before + public void before() { + embeddedStorageContextHolderMockedStatic = Mockito.mockStatic(EmbeddedStorageContextHolder.class); + dynamicDataSourceMockedStatic = Mockito.mockStatic(DynamicDataSource.class); + envUtilMockedStatic = Mockito.mockStatic(EnvUtil.class); + when(DynamicDataSource.getInstance()).thenReturn(dynamicDataSource); + when(dynamicDataSource.getDataSource()).thenReturn(dataSourceService); + when(dataSourceService.getDataSourceType()).thenReturn("derby"); + envUtilMockedStatic.when(() -> EnvUtil.getProperty(anyString(), eq(Boolean.class), eq(false))) + .thenReturn(false); + embeddedHistoryConfigInfoPersistService = new EmbeddedHistoryConfigInfoPersistServiceImpl(databaseOperate); + } + + @After + public void after() { + dynamicDataSourceMockedStatic.close(); + envUtilMockedStatic.close(); + embeddedStorageContextHolderMockedStatic.close(); + } + + @Test + public void testInsertConfigHistoryAtomic() { + String dataId = "dateId243"; + String group = "group243"; + String tenant = "tenant243"; + String content = "content243"; + String appName = "appName243"; + long id = 123456787765432L; + String srcUser = "user12345"; + String srcIp = "ip1234"; + String ops = "D"; + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key23456"); + //expect insert success,verify insert invoked + embeddedHistoryConfigInfoPersistService.insertConfigHistoryAtomic(id, configInfo, srcIp, srcUser, timestamp, + ops); + + //verify insert to be invoked + embeddedStorageContextHolderMockedStatic.verify( + () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(id), eq(dataId), eq(group), eq(tenant), + eq(appName), eq(content), eq(configInfo.getMd5()), eq(srcIp), eq(srcUser), eq(timestamp), + eq(ops), eq(configInfo.getEncryptedDataKey())), times(1)); + } + + @Test + public void testRemoveConfigHistory() { + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + int pageSize = 1233; + embeddedHistoryConfigInfoPersistService.removeConfigHistory(timestamp, pageSize); + //verify delete by time and size invoked. + embeddedStorageContextHolderMockedStatic.verify( + () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(timestamp), eq(pageSize)), times(1)); + } + + @Test + public void testFindDeletedConfig() { + + //mock query list return + Map mockObj1 = new HashMap<>(); + mockObj1.put("nid", new BigInteger("1234")); + mockObj1.put("data_id", "data_id1"); + mockObj1.put("group_id", "group_id1"); + mockObj1.put("tenant_id", "tenant_id1"); + LocalDateTime now = LocalDateTime.of(LocalDate.now(), LocalTime.now()); + mockObj1.put("gmt_modified", now); + List> list = new ArrayList<>(); + list.add(mockObj1); + Map mockObj2 = new HashMap<>(); + mockObj2.put("nid", new BigInteger("12345")); + mockObj2.put("data_id", "data_id2"); + mockObj2.put("group_id", "group_id2"); + mockObj2.put("tenant_id", "tenant_id2"); + LocalDateTime now2 = LocalDateTime.of(LocalDate.now(), LocalTime.now()); + mockObj2.put("gmt_modified", now2); + list.add(mockObj2); + int pageSize = 1233; + long startId = 23456; + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + Mockito.when(databaseOperate.queryMany(anyString(), eq(new Object[] {timestamp, startId, pageSize}))) + .thenReturn(list); + //execute + List deletedConfig = embeddedHistoryConfigInfoPersistService.findDeletedConfig(timestamp, + startId, pageSize); + //expect verify + Assert.assertEquals("data_id1", deletedConfig.get(0).getDataId()); + Assert.assertEquals("group_id1", deletedConfig.get(0).getGroup()); + Assert.assertEquals("tenant_id1", deletedConfig.get(0).getTenant()); + Assert.assertEquals(now.toInstant(ZoneOffset.ofHours(8)).toEpochMilli(), + deletedConfig.get(0).getLastModified()); + Assert.assertEquals("data_id2", deletedConfig.get(1).getDataId()); + Assert.assertEquals("group_id2", deletedConfig.get(1).getGroup()); + Assert.assertEquals("tenant_id2", deletedConfig.get(1).getTenant()); + Assert.assertEquals(now2.toInstant(ZoneOffset.ofHours(8)).toEpochMilli(), + deletedConfig.get(1).getLastModified()); + } + + @Test + public void testFindConfigHistory() { + String dataId = "dataId34567"; + String group = "group34567"; + String tenant = "tenant34567"; + + //mock count + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant}), eq(Integer.class))) + .thenReturn(300); + //mock list + List mockList = new ArrayList<>(); + mockList.add(createMockConfigHistoryInfo(0)); + mockList.add(createMockConfigHistoryInfo(1)); + mockList.add(createMockConfigHistoryInfo(2)); + Mockito.when(databaseOperate.queryMany(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(HISTORY_LIST_ROW_MAPPER))).thenReturn(mockList); + int pageSize = 100; + int pageNo = 2; + //execute & verify + Page historyReturn = embeddedHistoryConfigInfoPersistService.findConfigHistory(dataId, group, + tenant, pageNo, pageSize); + Assert.assertEquals(mockList, historyReturn.getPageItems()); + Assert.assertEquals(300, historyReturn.getTotalCount()); + + } + + @Test + public void testDetailConfigHistory() { + long nid = 256789; + + //mock query + ConfigHistoryInfo mockConfigHistoryInfo = createMockConfigHistoryInfo(0); + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {nid}), eq(HISTORY_DETAIL_ROW_MAPPER))) + .thenReturn(mockConfigHistoryInfo); + //execute & verify + ConfigHistoryInfo historyReturn = embeddedHistoryConfigInfoPersistService.detailConfigHistory(nid); + Assert.assertEquals(mockConfigHistoryInfo, historyReturn); + } + + @Test + public void testDetailPreviousConfigHistory() { + long nid = 256789; + //mock query + ConfigHistoryInfo mockConfigHistoryInfo = createMockConfigHistoryInfo(0); + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {nid}), eq(HISTORY_DETAIL_ROW_MAPPER))) + .thenReturn(mockConfigHistoryInfo); + //execute & verify + ConfigHistoryInfo historyReturn = embeddedHistoryConfigInfoPersistService.detailPreviousConfigHistory(nid); + Assert.assertEquals(mockConfigHistoryInfo, historyReturn); + } + + @Test + public void testFindConfigHistoryCountByTime() { + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + + //mock count + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {timestamp}), eq(Integer.class))) + .thenReturn(308); + //execute & verify + int count = embeddedHistoryConfigInfoPersistService.findConfigHistoryCountByTime(timestamp); + Assert.assertEquals(308, count); + + } + + private ConfigHistoryInfo createMockConfigHistoryInfo(long mockId) { + ConfigHistoryInfo configAllInfo = new ConfigHistoryInfo(); + configAllInfo.setDataId("test" + mockId + ".yaml"); + configAllInfo.setGroup("test"); + configAllInfo.setContent("23456789000content"); + configAllInfo.setOpType("D"); + configAllInfo.setEncryptedDataKey("key4567"); + configAllInfo.setSrcIp("ip567"); + configAllInfo.setSrcUser("user1234"); + configAllInfo.setMd5("md52345678"); + return configAllInfo; + } +} diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoAggrPersistServiceImplTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoAggrPersistServiceImplTest.java new file mode 100644 index 00000000000..47922d240e2 --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoAggrPersistServiceImplTest.java @@ -0,0 +1,339 @@ +/* + * 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.config.server.service.repository.extrnal; + +import com.alibaba.nacos.config.server.model.ConfigInfoAggr; +import com.alibaba.nacos.config.server.model.ConfigInfoChanged; +import com.alibaba.nacos.config.server.service.sql.ExternalStorageUtils; +import com.alibaba.nacos.config.server.utils.TestCaseUtils; +import com.alibaba.nacos.persistence.datasource.DataSourceService; +import com.alibaba.nacos.persistence.datasource.DynamicDataSource; +import com.alibaba.nacos.persistence.model.Page; +import com.alibaba.nacos.sys.env.EnvUtil; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.CannotGetJdbcConnectionException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.TransactionSystemException; +import org.springframework.transaction.support.TransactionTemplate; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_AGGR_ROW_MAPPER; +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_CHANGED_ROW_MAPPER; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +@RunWith(SpringJUnit4ClassRunner.class) +public class ExternalConfigInfoAggrPersistServiceImplTest { + + private ExternalConfigInfoAggrPersistServiceImpl externalConfigInfoAggrPersistService; + + @Mock + private DataSourceService dataSourceService; + + @Mock + private JdbcTemplate jdbcTemplate; + + private TransactionTemplate transactionTemplate = TestCaseUtils.createMockTransactionTemplate(); + + MockedStatic envUtilMockedStatic; + + MockedStatic externalStorageUtilsMockedStatic; + + MockedStatic dynamicDataSourceMockedStatic; + + @Mock + DynamicDataSource dynamicDataSource; + + @Before + public void before() { + dynamicDataSourceMockedStatic = Mockito.mockStatic(DynamicDataSource.class); + envUtilMockedStatic = Mockito.mockStatic(EnvUtil.class); + externalStorageUtilsMockedStatic = Mockito.mockStatic(ExternalStorageUtils.class); + when(DynamicDataSource.getInstance()).thenReturn(dynamicDataSource); + when(dynamicDataSource.getDataSource()).thenReturn(dataSourceService); + when(dataSourceService.getTransactionTemplate()).thenReturn(transactionTemplate); + when(dataSourceService.getJdbcTemplate()).thenReturn(jdbcTemplate); + when(dataSourceService.getDataSourceType()).thenReturn("mysql"); + envUtilMockedStatic.when(() -> EnvUtil.getProperty(anyString(), eq(Boolean.class), eq(false))) + .thenReturn(false); + externalConfigInfoAggrPersistService = new ExternalConfigInfoAggrPersistServiceImpl(); + + } + + @After + public void after() { + dynamicDataSourceMockedStatic.close(); + envUtilMockedStatic.close(); + externalStorageUtilsMockedStatic.close(); + } + + @Test + public void testAddAggrConfigInfoOfEqualContent() { + String dataId = "dataId111"; + String group = "group"; + String tenant = "tenant"; + String datumId = "datumId"; + String appName = "appname1234"; + String content = "content1234"; + + //mock query datumId and equal with current content param. + String existContent = "content1234"; + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, datumId}), + eq(String.class))).thenReturn(existContent); + + boolean result = externalConfigInfoAggrPersistService.addAggrConfigInfo(dataId, group, tenant, datumId, appName, + content); + Assert.assertTrue(result); + } + + @Test + public void testAddAggrConfigInfoOfAddNewContent() { + String dataId = "dataId111"; + String group = "group"; + String tenant = "tenant"; + String datumId = "datumId"; + String appName = "appname1234"; + String content = "content1234"; + + //mock query datumId and throw EmptyResultDataAccessException. + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, datumId}), + eq(String.class))).thenThrow(new EmptyResultDataAccessException(1)); + //mock insert success + when(jdbcTemplate.update(anyString(), eq(dataId), eq(group), eq(tenant), eq(datumId), eq(appName), eq(content), + any(Timestamp.class))).thenReturn(1); + + //execute + boolean result = externalConfigInfoAggrPersistService.addAggrConfigInfo(dataId, group, tenant, datumId, appName, + content); + Assert.assertTrue(result); + } + + @Test + public void testAddAggrConfigInfoOfUpdateNotEqualContent() { + String dataId = "dataId111"; + String group = "group"; + String tenant = "tenant"; + String datumId = "datumId"; + String appName = "appname1234"; + String content = "content1234"; + + //mock query datumId + String existContent = "existContent111"; + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, datumId}), + eq(String.class))).thenReturn(existContent); + //mock update success,return 1 + when(jdbcTemplate.update(anyString(), eq(content), any(Timestamp.class), eq(dataId), eq(group), eq(tenant), + eq(datumId))).thenReturn(1); + //mock update content + boolean result = externalConfigInfoAggrPersistService.addAggrConfigInfo(dataId, group, tenant, datumId, appName, + content); + Assert.assertTrue(result); + + } + + @Test + public void testAddAggrConfigInfoOfException() { + String dataId = "dataId111"; + String group = "group"; + String tenant = "tenant"; + String datumId = "datumId"; + String appName = "appname1234"; + String content = "content1234"; + + //mock query datumId and throw EmptyResultDataAccessException. + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, datumId}), + eq(String.class))).thenThrow(new CannotGetJdbcConnectionException("mock exp")); + try { + externalConfigInfoAggrPersistService.addAggrConfigInfo(dataId, group, tenant, datumId, appName, content); + Assert.assertTrue(false); + } catch (Exception exp) { + Assert.assertEquals("mock exp", exp.getMessage()); + } + } + + @Test + public void testBatchPublishAggrSuccess() { + + String dataId = "dataId111"; + String group = "group"; + String tenant = "tenant"; + //mock query datumId and equal with current content param. + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, "d1"}), + eq(String.class))).thenReturn("c1"); + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, "d2"}), + eq(String.class))).thenReturn("c2"); + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, "d3"}), + eq(String.class))).thenReturn("c3"); + Map datumMap = new HashMap<>(); + datumMap.put("d1", "c1"); + datumMap.put("d2", "c2"); + datumMap.put("d3", "c3"); + String appName = "appname1234"; + boolean result = externalConfigInfoAggrPersistService.batchPublishAggr(dataId, group, tenant, datumMap, + appName); + Assert.assertTrue(result); + } + + @Test + public void testBatchPublishAggrException() { + + String dataId = "dataId111"; + String group = "group"; + String tenant = "tenant"; + //mock query datumId and equal with current content param. + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, "d1"}), + eq(String.class))).thenThrow(new TransactionSystemException("c1t fail")); + Map datumMap = new HashMap<>(); + datumMap.put("d1", "c1"); + datumMap.put("d2", "c2"); + datumMap.put("d3", "c3"); + String appName = "appname1234"; + boolean result = externalConfigInfoAggrPersistService.batchPublishAggr(dataId, group, tenant, datumMap, + appName); + Assert.assertFalse(result); + } + + @Test + public void testAggrConfigInfoCount() { + String dataId = "dataId11122"; + String group = "group"; + String tenant = "tenant"; + + //mock select count of aggr. + when(jdbcTemplate.queryForObject(anyString(), eq(Integer.class), eq(dataId), eq(group), eq(tenant))).thenReturn( + new Integer(101)); + int result = externalConfigInfoAggrPersistService.aggrConfigInfoCount(dataId, group, tenant); + Assert.assertEquals(101, result); + + } + + @Test + public void testFindConfigInfoAggrByPage() { + String dataId = "dataId111"; + String group = "group"; + String tenant = "tenant"; + + //mock query count. + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(Integer.class))).thenReturn(101); + //mock query page list + List configInfoAggrs = new ArrayList<>(); + configInfoAggrs.add(new ConfigInfoAggr()); + configInfoAggrs.add(new ConfigInfoAggr()); + configInfoAggrs.add(new ConfigInfoAggr()); + + when(jdbcTemplate.query(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_AGGR_ROW_MAPPER))).thenReturn(configInfoAggrs); + int pageNo = 1; + int pageSize = 120; + Page configInfoAggrByPage = externalConfigInfoAggrPersistService.findConfigInfoAggrByPage( + dataId, group, tenant, pageNo, pageSize); + Assert.assertEquals(101, configInfoAggrByPage.getTotalCount()); + Assert.assertEquals(configInfoAggrs, configInfoAggrByPage.getPageItems()); + + } + + @Test + public void testFindConfigInfoAggrByPageOfException() { + String dataId = "dataId111"; + String group = "group"; + String tenant = "tenant"; + + //mock query count exception. + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(Integer.class))).thenThrow(new CannotGetJdbcConnectionException("mock fail222")); + + try { + int pageNo = 1; + int pageSize = 120; + externalConfigInfoAggrPersistService.findConfigInfoAggrByPage(dataId, group, tenant, pageNo, pageSize); + Assert.assertTrue(false); + } catch (Throwable throwable) { + Assert.assertEquals("mock fail222", throwable.getMessage()); + } + } + + @Test + public void testFindAllAggrGroup() { + List configList = new ArrayList<>(); + configList.add(create("dataId", 0)); + configList.add(create("dataId", 1)); + //mock return list + when(jdbcTemplate.query(anyString(), eq(new Object[] {}), eq(CONFIG_INFO_CHANGED_ROW_MAPPER))).thenReturn( + configList); + + List allAggrGroup = externalConfigInfoAggrPersistService.findAllAggrGroup(); + Assert.assertEquals(configList, allAggrGroup); + + } + + @Test + public void testFindAllAggrGroupException() { + + //mock throw CannotGetJdbcConnectionException + when(jdbcTemplate.query(anyString(), eq(new Object[] {}), eq(CONFIG_INFO_CHANGED_ROW_MAPPER))).thenThrow( + new CannotGetJdbcConnectionException("mock fail")); + try { + externalConfigInfoAggrPersistService.findAllAggrGroup(); + Assert.assertTrue(false); + } catch (Throwable throwable) { + Assert.assertEquals("mock fail", throwable.getMessage()); + } + + //mock throw EmptyResultDataAccessException + when(jdbcTemplate.query(anyString(), eq(new Object[] {}), eq(CONFIG_INFO_CHANGED_ROW_MAPPER))).thenThrow( + new EmptyResultDataAccessException(1)); + List allAggrGroup = externalConfigInfoAggrPersistService.findAllAggrGroup(); + Assert.assertEquals(null, allAggrGroup); + + //mock Exception + when(jdbcTemplate.query(anyString(), eq(new Object[] {}), eq(CONFIG_INFO_CHANGED_ROW_MAPPER))).thenThrow( + new RuntimeException("789")); + try { + externalConfigInfoAggrPersistService.findAllAggrGroup(); + Assert.assertTrue(false); + } catch (Throwable throwable) { + Assert.assertEquals("789", throwable.getCause().getMessage()); + } + + } + + private ConfigInfoChanged create(String dataID, int i) { + ConfigInfoChanged hasDatum = new ConfigInfoChanged(); + hasDatum.setDataId(dataID + i); + hasDatum.setTenant("tenant1"); + hasDatum.setGroup("group1"); + return hasDatum; + } + +} diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoBetaPersistServiceImplTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoBetaPersistServiceImplTest.java new file mode 100644 index 00000000000..c1ab3fb2f71 --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoBetaPersistServiceImplTest.java @@ -0,0 +1,501 @@ +/* + * 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.config.server.service.repository.extrnal; + +import com.alibaba.nacos.common.utils.MD5Utils; +import com.alibaba.nacos.config.server.constant.Constants; +import com.alibaba.nacos.config.server.model.ConfigInfo; +import com.alibaba.nacos.config.server.model.ConfigInfoBetaWrapper; +import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; +import com.alibaba.nacos.config.server.model.ConfigOperateResult; +import com.alibaba.nacos.config.server.service.sql.ExternalStorageUtils; +import com.alibaba.nacos.config.server.utils.TestCaseUtils; +import com.alibaba.nacos.persistence.datasource.DataSourceService; +import com.alibaba.nacos.persistence.datasource.DynamicDataSource; +import com.alibaba.nacos.persistence.model.Page; +import com.alibaba.nacos.sys.env.EnvUtil; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.CannotGetJdbcConnectionException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.support.TransactionTemplate; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; + +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_BETA_WRAPPER_ROW_MAPPER; +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; + +@RunWith(SpringJUnit4ClassRunner.class) +public class ExternalConfigInfoBetaPersistServiceImplTest { + + private ExternalConfigInfoBetaPersistServiceImpl externalConfigInfoBetaPersistService; + + @Mock + private DataSourceService dataSourceService; + + @Mock + private JdbcTemplate jdbcTemplate; + + private TransactionTemplate transactionTemplate = TestCaseUtils.createMockTransactionTemplate(); + + MockedStatic envUtilMockedStatic; + + MockedStatic externalStorageUtilsMockedStatic; + + MockedStatic dynamicDataSourceMockedStatic; + + @Mock + DynamicDataSource dynamicDataSource; + + @Before + public void before() { + dynamicDataSourceMockedStatic = Mockito.mockStatic(DynamicDataSource.class); + envUtilMockedStatic = Mockito.mockStatic(EnvUtil.class); + externalStorageUtilsMockedStatic = Mockito.mockStatic(ExternalStorageUtils.class); + when(DynamicDataSource.getInstance()).thenReturn(dynamicDataSource); + when(dynamicDataSource.getDataSource()).thenReturn(dataSourceService); + when(dataSourceService.getTransactionTemplate()).thenReturn(transactionTemplate); + when(dataSourceService.getJdbcTemplate()).thenReturn(jdbcTemplate); + when(dataSourceService.getDataSourceType()).thenReturn("mysql"); + envUtilMockedStatic.when(() -> EnvUtil.getProperty(anyString(), eq(Boolean.class), eq(false))) + .thenReturn(false); + externalConfigInfoBetaPersistService = new ExternalConfigInfoBetaPersistServiceImpl(); + } + + @After + public void after() { + dynamicDataSourceMockedStatic.close(); + envUtilMockedStatic.close(); + externalStorageUtilsMockedStatic.close(); + } + + @Test + public void testInsertOrUpdateBetaOfUpdate() { + String dataId = "betaDataId113"; + String group = "group"; + String tenant = "tenant"; + //mock exist beta + ConfigInfoStateWrapper mockedConfigInfoStateWrapper = new ConfigInfoStateWrapper(); + mockedConfigInfoStateWrapper.setDataId(dataId); + mockedConfigInfoStateWrapper.setGroup(group); + mockedConfigInfoStateWrapper.setTenant(tenant); + mockedConfigInfoStateWrapper.setId(123456L); + mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(mockedConfigInfoStateWrapper, + mockedConfigInfoStateWrapper); + //execute + String betaIps = "betaips..."; + String srcIp = "srcUp..."; + String srcUser = "srcUser..."; + String appName = "appname"; + String content = "content111"; + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key34567"); + ConfigOperateResult configOperateResult = externalConfigInfoBetaPersistService.insertOrUpdateBeta(configInfo, + betaIps, srcIp, srcUser); + //expect return obj + Assert.assertEquals(mockedConfigInfoStateWrapper.getId(), configOperateResult.getId()); + Assert.assertEquals(mockedConfigInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + //verify update to be invoked + Mockito.verify(jdbcTemplate, times(1)) + .update(anyString(), eq(configInfo.getContent()), eq(configInfo.getMd5()), eq(betaIps), eq(srcIp), + eq(srcUser), any(Timestamp.class), eq(configInfo.getAppName()), + eq(configInfo.getEncryptedDataKey()), eq(dataId), eq(group), eq(tenant)); + } + + @Test + public void testInsertOrUpdateBetaOfAdd() { + String dataId = "betaDataId113"; + String group = "group113"; + String tenant = "tenant113"; + //mock exist beta + ConfigInfoStateWrapper mockedConfigInfoStateWrapper = new ConfigInfoStateWrapper(); + mockedConfigInfoStateWrapper.setDataId(dataId); + mockedConfigInfoStateWrapper.setGroup(group); + mockedConfigInfoStateWrapper.setTenant(tenant); + mockedConfigInfoStateWrapper.setId(123456L); + mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenThrow(new EmptyResultDataAccessException(1)) + .thenReturn(mockedConfigInfoStateWrapper); + + String betaIps = "betaips..."; + String srcIp = "srcUp..."; + String srcUser = "srcUser..."; + String appName = "appname"; + String content = "content111"; + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key34567"); + //execute + ConfigOperateResult configOperateResult = externalConfigInfoBetaPersistService.insertOrUpdateBeta(configInfo, + betaIps, srcIp, srcUser); + //expect return obj + Assert.assertEquals(mockedConfigInfoStateWrapper.getId(), configOperateResult.getId()); + Assert.assertEquals(mockedConfigInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + //verify add to be invoked + Mockito.verify(jdbcTemplate, times(1)) + .update(anyString(), eq(dataId), eq(group), eq(tenant), eq(configInfo.getAppName()), + eq(configInfo.getContent()), eq(configInfo.getMd5()), eq(betaIps), eq(srcIp), eq(srcUser), + any(Timestamp.class), any(Timestamp.class), eq(configInfo.getEncryptedDataKey())); + + } + + @Test + public void testInsertOrUpdateBetaOfException() { + String dataId = "betaDataId113"; + String group = "group113"; + String tenant = "tenant113"; + //mock exist beta + ConfigInfoStateWrapper mockedConfigInfoStateWrapper = new ConfigInfoStateWrapper(); + mockedConfigInfoStateWrapper.setDataId(dataId); + mockedConfigInfoStateWrapper.setGroup(group); + mockedConfigInfoStateWrapper.setTenant(tenant); + mockedConfigInfoStateWrapper.setId(123456L); + mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(mockedConfigInfoStateWrapper); + + String betaIps = "betaips..."; + String srcIp = "srcUp..."; + String srcUser = "srcUser..."; + String appName = "appname"; + String content = "content111"; + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key34567"); + + // mock update throw CannotGetJdbcConnectionException + when(jdbcTemplate.update(anyString(), eq(configInfo.getContent()), eq(configInfo.getMd5()), eq(betaIps), + eq(srcIp), eq(srcUser), any(Timestamp.class), eq(configInfo.getAppName()), + eq(configInfo.getEncryptedDataKey()), eq(dataId), eq(group), eq(tenant))).thenThrow( + new CannotGetJdbcConnectionException("mock fail")); + //execute of update& expect. + try { + externalConfigInfoBetaPersistService.insertOrUpdateBeta(configInfo, betaIps, srcIp, srcUser); + Assert.assertTrue(false); + } catch (Exception exception) { + Assert.assertEquals("mock fail", exception.getMessage()); + } + + //mock query return null + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(null); + //mock add throw CannotGetJdbcConnectionException + when(jdbcTemplate.update(anyString(), eq(dataId), eq(group), eq(tenant), eq(configInfo.getAppName()), + eq(configInfo.getContent()), eq(configInfo.getMd5()), eq(betaIps), eq(srcIp), eq(srcUser), + any(Timestamp.class), any(Timestamp.class), eq(configInfo.getEncryptedDataKey()))).thenThrow( + new CannotGetJdbcConnectionException("mock fail add")); + //execute of add& expect. + try { + externalConfigInfoBetaPersistService.insertOrUpdateBeta(configInfo, betaIps, srcIp, srcUser); + Assert.assertTrue(false); + } catch (Exception exception) { + Assert.assertEquals("mock fail add", exception.getMessage()); + } + + //mock query throw CannotGetJdbcConnectionException + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenThrow( + new CannotGetJdbcConnectionException("get c fail")); + //execute of add& expect. + try { + externalConfigInfoBetaPersistService.insertOrUpdateBeta(configInfo, betaIps, srcIp, srcUser); + Assert.assertTrue(false); + } catch (Exception exception) { + Assert.assertEquals("get c fail", exception.getMessage()); + } + + } + + @Test + public void testInsertOrUpdateBetaCasOfUpdate() { + String dataId = "betaDataId113"; + String group = "group"; + String tenant = "tenant"; + //mock exist beta + ConfigInfoStateWrapper mockedConfigInfoStateWrapper = new ConfigInfoStateWrapper(); + mockedConfigInfoStateWrapper.setDataId(dataId); + mockedConfigInfoStateWrapper.setGroup(group); + mockedConfigInfoStateWrapper.setTenant(tenant); + mockedConfigInfoStateWrapper.setId(123456L); + mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(mockedConfigInfoStateWrapper, + mockedConfigInfoStateWrapper); + + //execute + String betaIps = "betaips..."; + String srcIp = "srcUp..."; + String srcUser = "srcUser..."; + String appName = "appname"; + String content = "content111"; + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key34567"); + configInfo.setMd5("casMd5"); + //mock cas update + when(jdbcTemplate.update(anyString(), eq(configInfo.getContent()), + eq(MD5Utils.md5Hex(content, Constants.PERSIST_ENCODE)), eq(betaIps), eq(srcIp), eq(srcUser), + any(Timestamp.class), eq(appName), eq(dataId), eq(group), eq(tenant), + eq(configInfo.getMd5()))).thenReturn(1); + + ConfigOperateResult configOperateResult = externalConfigInfoBetaPersistService.insertOrUpdateBetaCas(configInfo, + betaIps, srcIp, srcUser); + //expect return obj + Assert.assertEquals(mockedConfigInfoStateWrapper.getId(), configOperateResult.getId()); + Assert.assertEquals(mockedConfigInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + //verify cas update to be invoked + Mockito.verify(jdbcTemplate, times(1)).update(anyString(), eq(configInfo.getContent()), + eq(MD5Utils.md5Hex(content, Constants.PERSIST_ENCODE)), eq(betaIps), eq(srcIp), eq(srcUser), + any(Timestamp.class), eq(appName), eq(dataId), eq(group), eq(tenant), eq(configInfo.getMd5())); + + } + + @Test + public void testInsertOrUpdateBetaCasOfAdd() { + String dataId = "betaDataId113"; + String group = "group113"; + String tenant = "tenant113"; + //mock exist beta + ConfigInfoStateWrapper mockedConfigInfoStateWrapper = new ConfigInfoStateWrapper(); + mockedConfigInfoStateWrapper.setDataId(dataId); + mockedConfigInfoStateWrapper.setGroup(group); + mockedConfigInfoStateWrapper.setTenant(tenant); + mockedConfigInfoStateWrapper.setId(123456L); + mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenThrow(new EmptyResultDataAccessException(1)) + .thenReturn(mockedConfigInfoStateWrapper); + + String betaIps = "betaips..."; + String srcIp = "srcUp..."; + String srcUser = "srcUser..."; + String appName = "appname"; + String content = "content111"; + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key34567"); + //execute + ConfigOperateResult configOperateResult = externalConfigInfoBetaPersistService.insertOrUpdateBetaCas(configInfo, + betaIps, srcIp, srcUser); + //expect return obj + Assert.assertEquals(mockedConfigInfoStateWrapper.getId(), configOperateResult.getId()); + Assert.assertEquals(mockedConfigInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + //verify add to be invoked + Mockito.verify(jdbcTemplate, times(1)) + .update(anyString(), eq(dataId), eq(group), eq(tenant), eq(configInfo.getAppName()), + eq(configInfo.getContent()), eq(configInfo.getMd5()), eq(betaIps), eq(srcIp), eq(srcUser), + any(Timestamp.class), any(Timestamp.class), eq(configInfo.getEncryptedDataKey())); + + } + + @Test + public void testInsertOrUpdateBetaCasOfException() { + String dataId = "betaDataId113"; + String group = "group113"; + String tenant = "tenant113"; + //mock exist beta + ConfigInfoStateWrapper mockedConfigInfoStateWrapper = new ConfigInfoStateWrapper(); + mockedConfigInfoStateWrapper.setDataId(dataId); + mockedConfigInfoStateWrapper.setGroup(group); + mockedConfigInfoStateWrapper.setTenant(tenant); + mockedConfigInfoStateWrapper.setId(123456L); + mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(mockedConfigInfoStateWrapper); + + String betaIps = "betaips..."; + String srcIp = "srcUp..."; + String srcUser = "srcUser..."; + String appName = "appname"; + String content = "content111"; + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key34567"); + configInfo.setMd5("casMd5"); + // mock update throw CannotGetJdbcConnectionException + when(jdbcTemplate.update(anyString(), eq(configInfo.getContent()), + eq(MD5Utils.md5Hex(content, Constants.PERSIST_ENCODE)), eq(betaIps), eq(srcIp), eq(srcUser), + any(Timestamp.class), eq(appName), eq(dataId), eq(group), eq(tenant), + eq(configInfo.getMd5()))).thenThrow(new CannotGetJdbcConnectionException("mock fail")); + //execute of update& expect. + try { + externalConfigInfoBetaPersistService.insertOrUpdateBetaCas(configInfo, betaIps, srcIp, srcUser); + Assert.assertTrue(false); + } catch (Exception exception) { + Assert.assertEquals("mock fail", exception.getMessage()); + } + + //mock query return null + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(null); + //mock add throw CannotGetJdbcConnectionException + when(jdbcTemplate.update(anyString(), eq(dataId), eq(group), eq(tenant), eq(configInfo.getAppName()), + eq(configInfo.getContent()), eq(MD5Utils.md5Hex(configInfo.getContent(), Constants.PERSIST_ENCODE)), + eq(betaIps), eq(srcIp), eq(srcUser), any(Timestamp.class), any(Timestamp.class), + eq(configInfo.getEncryptedDataKey()))).thenThrow(new CannotGetJdbcConnectionException("mock fail add")); + + //execute of add& expect. + try { + externalConfigInfoBetaPersistService.insertOrUpdateBetaCas(configInfo, betaIps, srcIp, srcUser); + Assert.assertTrue(false); + } catch (Exception exception) { + Assert.assertEquals("mock fail add", exception.getMessage()); + } + + //mock query throw CannotGetJdbcConnectionException + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenThrow( + new CannotGetJdbcConnectionException("get c fail")); + //execute of add& expect. + try { + externalConfigInfoBetaPersistService.insertOrUpdateBetaCas(configInfo, betaIps, srcIp, srcUser); + Assert.assertTrue(false); + } catch (Exception exception) { + Assert.assertEquals("get c fail", exception.getMessage()); + } + + } + + @Test + public void testRemoveConfigInfo4Beta() { + String dataId = "dataId456789"; + String group = "group4567"; + String tenant = "tenant56789o0"; + //mock exist beta + ConfigInfoStateWrapper mockedConfigInfoStateWrapper = new ConfigInfoStateWrapper(); + mockedConfigInfoStateWrapper.setDataId(dataId); + mockedConfigInfoStateWrapper.setGroup(group); + mockedConfigInfoStateWrapper.setTenant(tenant); + mockedConfigInfoStateWrapper.setId(123456L); + mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(mockedConfigInfoStateWrapper); + externalConfigInfoBetaPersistService.removeConfigInfo4Beta(dataId, group, tenant); + + //verity + Mockito.verify(jdbcTemplate, times(1)).update(anyString(), eq(dataId), eq(group), eq(tenant)); + + //mock query throw CannotGetJdbcConnectionException + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenThrow( + new CannotGetJdbcConnectionException("mock fail11111")); + + try { + externalConfigInfoBetaPersistService.removeConfigInfo4Beta(dataId, group, tenant); + Assert.assertTrue(false); + } catch (Exception exception) { + Assert.assertEquals("mock fail11111", exception.getMessage()); + } + } + + @Test + public void testFindConfigInfo4Beta() { + String dataId = "dataId456789"; + String group = "group4567"; + String tenant = "tenant56789o0"; + //mock exist beta + ConfigInfoBetaWrapper mockedConfigInfoStateWrapper = new ConfigInfoBetaWrapper(); + mockedConfigInfoStateWrapper.setDataId(dataId); + mockedConfigInfoStateWrapper.setGroup(group); + mockedConfigInfoStateWrapper.setTenant(tenant); + mockedConfigInfoStateWrapper.setId(123456L); + mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_BETA_WRAPPER_ROW_MAPPER))).thenReturn(mockedConfigInfoStateWrapper); + ConfigInfoBetaWrapper configInfo4BetaReturn = externalConfigInfoBetaPersistService.findConfigInfo4Beta(dataId, + group, tenant); + Assert.assertEquals(mockedConfigInfoStateWrapper, configInfo4BetaReturn); + + //mock query throw CannotGetJdbcConnectionException + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_BETA_WRAPPER_ROW_MAPPER))).thenThrow( + new CannotGetJdbcConnectionException("mock fail11111")); + try { + externalConfigInfoBetaPersistService.findConfigInfo4Beta(dataId, group, tenant); + Assert.assertTrue(false); + } catch (Exception exception) { + Assert.assertEquals("mock fail11111", exception.getMessage()); + } + + //mock query throw EmptyResultDataAccessException + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_BETA_WRAPPER_ROW_MAPPER))).thenThrow(new EmptyResultDataAccessException(1)); + ConfigInfoBetaWrapper configInfo4BetaNull = externalConfigInfoBetaPersistService.findConfigInfo4Beta(dataId, + group, tenant); + Assert.assertNull(configInfo4BetaNull); + } + + @Test + public void testConfigInfoBetaCount() { + when(jdbcTemplate.queryForObject(anyString(), eq(Integer.class))).thenReturn(101); + int returnCount = externalConfigInfoBetaPersistService.configInfoBetaCount(); + Assert.assertEquals(101, returnCount); + } + + @Test + public void testFindAllConfigInfoBetaForDumpAll() { + //mock count + when(jdbcTemplate.queryForObject(anyString(), eq(Integer.class))).thenReturn(12345); + + //mock page list + List mockList = new ArrayList<>(); + mockList.add(new ConfigInfoBetaWrapper()); + mockList.add(new ConfigInfoBetaWrapper()); + mockList.add(new ConfigInfoBetaWrapper()); + mockList.get(0).setLastModified(System.currentTimeMillis()); + mockList.get(1).setLastModified(System.currentTimeMillis()); + mockList.get(2).setLastModified(System.currentTimeMillis()); + + when(jdbcTemplate.query(anyString(), eq(new Object[] {}), eq(CONFIG_INFO_BETA_WRAPPER_ROW_MAPPER))).thenReturn( + mockList); + + int pageNo = 1; + int pageSize = 101; + when(jdbcTemplate.queryForObject(anyString(), eq(Integer.class))).thenReturn(101); + //execute & expect + Page pageReturn = externalConfigInfoBetaPersistService.findAllConfigInfoBetaForDumpAll( + pageNo, pageSize); + Assert.assertEquals(mockList, pageReturn.getPageItems()); + Assert.assertEquals(101, pageReturn.getTotalCount()); + + //mock count throw CannotGetJdbcConnectionException + when(jdbcTemplate.queryForObject(anyString(), eq(Integer.class))).thenThrow( + new CannotGetJdbcConnectionException("345678909fail")); + //execute &expect + try { + externalConfigInfoBetaPersistService.findAllConfigInfoBetaForDumpAll(pageNo, pageSize); + Assert.assertTrue(false); + } catch (Exception exception) { + Assert.assertEquals("345678909fail", exception.getMessage()); + } + } + +} + diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoPersistServiceImplTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoPersistServiceImplTest.java new file mode 100644 index 00000000000..f791eff24bc --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoPersistServiceImplTest.java @@ -0,0 +1,1274 @@ +/* + * 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.config.server.service.repository.extrnal; + +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.common.utils.MD5Utils; +import com.alibaba.nacos.common.utils.StringUtils; +import com.alibaba.nacos.config.server.constant.Constants; +import com.alibaba.nacos.config.server.model.ConfigAdvanceInfo; +import com.alibaba.nacos.config.server.model.ConfigAllInfo; +import com.alibaba.nacos.config.server.model.ConfigInfo; +import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; +import com.alibaba.nacos.config.server.model.ConfigInfoWrapper; +import com.alibaba.nacos.config.server.model.ConfigOperateResult; +import com.alibaba.nacos.config.server.model.SameConfigPolicy; +import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService; +import com.alibaba.nacos.config.server.service.sql.ExternalStorageUtils; +import com.alibaba.nacos.config.server.utils.TestCaseUtils; +import com.alibaba.nacos.persistence.datasource.DataSourceService; +import com.alibaba.nacos.persistence.datasource.DynamicDataSource; +import com.alibaba.nacos.persistence.model.Page; +import com.alibaba.nacos.plugin.datasource.constants.TableConstant; +import com.alibaba.nacos.plugin.datasource.mapper.ConfigInfoMapper; +import com.alibaba.nacos.sys.env.EnvUtil; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.springframework.dao.CannotAcquireLockException; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.dao.IncorrectResultSizeDataAccessException; +import org.springframework.jdbc.CannotGetJdbcConnectionException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.PreparedStatementCreator; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.transaction.support.TransactionTemplate; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_ADVANCE_INFO_ROW_MAPPER; +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_ALL_INFO_ROW_MAPPER; +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_ROW_MAPPER; +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER; +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_WRAPPER_ROW_MAPPER; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; + +@RunWith(SpringJUnit4ClassRunner.class) +public class ExternalConfigInfoPersistServiceImplTest { + + private ExternalConfigInfoPersistServiceImpl externalConfigInfoPersistService; + + @Mock + private HistoryConfigInfoPersistService historyConfigInfoPersistService; + + @Mock + private DataSourceService dataSourceService; + + @Mock + private JdbcTemplate jdbcTemplate; + + private TransactionTemplate transactionTemplate = TestCaseUtils.createMockTransactionTemplate(); + + MockedStatic envUtilMockedStatic; + + MockedStatic externalStorageUtilsMockedStatic; + + MockedStatic dynamicDataSourceMockedStatic; + + @Mock + DynamicDataSource dynamicDataSource; + + @Before + public void before() { + dynamicDataSourceMockedStatic = Mockito.mockStatic(DynamicDataSource.class); + envUtilMockedStatic = Mockito.mockStatic(EnvUtil.class); + externalStorageUtilsMockedStatic = Mockito.mockStatic(ExternalStorageUtils.class); + when(DynamicDataSource.getInstance()).thenReturn(dynamicDataSource); + when(dynamicDataSource.getDataSource()).thenReturn(dataSourceService); + when(dataSourceService.getTransactionTemplate()).thenReturn(transactionTemplate); + when(dataSourceService.getJdbcTemplate()).thenReturn(jdbcTemplate); + when(dataSourceService.getDataSourceType()).thenReturn("mysql"); + /*when(EnvUtil.getProperty(anyString(), eq(Boolean.class), + eq(false))).thenReturn(false);*/ + envUtilMockedStatic.when(() -> EnvUtil.getProperty(anyString(), eq(Boolean.class), eq(false))) + .thenReturn(false); + externalConfigInfoPersistService = new ExternalConfigInfoPersistServiceImpl(historyConfigInfoPersistService); + } + + @After + public void after() { + dynamicDataSourceMockedStatic.close(); + envUtilMockedStatic.close(); + externalStorageUtilsMockedStatic.close(); + } + + @Test + public void testInsertOrUpdateOfInsertConfigSuccess() { + + String dataId = "dataId"; + String group = "group"; + String tenant = "tenant"; + String appName = "appNameNew"; + String content = "content132456"; + Map configAdvanceInfo = new HashMap<>(); + configAdvanceInfo.put("config_tags", "tag1,tag2"); + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + long insertConfigIndoId = 12345678765L; + GeneratedKeyHolder generatedKeyHolder = TestCaseUtils.createGeneratedKeyHolder(insertConfigIndoId); + externalStorageUtilsMockedStatic.when(ExternalStorageUtils::createKeyHolder).thenReturn(generatedKeyHolder); + //mock get config state + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(null, new ConfigInfoStateWrapper()); + //mock insert config info + Mockito.when(jdbcTemplate.update(any(PreparedStatementCreator.class), eq(generatedKeyHolder))).thenReturn(1); + Mockito.when(jdbcTemplate.update( + eq(externalConfigInfoPersistService.mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_TAGS_RELATION) + .insert(Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id"))), + eq(insertConfigIndoId), eq("tag1"), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant))) + .thenReturn(1); + Mockito.when(jdbcTemplate.update( + eq(externalConfigInfoPersistService.mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_TAGS_RELATION) + .insert(Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id"))), + eq(insertConfigIndoId), eq("tag2"), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant))) + .thenReturn(1); + String srcIp = "srcIp"; + String srcUser = "srcUser"; + //mock insert config info + Mockito.doNothing().when(historyConfigInfoPersistService) + .insertConfigHistoryAtomic(eq(0), eq(configInfo), eq(srcIp), eq(srcUser), any(Timestamp.class), + eq("I")); + + externalConfigInfoPersistService.insertOrUpdate(srcIp, srcUser, configInfo, configAdvanceInfo); + //expect insert config info + Mockito.verify(jdbcTemplate, times(1)).update(any(PreparedStatementCreator.class), eq(generatedKeyHolder)); + //expect insert config tags + Mockito.verify(jdbcTemplate, times(1)).update(eq( + externalConfigInfoPersistService.mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_TAGS_RELATION) + .insert(Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id"))), + eq(insertConfigIndoId), eq("tag1"), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant)); + Mockito.verify(jdbcTemplate, times(1)).update(eq( + externalConfigInfoPersistService.mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_TAGS_RELATION) + .insert(Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id"))), + eq(insertConfigIndoId), eq("tag2"), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant)); + + //expect insert history info + Mockito.verify(historyConfigInfoPersistService, times(1)) + .insertConfigHistoryAtomic(eq(0L), eq(configInfo), eq(srcIp), eq(srcUser), any(Timestamp.class), + eq("I")); + + } + + @Test + public void testInsertOrUpdateCasOfInsertConfigSuccess() { + + Map configAdvanceInfo = new HashMap<>(); + configAdvanceInfo.put("config_tags", "tag1,tag2"); + String dataId = "dataId"; + String group = "group"; + String tenant = "tenant"; + String appName = "appName"; + String content = "content132456"; + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + long insertConfigIndoId = 12345678765L; + GeneratedKeyHolder generatedKeyHolder = TestCaseUtils.createGeneratedKeyHolder(insertConfigIndoId); + externalStorageUtilsMockedStatic.when(ExternalStorageUtils::createKeyHolder).thenReturn(generatedKeyHolder); + //mock get config state + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(null, new ConfigInfoStateWrapper()); + //mock insert config info + Mockito.when(jdbcTemplate.update(any(PreparedStatementCreator.class), eq(generatedKeyHolder))).thenReturn(1); + Mockito.when(jdbcTemplate.update( + eq(externalConfigInfoPersistService.mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_TAGS_RELATION) + .insert(Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id"))), + eq(insertConfigIndoId), eq("tag1"), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant))) + .thenReturn(1); + Mockito.when(jdbcTemplate.update( + eq(externalConfigInfoPersistService.mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_TAGS_RELATION) + .insert(Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id"))), + eq(insertConfigIndoId), eq("tag2"), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant))) + .thenReturn(1); + String srcIp = "srcIp"; + String srcUser = "srcUser"; + //mock insert config info + Mockito.doNothing().when(historyConfigInfoPersistService) + .insertConfigHistoryAtomic(eq(0), eq(configInfo), eq(srcIp), eq(srcUser), any(Timestamp.class), + eq("I")); + + externalConfigInfoPersistService.insertOrUpdateCas(srcIp, srcUser, configInfo, configAdvanceInfo); + //expect insert config info + Mockito.verify(jdbcTemplate, times(1)).update(any(PreparedStatementCreator.class), eq(generatedKeyHolder)); + //expect insert config tags + Mockito.verify(jdbcTemplate, times(1)).update(eq( + externalConfigInfoPersistService.mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_TAGS_RELATION) + .insert(Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id"))), + eq(insertConfigIndoId), eq("tag1"), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant)); + Mockito.verify(jdbcTemplate, times(1)).update(eq( + externalConfigInfoPersistService.mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_TAGS_RELATION) + .insert(Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id"))), + eq(insertConfigIndoId), eq("tag2"), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant)); + + //expect insert history info + Mockito.verify(historyConfigInfoPersistService, times(1)) + .insertConfigHistoryAtomic(eq(0L), eq(configInfo), eq(srcIp), eq(srcUser), any(Timestamp.class), + eq("I")); + + } + + @Test + public void testInsertOrUpdateOfException() { + String dataId = "dataId"; + String group = "group"; + String tenant = "tenant"; + //mock get config state + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(null); + //mock insert config throw exception + long insertConfigIndoId = 12345678765L; + GeneratedKeyHolder generatedKeyHolder = TestCaseUtils.createGeneratedKeyHolder(insertConfigIndoId); + externalStorageUtilsMockedStatic.when(ExternalStorageUtils::createKeyHolder).thenReturn(generatedKeyHolder); + Mockito.when(jdbcTemplate.update(any(PreparedStatementCreator.class), any(KeyHolder.class))) + .thenThrow(new CannotGetJdbcConnectionException("mock fail")); + Map configAdvanceInfo = new HashMap<>(); + configAdvanceInfo.put("config_tags", "tag1,tag2"); + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, null, "content"); + try { + externalConfigInfoPersistService.insertOrUpdate("srcIp", "srcUser", configInfo, configAdvanceInfo); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertEquals(e.getMessage(), "mock fail"); + } + + } + + @Test + public void testInsertOrUpdateOfUpdateConfigSuccess() { + + Map configAdvanceInfo = new HashMap<>(); + configAdvanceInfo.put("config_tags", "tag1,tag2"); + configAdvanceInfo.put("desc", "desc11"); + configAdvanceInfo.put("use", "use2233"); + configAdvanceInfo.put("effect", "effect222"); + configAdvanceInfo.put("type", "type3"); + configAdvanceInfo.put("schema", "schema"); + + String dataId = "dataId"; + String group = "group"; + String tenant = "tenant"; + String content = "content132456"; + + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, null, content); + String encryptedDataKey = "key34567"; + configInfo.setEncryptedDataKey(encryptedDataKey); + //mock get config state,first and second is not null + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))) + .thenReturn(new ConfigInfoStateWrapper(), new ConfigInfoStateWrapper()); + + //mock select config info before update + ConfigInfoWrapper configInfoWrapperOld = new ConfigInfoWrapper(); + configInfoWrapperOld.setDataId(dataId); + configInfoWrapperOld.setGroup(group); + configInfoWrapperOld.setTenant(tenant); + configInfoWrapperOld.setAppName("old_app"); + configInfoWrapperOld.setMd5("old_md5"); + configInfoWrapperOld.setId(12345678765L); + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_WRAPPER_ROW_MAPPER))).thenReturn(configInfoWrapperOld); + String srcIp = "srcIp"; + String srcUser = "srcUser"; + //mock update config info + Mockito.when(jdbcTemplate.update( + eq(externalConfigInfoPersistService.mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO) + .update(Arrays.asList("content", "md5", "src_ip", "src_user", "gmt_modified", "app_name", + "c_desc", "c_use", "effect", "type", "c_schema", "encrypted_data_key"), + Arrays.asList("data_id", "group_id", "tenant_id"))), eq(configInfo.getContent()), + eq(configInfo.getMd5()), eq(srcIp), eq(srcUser), any(), eq(configInfoWrapperOld.getAppName()), + eq(configAdvanceInfo.get("desc")), eq(configAdvanceInfo.get("use")), + eq(configAdvanceInfo.get("effect")), eq(configAdvanceInfo.get("type")), + eq(configAdvanceInfo.get("schema")), eq(encryptedDataKey), eq(configInfo.getDataId()), + eq(configInfo.getGroup()), eq(tenant))).thenReturn(1); + + //mock insert config tags. + Mockito.when(jdbcTemplate.update( + eq(externalConfigInfoPersistService.mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_TAGS_RELATION) + .insert(Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id"))), + eq(12345678765L), anyString(), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant))).thenReturn(1); + + //mock insert his config info + Mockito.doNothing().when(historyConfigInfoPersistService) + .insertConfigHistoryAtomic(eq(configInfoWrapperOld.getId()), eq(configInfo), eq(srcIp), eq(srcUser), + any(Timestamp.class), eq("I")); + + externalConfigInfoPersistService.insertOrUpdate(srcIp, srcUser, configInfo, configAdvanceInfo); + + //expect update config tags + Mockito.verify(jdbcTemplate, times(1)).update(eq( + externalConfigInfoPersistService.mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_TAGS_RELATION) + .insert(Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id"))), + eq(configInfoWrapperOld.getId()), eq("tag1"), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant)); + Mockito.verify(jdbcTemplate, times(1)).update(eq( + externalConfigInfoPersistService.mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_TAGS_RELATION) + .insert(Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id"))), + eq(configInfoWrapperOld.getId()), eq("tag2"), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant)); + + //expect insert history info + Mockito.verify(historyConfigInfoPersistService, times(1)) + .insertConfigHistoryAtomic(eq(configInfoWrapperOld.getId()), any(ConfigInfo.class), eq(srcIp), + eq(srcUser), any(Timestamp.class), eq("U")); + + } + + @Test + public void testInsertOrUpdateCasOfUpdateConfigSuccess() { + + Map configAdvanceInfo = new HashMap<>(); + configAdvanceInfo.put("config_tags", "tag1,tag2"); + configAdvanceInfo.put("desc", "desc11"); + configAdvanceInfo.put("use", "use2233"); + configAdvanceInfo.put("effect", "effect222"); + configAdvanceInfo.put("type", "type3"); + configAdvanceInfo.put("schema", "schema"); + String dataId = "dataId"; + String group = "group"; + String tenant = "tenant"; + String content = "content132456"; + String encryptedDataKey = "key34567"; + String casMd5 = "casMd5.."; + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, null, content); + configInfo.setMd5(casMd5); + configInfo.setEncryptedDataKey(encryptedDataKey); + + //mock get config state,first and second is not null + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))) + .thenReturn(new ConfigInfoStateWrapper(), new ConfigInfoStateWrapper()); + + //mock select config info before update + ConfigInfoWrapper configInfoWrapperOld = new ConfigInfoWrapper(); + configInfoWrapperOld.setDataId(dataId); + configInfoWrapperOld.setGroup(group); + configInfoWrapperOld.setTenant(tenant); + configInfoWrapperOld.setAppName("old_app11"); + configInfoWrapperOld.setMd5("old_md5"); + configInfoWrapperOld.setId(123456799L); + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_WRAPPER_ROW_MAPPER))).thenReturn(configInfoWrapperOld); + String srcIp = "srcIp"; + String srcUser = "srcUser"; + //mock update config info cas + Mockito.when( + jdbcTemplate.update(anyString(), eq(content), eq(MD5Utils.md5Hex(content, Constants.PERSIST_ENCODE)), + eq(srcIp), eq(srcUser), any(Timestamp.class), eq(configInfoWrapperOld.getAppName()), + eq(configAdvanceInfo.get("desc")), eq(configAdvanceInfo.get("use")), + eq(configAdvanceInfo.get("effect")), eq(configAdvanceInfo.get("type")), + eq(configAdvanceInfo.get("schema")), eq(dataId), eq(group), eq(tenant), eq(casMd5))) + .thenReturn(1); + + //mock insert config tags. + Mockito.when(jdbcTemplate.update( + eq(externalConfigInfoPersistService.mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_TAGS_RELATION) + .insert(Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id"))), + eq(configInfoWrapperOld.getId()), anyString(), eq(StringUtils.EMPTY), eq(dataId), eq(group), + eq(tenant))).thenReturn(1); + + //mock insert his config info + Mockito.doNothing().when(historyConfigInfoPersistService) + .insertConfigHistoryAtomic(eq(configInfoWrapperOld.getId()), eq(configInfo), eq(srcIp), eq(srcUser), + any(Timestamp.class), eq("I")); + + externalConfigInfoPersistService.insertOrUpdateCas(srcIp, srcUser, configInfo, configAdvanceInfo); + //expect update config cas + Mockito.verify(jdbcTemplate, times(1)) + .update(anyString(), eq(content), eq(MD5Utils.md5Hex(content, Constants.PERSIST_ENCODE)), eq(srcIp), + eq(srcUser), any(Timestamp.class), eq(configInfoWrapperOld.getAppName()), + eq(configAdvanceInfo.get("desc")), eq(configAdvanceInfo.get("use")), + eq(configAdvanceInfo.get("effect")), eq(configAdvanceInfo.get("type")), + eq(configAdvanceInfo.get("schema")), eq(dataId), eq(group), eq(tenant), eq(casMd5)); + + //expect update config tags + Mockito.verify(jdbcTemplate, times(1)).update(eq( + externalConfigInfoPersistService.mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_TAGS_RELATION) + .insert(Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id"))), + eq(configInfoWrapperOld.getId()), eq("tag1"), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant)); + Mockito.verify(jdbcTemplate, times(1)).update(eq( + externalConfigInfoPersistService.mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_TAGS_RELATION) + .insert(Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id"))), + eq(configInfoWrapperOld.getId()), eq("tag2"), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant)); + + //expect insert history info + Mockito.verify(historyConfigInfoPersistService, times(1)) + .insertConfigHistoryAtomic(eq(configInfoWrapperOld.getId()), any(ConfigInfo.class), eq(srcIp), + eq(srcUser), any(Timestamp.class), eq("U")); + + } + + @Test + public void testCreatePsForInsertConfigInfo() throws SQLException { + + Map configAdvanceInfo = new HashMap<>(); + configAdvanceInfo.put("config_tags", "tag1,tag2"); + configAdvanceInfo.put("desc", "desc11"); + configAdvanceInfo.put("use", "use2233"); + configAdvanceInfo.put("effect", "effect222"); + configAdvanceInfo.put("type", "type3"); + configAdvanceInfo.put("schema", "schema"); + String dataId = "dataId"; + String group = "group"; + String tenant = "tenant"; + String content = "content132456"; + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, null, content); + Connection mockConnection = Mockito.mock(Connection.class); + PreparedStatement preparedStatement = Mockito.mock(PreparedStatement.class); + + ConfigInfoMapper configInfoMapper = externalConfigInfoPersistService.mapperManager.findMapper( + dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); + + Mockito.when(mockConnection.prepareStatement(anyString(), any(String[].class))).thenReturn(preparedStatement); + String srcIp = "srcIp"; + String srcUser = "srcUser"; + externalConfigInfoPersistService.createPsForInsertConfigInfo(srcIp, srcUser, configInfo, configAdvanceInfo, + mockConnection, configInfoMapper); + Mockito.verify(preparedStatement, times(14)).setString(anyInt(), anyString()); + Mockito.verify(preparedStatement, times(2)).setTimestamp(anyInt(), any(Timestamp.class)); + + } + + @Test + public void testRemoveConfigInfo() { + String dataId = "dataId4567"; + String group = "group3456789"; + String tenant = "tenant4567890"; + + //mock exist config info + ConfigInfoWrapper configInfoWrapperOld = new ConfigInfoWrapper(); + configInfoWrapperOld.setDataId(dataId); + configInfoWrapperOld.setGroup(group); + configInfoWrapperOld.setTenant(tenant); + configInfoWrapperOld.setAppName("old_app"); + configInfoWrapperOld.setContent("old content"); + configInfoWrapperOld.setMd5("old_md5"); + configInfoWrapperOld.setId(12345678765L); + configInfoWrapperOld.setEncryptedDataKey("key3456"); + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_WRAPPER_ROW_MAPPER))).thenReturn(configInfoWrapperOld); + String srcIp = "srcIp1234"; + String srcUser = "srcUser"; + externalConfigInfoPersistService.removeConfigInfo(dataId, group, tenant, srcIp, srcUser); + + //expect delete to be invoked + Mockito.verify(jdbcTemplate, times(1)).update(anyString(), eq(dataId), eq(group), eq(tenant)); + //expect delete tags to be invoked + Mockito.verify(jdbcTemplate, times(1)).update(anyString(), eq(configInfoWrapperOld.getId())); + //expect insert delete history + Mockito.verify(historyConfigInfoPersistService, times(1)) + .insertConfigHistoryAtomic(eq(configInfoWrapperOld.getId()), eq(configInfoWrapperOld), eq(srcIp), + eq(srcUser), any(), eq("D")); + + } + + @Test + public void testRemoveConfigInfoByIds() { + + //mock exist config info + List configInfos = new ArrayList<>(); + configInfos.add(new ConfigInfo("data1", "group", "tenant", "app", "content")); + configInfos.add(new ConfigInfo("data2", "grou2", "tenan2", "app2", "content2")); + List deleteIds = Arrays.asList(12344L, 3456789L); + configInfos.get(0).setId(12344L); + configInfos.get(1).setId(3456789L); + Mockito.when(jdbcTemplate.query(anyString(), eq(deleteIds.toArray()), eq(CONFIG_INFO_ROW_MAPPER))) + .thenReturn(configInfos); + String srcIp = "srcIp1234"; + String srcUser = "srcUser"; + externalConfigInfoPersistService.removeConfigInfoByIds(deleteIds, srcIp, srcUser); + + //expect delete to be invoked + Mockito.verify(jdbcTemplate, times(1)).update(anyString(), eq(deleteIds.get(0)), eq(deleteIds.get(1))); + //expect delete tags to be invoked + Mockito.verify(jdbcTemplate, times(1)).update(anyString(), eq(deleteIds.get(0))); + Mockito.verify(jdbcTemplate, times(1)).update(anyString(), eq(deleteIds.get(1))); + //expect insert delete history + Mockito.verify(historyConfigInfoPersistService, times(1)) + .insertConfigHistoryAtomic(eq(configInfos.get(0).getId()), eq(configInfos.get(0)), eq(srcIp), + eq(srcUser), any(), eq("D")); + Mockito.verify(historyConfigInfoPersistService, times(1)) + .insertConfigHistoryAtomic(eq(configInfos.get(1).getId()), eq(configInfos.get(1)), eq(srcIp), + eq(srcUser), any(), eq("D")); + + } + + @Test + public void testBatchInsertOrUpdateOverwrite() throws NacosException { + List configInfoList = new ArrayList<>(); + //insert direct + configInfoList.add(createMockConfigAllInfo(0)); + //exist config and overwrite + configInfoList.add(createMockConfigAllInfo(1)); + //insert direct + configInfoList.add(createMockConfigAllInfo(2)); + String srcUser = "srcUser1324"; + String srcIp = "srcIp1243"; + Map configAdvanceInfo = new HashMap<>(); + //mock transactionTemplate and replace + TransactionTemplate transactionTemplateCurrent = Mockito.mock(TransactionTemplate.class); + ReflectionTestUtils.setField(externalConfigInfoPersistService, "tjt", transactionTemplateCurrent); + //mock add config 1 success,config 2 fail and update success,config 3 success + Mockito.when(transactionTemplateCurrent.execute(any())) + .thenReturn(new ConfigOperateResult(true), new ConfigOperateResult(false), + new ConfigOperateResult(true), new ConfigOperateResult(true)); + + Map stringObjectMap = externalConfigInfoPersistService.batchInsertOrUpdate(configInfoList, + srcUser, srcIp, configAdvanceInfo, SameConfigPolicy.OVERWRITE); + Assert.assertEquals(3, stringObjectMap.get("succCount")); + Assert.assertEquals(0, stringObjectMap.get("skipCount")); + } + + @Test + public void testBatchInsertOrUpdateSkip() throws NacosException { + List configInfoList = new ArrayList<>(); + //insert direct + configInfoList.add(createMockConfigAllInfo(0)); + //exist config and overwrite + configInfoList.add(createMockConfigAllInfo(1)); + //insert direct + configInfoList.add(createMockConfigAllInfo(2)); + String srcUser = "srcUser1324"; + String srcIp = "srcIp1243"; + Map configAdvanceInfo = new HashMap<>(); + //mock transactionTemplate and replace + TransactionTemplate transactionTemplateCurrent = Mockito.mock(TransactionTemplate.class); + ReflectionTestUtils.setField(externalConfigInfoPersistService, "tjt", transactionTemplateCurrent); + //mock add config 1 success,config 2 fail and skip,config 3 success + Mockito.when(transactionTemplateCurrent.execute(any())) + .thenReturn(new ConfigOperateResult(true), new ConfigOperateResult(false), + new ConfigOperateResult(true)); + + Map stringObjectMap = externalConfigInfoPersistService.batchInsertOrUpdate(configInfoList, + srcUser, srcIp, configAdvanceInfo, SameConfigPolicy.SKIP); + Assert.assertEquals(2, stringObjectMap.get("succCount")); + Assert.assertEquals(1, stringObjectMap.get("skipCount")); + Assert.assertEquals(configInfoList.get(1).getDataId(), + ((List>) stringObjectMap.get("skipData")).get(0).get("dataId")); + } + + @Test + public void testBatchInsertOrUpdateAbort() throws NacosException { + List configInfoList = new ArrayList<>(); + //insert direct + configInfoList.add(createMockConfigAllInfo(0)); + //exist config and overwrite + configInfoList.add(createMockConfigAllInfo(1)); + //insert direct + configInfoList.add(createMockConfigAllInfo(2)); + String srcUser = "srcUser1324"; + String srcIp = "srcIp1243"; + Map configAdvanceInfo = new HashMap<>(); + //mock transactionTemplate and replace + TransactionTemplate transactionTemplateCurrent = Mockito.mock(TransactionTemplate.class); + ReflectionTestUtils.setField(externalConfigInfoPersistService, "tjt", transactionTemplateCurrent); + //mock add config 1 success,config 2 fail and abort,config 3 not operated + Mockito.when(transactionTemplateCurrent.execute(any())) + .thenReturn(new ConfigOperateResult(true), new ConfigOperateResult(false)); + + Map stringObjectMap = externalConfigInfoPersistService.batchInsertOrUpdate(configInfoList, + srcUser, srcIp, configAdvanceInfo, SameConfigPolicy.ABORT); + Assert.assertEquals(1, stringObjectMap.get("succCount")); + Assert.assertEquals(1, stringObjectMap.get("skipCount")); + // config 2 failed + Assert.assertEquals(configInfoList.get(1).getDataId(), + ((List>) stringObjectMap.get("failData")).get(0).get("dataId")); + //skip config 3 + Assert.assertEquals(configInfoList.get(2).getDataId(), + ((List>) stringObjectMap.get("skipData")).get(0).get("dataId")); + } + + private ConfigAllInfo createMockConfigAllInfo(long mockId) { + ConfigAllInfo configAllInfo = new ConfigAllInfo(); + configAllInfo.setDataId("test" + mockId + ".yaml"); + configAllInfo.setGroup("test"); + configAllInfo.setCreateIp("localhost"); + configAllInfo.setCreateUser("test"); + configAllInfo.setContent("23456789000content"); + return configAllInfo; + } + + private ConfigInfoWrapper createMockConfigInfoWrapper(long mockId) { + ConfigInfoWrapper configAllInfo = new ConfigInfoWrapper(); + configAllInfo.setDataId("test" + mockId + ".yaml"); + configAllInfo.setGroup("test"); + configAllInfo.setContent("23456789000content"); + return configAllInfo; + } + + private ConfigInfo createMockConfigInfo(long mockId) { + ConfigInfo configInfo = new ConfigInfo(); + configInfo.setDataId("test" + mockId + ".yaml"); + configInfo.setGroup("test"); + configInfo.setContent("23456789000content"); + + return configInfo; + } + + @Test + public void testFindConfigMaxId() { + + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(Long.class))).thenReturn(123456L); + long configMaxId = externalConfigInfoPersistService.findConfigMaxId(); + Assert.assertEquals(123456L, configMaxId); + } + + @Test + public void testFindConfigMaxId0() { + + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(Long.class))).thenThrow(new NullPointerException()); + long configMaxId = externalConfigInfoPersistService.findConfigMaxId(); + Assert.assertEquals(0, configMaxId); + } + + @Test + public void testFindConfigInfoById() { + long id = 1234567890876L; + ConfigInfo configInfo = new ConfigInfo(); + configInfo.setId(id); + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {id}), eq(CONFIG_INFO_ROW_MAPPER))) + .thenReturn(configInfo); + ConfigInfo configReturn = externalConfigInfoPersistService.findConfigInfo(id); + Assert.assertEquals(id, configReturn.getId()); + } + + @Test + public void testFindConfigInfoByIdNull() { + long id = 1234567890876L; + ConfigInfo configInfo = new ConfigInfo(); + configInfo.setId(id); + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {id}), eq(CONFIG_INFO_ROW_MAPPER))) + .thenThrow(new EmptyResultDataAccessException(1)); + ConfigInfo configReturn = externalConfigInfoPersistService.findConfigInfo(id); + Assert.assertEquals(null, configReturn); + } + + @Test + public void testFindConfigInfoByIdGetConFail() { + long id = 1234567890876L; + ConfigInfo configInfo = new ConfigInfo(); + configInfo.setId(id); + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {id}), eq(CONFIG_INFO_ROW_MAPPER))) + .thenThrow(new CannotGetJdbcConnectionException("mocked exp")); + try { + ConfigInfo configReturn = externalConfigInfoPersistService.findConfigInfo(id); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertTrue(e instanceof CannotGetJdbcConnectionException); + } + } + + @Test + public void testFindConfigInfoByDataId() { + String dataId = "dataId4567"; + String group = "group3456789"; + String tenant = "tenant4567890"; + ConfigInfoWrapper configInfoWrapper = new ConfigInfoWrapper(); + configInfoWrapper.setDataId(dataId); + configInfoWrapper.setGroup(group); + configInfoWrapper.setTenant(tenant); + + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_WRAPPER_ROW_MAPPER))).thenReturn(configInfoWrapper); + ConfigInfo configReturn = externalConfigInfoPersistService.findConfigInfo(dataId, group, tenant); + Assert.assertEquals(dataId, configReturn.getDataId()); + } + + @Test + public void testFindConfigInfoByDataIdNull() { + String dataId = "dataId4567"; + String group = "group3456789"; + String tenant = "tenant4567890"; + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_WRAPPER_ROW_MAPPER))).thenThrow(new EmptyResultDataAccessException(1)); + ConfigInfoWrapper configReturn = externalConfigInfoPersistService.findConfigInfo(dataId, group, tenant); + Assert.assertEquals(null, configReturn); + } + + @Test + public void testFindConfigInfoByDataIdGetConFail() { + String dataId = "dataId4567222"; + String group = "group3456789"; + String tenant = "tenant4567890"; + + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_WRAPPER_ROW_MAPPER))).thenThrow(new CannotGetJdbcConnectionException("mocked exp")); + try { + externalConfigInfoPersistService.findConfigInfo(dataId, group, tenant); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertTrue(e instanceof CannotGetJdbcConnectionException); + } + } + + @Test + public void testFindConfigInfo4Page() { + String dataId = "dataId4567222"; + String group = "group3456789"; + String tenant = "tenant4567890"; + + //mock total count + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {tenant, dataId, group}), + eq(Integer.class))).thenReturn(new Integer(9)); + //mock page list + List result = new ArrayList<>(); + result.add(createMockConfigInfo(0)); + result.add(createMockConfigInfo(1)); + result.add(createMockConfigInfo(2)); + when(jdbcTemplate.query(anyString(), eq(new Object[] {tenant, dataId, group}), + eq(CONFIG_INFO_ROW_MAPPER))).thenReturn(result); + Map configAdvanceInfo = new HashMap<>(); + Page configInfo4Page = externalConfigInfoPersistService.findConfigInfo4Page(1, 3, dataId, group, + tenant, configAdvanceInfo); + Assert.assertEquals(result.size(), configInfo4Page.getPageItems().size()); + Assert.assertEquals(9, configInfo4Page.getTotalCount()); + + } + + @Test + public void testFindConfigInfo4PageWithTags() { + String dataId = "dataId4567222"; + String group = "group3456789"; + String tenant = "tenant4567890"; + Map configAdvanceInfo = new HashMap<>(); + configAdvanceInfo.put("config_tags", "tags1,tags3"); + + //mock total count + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {tenant, dataId, group, "tags1", "tags3"}), + eq(Integer.class))).thenReturn(new Integer(9)); + //mock page list + List result = new ArrayList<>(); + result.add(createMockConfigInfo(0)); + result.add(createMockConfigInfo(1)); + result.add(createMockConfigInfo(2)); + when(jdbcTemplate.query(anyString(), eq(new Object[] {tenant, dataId, group, "tags1", "tags3"}), + eq(CONFIG_INFO_ROW_MAPPER))).thenReturn(result); + + Page configInfo4Page = externalConfigInfoPersistService.findConfigInfo4Page(1, 3, dataId, group, + tenant, configAdvanceInfo); + Assert.assertEquals(result.size(), configInfo4Page.getPageItems().size()); + Assert.assertEquals(9, configInfo4Page.getTotalCount()); + } + + @Test + public void testConfigInfoCount() { + + //mock total count + when(jdbcTemplate.queryForObject(anyString(), eq(Integer.class))).thenReturn(new Integer(9)); + int count = externalConfigInfoPersistService.configInfoCount(); + Assert.assertEquals(9, count); + + when(jdbcTemplate.queryForObject(anyString(), eq(Integer.class))).thenReturn(null); + try { + externalConfigInfoPersistService.configInfoCount(); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertTrue(e instanceof IllegalArgumentException); + } + + } + + @Test + public void testConfigInfoCountByTenant() { + + String tenant = "tenant124"; + //mock total count + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {tenant}), eq(Integer.class))).thenReturn( + new Integer(90)); + int count = externalConfigInfoPersistService.configInfoCount(tenant); + Assert.assertEquals(90, count); + + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {tenant}), eq(Integer.class))).thenReturn(null); + try { + externalConfigInfoPersistService.configInfoCount(tenant); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertTrue(e instanceof IllegalArgumentException); + } + + } + + @Test + public void testFindConfigInfoLike4Page() { + String dataId = "dataId4567222*"; + String group = "group3456789*"; + String tenant = "tenant4567890"; + String appName = "appName1234"; + String content = "content123"; + Map configAdvanceInfo = new HashMap<>(); + configAdvanceInfo.put("appName", appName); + configAdvanceInfo.put("content", content); + //mock total count + when(jdbcTemplate.queryForObject(anyString(), + eq(new Object[] {tenant, dataId.replaceAll("\\*", "%"), group.replaceAll("\\*", "%"), appName, + content}), eq(Integer.class))).thenReturn(new Integer(9)); + //mock page list + List result = new ArrayList<>(); + result.add(createMockConfigInfo(0)); + result.add(createMockConfigInfo(1)); + result.add(createMockConfigInfo(2)); + when(jdbcTemplate.query(anyString(), + eq(new Object[] {tenant, dataId.replaceAll("\\*", "%"), group.replaceAll("\\*", "%"), appName, + content}), eq(CONFIG_INFO_ROW_MAPPER))).thenReturn(result); + + Page configInfo4Page = externalConfigInfoPersistService.findConfigInfoLike4Page(1, 3, dataId, group, + tenant, configAdvanceInfo); + Assert.assertEquals(result.size(), configInfo4Page.getPageItems().size()); + Assert.assertEquals(9, configInfo4Page.getTotalCount()); + + } + + @Test + public void testFindConfigInfoLike4PageWithTags() { + + String appName = "appName1234"; + String content = "content123"; + Map configAdvanceInfo = new HashMap<>(); + configAdvanceInfo.put("appName", appName); + configAdvanceInfo.put("content", content); + configAdvanceInfo.put("config_tags", "tags,tag2"); + String dataId = "dataId4567222*"; + String group = "group3456789*"; + String tenant = "tenant4567890"; + //mock total count + when(jdbcTemplate.queryForObject(anyString(), + eq(new Object[] {tenant, dataId.replaceAll("\\*", "%"), group.replaceAll("\\*", "%"), appName, content, + "tags", "tag2"}), eq(Integer.class))).thenReturn(new Integer(9)); + //mock page list + List result = new ArrayList<>(); + result.add(createMockConfigInfo(0)); + result.add(createMockConfigInfo(1)); + result.add(createMockConfigInfo(2)); + when(jdbcTemplate.query(anyString(), + eq(new Object[] {tenant, dataId.replaceAll("\\*", "%"), group.replaceAll("\\*", "%"), appName, content, + "tags", "tag2"}), eq(CONFIG_INFO_ROW_MAPPER))).thenReturn(result); + + Page configInfo4Page = externalConfigInfoPersistService.findConfigInfoLike4Page(1, 3, dataId, group, + tenant, configAdvanceInfo); + Assert.assertEquals(result.size(), configInfo4Page.getPageItems().size()); + Assert.assertEquals(9, configInfo4Page.getTotalCount()); + + } + + @Test + public void testFindChangeConfig() { + + //mock page list + List result = new ArrayList<>(); + result.add(createMockConfigInfoWrapper(0)); + result.add(createMockConfigInfoWrapper(1)); + result.add(createMockConfigInfoWrapper(2)); + Timestamp startTime = new Timestamp(System.currentTimeMillis() - 1000L); + long lastMaxId = 10000L; + int pageSize = 30; + when(jdbcTemplate.query(anyString(), eq(new Object[] {startTime, lastMaxId, pageSize}), + eq(CONFIG_INFO_WRAPPER_ROW_MAPPER))).thenReturn(result); + + List configInfo4List = externalConfigInfoPersistService.findChangeConfig(startTime, + lastMaxId, pageSize); + Assert.assertEquals(result.size(), configInfo4List.size()); + } + + @Test + public void testFindChangeConfigError() { + Timestamp startTime = new Timestamp(System.currentTimeMillis() - 1000L); + long lastMaxId = 10000L; + int pageSize = 30; + //mock page list + when(jdbcTemplate.query(anyString(), eq(new Object[] {startTime, lastMaxId, pageSize}), + eq(CONFIG_INFO_WRAPPER_ROW_MAPPER))).thenThrow(new CannotAcquireLockException("mock ex")); + try { + List configInfo4List = externalConfigInfoPersistService.findChangeConfig(startTime, + lastMaxId, pageSize); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertTrue(e instanceof CannotAcquireLockException); + } + } + + @Test + public void testSelectTagByConfig() { + String dataId = "dataId4567222"; + String group = "group3456789"; + String tenant = "tenant4567890"; + + //mock page list + List tagStrings = Arrays.asList("", "", ""); + when(jdbcTemplate.queryForList(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(String.class))).thenReturn(tagStrings); + List configTags = externalConfigInfoPersistService.selectTagByConfig(dataId, group, tenant); + Assert.assertEquals(tagStrings, configTags); + + //mock EmptyResultDataAccessException + when(jdbcTemplate.queryForList(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(String.class))).thenThrow(new EmptyResultDataAccessException(3)); + List nullResult = externalConfigInfoPersistService.selectTagByConfig(dataId, group, tenant); + Assert.assertTrue(nullResult == null); + //mock IncorrectResultSizeDataAccessException + when(jdbcTemplate.queryForList(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(String.class))).thenThrow(new IncorrectResultSizeDataAccessException(3)); + List nullResult2 = externalConfigInfoPersistService.selectTagByConfig(dataId, group, tenant); + Assert.assertTrue(nullResult2 == null); + + //mock IncorrectResultSizeDataAccessException + when(jdbcTemplate.queryForList(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(String.class))).thenThrow(new CannotGetJdbcConnectionException("mock exp")); + try { + externalConfigInfoPersistService.selectTagByConfig(dataId, group, tenant); + Assert.assertFalse(true); + } catch (Exception e) { + Assert.assertTrue(e instanceof CannotGetJdbcConnectionException); + } + } + + @Test + public void testFindConfigInfosByIds() { + + //mock page list + List result = new ArrayList<>(); + result.add(createMockConfigInfo(0)); + result.add(createMockConfigInfo(1)); + result.add(createMockConfigInfo(2)); + when(jdbcTemplate.query(anyString(), eq(new Object[] {123L, 1232345L}), eq(CONFIG_INFO_ROW_MAPPER))).thenReturn( + result); + String ids = "123,1232345"; + List configInfosByIds = externalConfigInfoPersistService.findConfigInfosByIds(ids); + Assert.assertEquals(result.size(), configInfosByIds.size()); + Assert.assertEquals(result.get(2).getDataId(), configInfosByIds.get(2).getDataId()); + + //mock EmptyResultDataAccessException + when(jdbcTemplate.query(anyString(), eq(new Object[] {123L, 1232345L}), eq(CONFIG_INFO_ROW_MAPPER))).thenThrow( + new EmptyResultDataAccessException(3)); + List nullResult2 = externalConfigInfoPersistService.findConfigInfosByIds(ids); + Assert.assertTrue(nullResult2 == null); + + //blank ids. + List nullResultBlankIds = externalConfigInfoPersistService.findConfigInfosByIds(""); + Assert.assertTrue(nullResultBlankIds == null); + + //mock CannotGetJdbcConnectionException + when(jdbcTemplate.query(anyString(), eq(new Object[] {123L, 1232345L}), eq(CONFIG_INFO_ROW_MAPPER))).thenThrow( + new CannotGetJdbcConnectionException("mock exp")); + try { + externalConfigInfoPersistService.findConfigInfosByIds(ids); + Assert.assertFalse(true); + } catch (Exception e) { + Assert.assertTrue(e instanceof CannotGetJdbcConnectionException); + } + } + + @Test + public void testFindConfigAdvanceInfo() { + + String dataId = "dataId1324"; + String group = "group23546"; + String tenant = "tenant13245"; + //mock select tags + List mockTags = Arrays.asList("tag1", "tag2", "tag3"); + when(jdbcTemplate.queryForList(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(String.class))).thenReturn(mockTags); + + String schema = "schema12345654"; + //mock select config advance + ConfigAdvanceInfo mockedAdvance = new ConfigAdvanceInfo(); + mockedAdvance.setSchema(schema); + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_ADVANCE_INFO_ROW_MAPPER))).thenReturn(mockedAdvance); + + //execute return mock obj + ConfigAdvanceInfo configAdvanceInfo = externalConfigInfoPersistService.findConfigAdvanceInfo(dataId, group, + tenant); + //expect check schema & tags. + Assert.assertEquals(mockedAdvance.getSchema(), configAdvanceInfo.getSchema()); + Assert.assertEquals(String.join(",", mockTags), configAdvanceInfo.getConfigTags()); + + //mock EmptyResultDataAccessException + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_ADVANCE_INFO_ROW_MAPPER))).thenThrow(new EmptyResultDataAccessException(1)); + //expect return null. + Assert.assertNull(externalConfigInfoPersistService.findConfigAdvanceInfo(dataId, group, tenant)); + + //mock CannotGetJdbcConnectionException + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_ADVANCE_INFO_ROW_MAPPER))).thenThrow(new CannotGetJdbcConnectionException("mock exp")); + //expect throw exception. + try { + externalConfigInfoPersistService.findConfigAdvanceInfo(dataId, group, tenant); + Assert.assertFalse(true); + } catch (Exception e) { + Assert.assertTrue(e instanceof CannotGetJdbcConnectionException); + Assert.assertTrue(e.getMessage().endsWith("mock exp")); + } + } + + @Test + public void testFindConfigAllInfo() { + + String dataId = "dataId1324"; + String group = "group23546"; + String tenant = "tenant13245"; + //mock select tags + List mockTags = Arrays.asList("tag1", "tag2", "tag3"); + when(jdbcTemplate.queryForList(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(String.class))).thenReturn(mockTags); + + String schema = "schema12345654"; + //mock select config advance + ConfigAllInfo mockedConfig = new ConfigAllInfo(); + mockedConfig.setSchema(schema); + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_ALL_INFO_ROW_MAPPER))).thenReturn(mockedConfig); + + //execute return mock obj + ConfigAllInfo configAllInfo = externalConfigInfoPersistService.findConfigAllInfo(dataId, group, tenant); + //expect check schema & tags. + Assert.assertEquals(mockedConfig.getSchema(), configAllInfo.getSchema()); + Assert.assertEquals(String.join(",", mockTags), configAllInfo.getConfigTags()); + + //mock EmptyResultDataAccessException + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_ALL_INFO_ROW_MAPPER))).thenThrow(new EmptyResultDataAccessException(1)); + //expect return null. + Assert.assertNull(externalConfigInfoPersistService.findConfigAllInfo(dataId, group, tenant)); + + //mock CannotGetJdbcConnectionException + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_ALL_INFO_ROW_MAPPER))).thenThrow(new CannotGetJdbcConnectionException("mock exp")); + //expect throw exception. + try { + externalConfigInfoPersistService.findConfigAllInfo(dataId, group, tenant); + Assert.assertFalse(true); + } catch (Exception e) { + Assert.assertTrue(e instanceof CannotGetJdbcConnectionException); + Assert.assertTrue(e.getMessage().endsWith("mock exp")); + } + } + + @Test + public void testFindConfigInfoState() { + + String dataId = "dataId1324"; + String group = "group23546"; + String tenant = "tenant13245"; + + //mock select config state + ConfigInfoStateWrapper mockedConfig = new ConfigInfoStateWrapper(); + mockedConfig.setLastModified(2345678L); + mockedConfig.setId(23456789098765L); + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(mockedConfig); + + //execute return mock obj + ConfigInfoStateWrapper configInfoStateWrapper = externalConfigInfoPersistService.findConfigInfoState(dataId, + group, tenant); + //expect check schema & tags. + Assert.assertEquals(mockedConfig.getId(), configInfoStateWrapper.getId()); + Assert.assertEquals(mockedConfig.getLastModified(), configInfoStateWrapper.getLastModified()); + + //mock EmptyResultDataAccessException + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenThrow(new EmptyResultDataAccessException(1)); + //expect return null. + Assert.assertNull(externalConfigInfoPersistService.findConfigInfoState(dataId, group, tenant)); + + //mock CannotGetJdbcConnectionException + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenThrow(new CannotGetJdbcConnectionException("mock exp")); + //expect throw exception. + try { + externalConfigInfoPersistService.findConfigInfoState(dataId, group, tenant); + Assert.assertFalse(true); + } catch (Exception e) { + Assert.assertTrue(e instanceof CannotGetJdbcConnectionException); + Assert.assertTrue(e.getMessage().endsWith("mock exp")); + } + } + + @Test + public void testFindAllConfigInfo4Export() { + + //mock select config state + List mockConfigs = new ArrayList<>(); + mockConfigs.add(createMockConfigAllInfo(0)); + mockConfigs.add(createMockConfigAllInfo(1)); + mockConfigs.add(createMockConfigAllInfo(2)); + + String dataId = "dataId1324"; + String group = "group23546"; + String tenant = "tenant13245"; + String appName = "appName1243"; + List ids = Arrays.asList(132L, 1343L, 245L); + + when(jdbcTemplate.query(anyString(), eq(new Object[] {132L, 1343L, 245L}), + eq(CONFIG_ALL_INFO_ROW_MAPPER))).thenReturn(mockConfigs); + //execute return mock obj + List configAllInfosIds = externalConfigInfoPersistService.findAllConfigInfo4Export(dataId, group, + tenant, appName, ids); + //expect check + Assert.assertEquals(mockConfigs, configAllInfosIds); + + when(jdbcTemplate.query(anyString(), eq(new Object[] {tenant, dataId, group, appName}), + eq(CONFIG_ALL_INFO_ROW_MAPPER))).thenReturn(mockConfigs); + //execute return mock obj + List configAllInfosWithDataId = externalConfigInfoPersistService.findAllConfigInfo4Export(dataId, + group, tenant, appName, null); + //expect check + Assert.assertEquals(mockConfigs, configAllInfosWithDataId); + + //mock CannotGetJdbcConnectionException + when(jdbcTemplate.query(anyString(), eq(new Object[] {132L, 1343L, 245L}), + eq(CONFIG_ALL_INFO_ROW_MAPPER))).thenThrow(new CannotGetJdbcConnectionException("mock exp11")); + //expect throw exception. + try { + externalConfigInfoPersistService.findAllConfigInfo4Export(dataId, group, tenant, appName, ids); + Assert.assertFalse(true); + } catch (Exception e) { + Assert.assertTrue(e instanceof CannotGetJdbcConnectionException); + Assert.assertTrue(e.getMessage().endsWith("mock exp11")); + } + } + + @Test + public void testQueryConfigInfoByNamespace() { + + //mock select config state + List mockConfigs = new ArrayList<>(); + mockConfigs.add(createMockConfigInfoWrapper(0)); + mockConfigs.add(createMockConfigInfoWrapper(1)); + mockConfigs.add(createMockConfigInfoWrapper(2)); + String tenant = "tenant13245"; + when(jdbcTemplate.query(anyString(), eq(new Object[] {tenant}), eq(CONFIG_INFO_WRAPPER_ROW_MAPPER))).thenReturn( + mockConfigs); + //execute return mock obj + List configInfoWrappers = externalConfigInfoPersistService.queryConfigInfoByNamespace( + tenant); + //expect check + Assert.assertEquals(mockConfigs, configInfoWrappers); + + //mock CannotGetJdbcConnectionException + when(jdbcTemplate.query(anyString(), eq(new Object[] {tenant}), eq(CONFIG_INFO_WRAPPER_ROW_MAPPER))).thenThrow( + new EmptyResultDataAccessException(2)); + //execute return mock obj + List configInfoWrapperNull = externalConfigInfoPersistService.queryConfigInfoByNamespace( + tenant); + //expect check + Assert.assertEquals(Collections.EMPTY_LIST, configInfoWrapperNull); + + //mock CannotGetJdbcConnectionException + when(jdbcTemplate.query(anyString(), eq(new Object[] {tenant}), eq(CONFIG_INFO_WRAPPER_ROW_MAPPER))).thenThrow( + new CannotGetJdbcConnectionException("mock exp1111")); + //expect throw exception. + try { + externalConfigInfoPersistService.queryConfigInfoByNamespace(tenant); + Assert.assertFalse(true); + } catch (Exception e) { + Assert.assertTrue(e instanceof CannotGetJdbcConnectionException); + Assert.assertTrue(e.getMessage().endsWith("mock exp1111")); + } + } + + @Test + public void testGetTenantIdList() { + + int page = 10; + int pageSize = 100; + //mock select config state + List tenantStrings = Arrays.asList("tenant1", "tenant2", "tenant3"); + when(jdbcTemplate.queryForList(anyString(), eq(new Object[] {}), eq(String.class))).thenReturn(tenantStrings); + //execute return mock obj + List returnTenants = externalConfigInfoPersistService.getTenantIdList(page, pageSize); + + //expect check + Assert.assertEquals(tenantStrings, returnTenants); + } + + @Test + public void testGetGroupIdList() { + + int page = 10; + int pageSize = 100; + //mock select config state + List groupStrings = Arrays.asList("group1", "group2", "group3"); + when(jdbcTemplate.queryForList(anyString(), eq(new Object[] {}), eq(String.class))).thenReturn(groupStrings); + //execute return mock obj + List returnGroups = externalConfigInfoPersistService.getGroupIdList(page, pageSize); + + //expect check + Assert.assertEquals(groupStrings, returnGroups); + } + + @Test + public void testFindAllConfigInfoFragment() { + //mock page list + List mockConfigs = new ArrayList<>(); + mockConfigs.add(createMockConfigInfoWrapper(0)); + mockConfigs.add(createMockConfigInfoWrapper(1)); + mockConfigs.add(createMockConfigInfoWrapper(2)); + long lastId = 10111L; + when(jdbcTemplate.query(anyString(), eq(new Object[] {lastId}), eq(CONFIG_INFO_WRAPPER_ROW_MAPPER))).thenReturn( + mockConfigs); + int pageSize = 100; + //execute return mock obj + Page returnConfigPage = externalConfigInfoPersistService.findAllConfigInfoFragment(lastId, + pageSize); + + //expect check + Assert.assertEquals(mockConfigs, returnConfigPage.getPageItems()); + + when(jdbcTemplate.query(anyString(), eq(new Object[] {lastId}), eq(CONFIG_INFO_WRAPPER_ROW_MAPPER))).thenThrow( + new CannotGetJdbcConnectionException("mock fail")); + try { + externalConfigInfoPersistService.findAllConfigInfoFragment(lastId, pageSize); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertEquals("mock fail", e.getMessage()); + } + + } + +} diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoTagPersistServiceImplTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoTagPersistServiceImplTest.java new file mode 100644 index 00000000000..9dd2771f092 --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoTagPersistServiceImplTest.java @@ -0,0 +1,420 @@ +/* + * 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.config.server.service.repository.extrnal; + +import com.alibaba.nacos.common.utils.MD5Utils; +import com.alibaba.nacos.config.server.constant.Constants; +import com.alibaba.nacos.config.server.model.ConfigInfo; +import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; +import com.alibaba.nacos.config.server.model.ConfigInfoTagWrapper; +import com.alibaba.nacos.config.server.model.ConfigOperateResult; +import com.alibaba.nacos.config.server.service.sql.ExternalStorageUtils; +import com.alibaba.nacos.config.server.utils.TestCaseUtils; +import com.alibaba.nacos.persistence.datasource.DataSourceService; +import com.alibaba.nacos.persistence.datasource.DynamicDataSource; +import com.alibaba.nacos.persistence.model.Page; +import com.alibaba.nacos.sys.env.EnvUtil; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.CannotGetJdbcConnectionException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.support.TransactionTemplate; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER; +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_TAG_WRAPPER_ROW_MAPPER; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; + +@RunWith(SpringJUnit4ClassRunner.class) +public class ExternalConfigInfoTagPersistServiceImplTest { + + private ExternalConfigInfoTagPersistServiceImpl externalConfigInfoTagPersistService; + + @Mock + private DataSourceService dataSourceService; + + @Mock + private JdbcTemplate jdbcTemplate; + + private TransactionTemplate transactionTemplate = TestCaseUtils.createMockTransactionTemplate(); + + MockedStatic envUtilMockedStatic; + + MockedStatic externalStorageUtilsMockedStatic; + + MockedStatic dynamicDataSourceMockedStatic; + + @Mock + DynamicDataSource dynamicDataSource; + + @Before + public void before() { + dynamicDataSourceMockedStatic = Mockito.mockStatic(DynamicDataSource.class); + envUtilMockedStatic = Mockito.mockStatic(EnvUtil.class); + externalStorageUtilsMockedStatic = Mockito.mockStatic(ExternalStorageUtils.class); + when(DynamicDataSource.getInstance()).thenReturn(dynamicDataSource); + when(dynamicDataSource.getDataSource()).thenReturn(dataSourceService); + when(dataSourceService.getTransactionTemplate()).thenReturn(transactionTemplate); + when(dataSourceService.getJdbcTemplate()).thenReturn(jdbcTemplate); + when(dataSourceService.getDataSourceType()).thenReturn("mysql"); + envUtilMockedStatic.when(() -> EnvUtil.getProperty(anyString(), eq(Boolean.class), eq(false))) + .thenReturn(false); + externalConfigInfoTagPersistService = new ExternalConfigInfoTagPersistServiceImpl(); + } + + @After + public void after() { + dynamicDataSourceMockedStatic.close(); + envUtilMockedStatic.close(); + externalStorageUtilsMockedStatic.close(); + } + + @Test + public void testInsertOrUpdateTagOfAdd() { + String dataId = "dataId111222"; + String group = "group"; + String tenant = "tenant"; + String appName = "appname1234"; + String content = "c12345"; + + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key23456"); + //mock query config state empty and return obj after insert + ConfigInfoStateWrapper configInfoStateWrapper = new ConfigInfoStateWrapper(); + configInfoStateWrapper.setLastModified(System.currentTimeMillis()); + configInfoStateWrapper.setId(234567890L); + String tag = "tag123"; + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, tag}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenThrow(new EmptyResultDataAccessException(1)) + .thenReturn(configInfoStateWrapper); + String srcIp = "ip345678"; + String srcUser = "user1234567"; + ConfigOperateResult configOperateResult = externalConfigInfoTagPersistService.insertOrUpdateTag(configInfo, tag, + srcIp, srcUser); + //verify insert to be invoked + Mockito.verify(jdbcTemplate, times(1)) + .update(anyString(), eq(dataId), eq(group), eq(tenant), eq(tag), eq(appName), + eq(configInfo.getContent()), eq(configInfo.getMd5()), eq(srcIp), eq(srcUser), + any(Timestamp.class), any(Timestamp.class)); + Assert.assertEquals(configInfoStateWrapper.getId(), configOperateResult.getId()); + Assert.assertEquals(configInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + + } + + @Test + public void testInsertOrUpdateTagOfUpdate() { + String dataId = "dataId111222"; + String group = "group"; + String tenant = "tenant"; + String appName = "appname1234"; + String content = "c12345"; + + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key23456"); + //mock query config state and return obj after update + ConfigInfoStateWrapper configInfoStateWrapper = new ConfigInfoStateWrapper(); + configInfoStateWrapper.setLastModified(System.currentTimeMillis()); + configInfoStateWrapper.setId(234567890L); + String tag = "tag123"; + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, tag}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(new ConfigInfoStateWrapper()) + .thenReturn(configInfoStateWrapper); + String srcIp = "ip345678"; + String srcUser = "user1234567"; + ConfigOperateResult configOperateResult = externalConfigInfoTagPersistService.insertOrUpdateTag(configInfo, tag, + srcIp, srcUser); + //verify update to be invoked + Mockito.verify(jdbcTemplate, times(1)) + .update(anyString(), eq(configInfo.getContent()), eq(configInfo.getMd5()), eq(srcIp), eq(srcUser), + any(Timestamp.class), eq(appName), eq(dataId), eq(group), eq(tenant), eq(tag)); + Assert.assertEquals(configInfoStateWrapper.getId(), configOperateResult.getId()); + Assert.assertEquals(configInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + + } + + @Test + public void testInsertOrUpdateTagCasOfAdd() { + String dataId = "dataId111222"; + String group = "group"; + String tenant = "tenant"; + String appName = "appname1234"; + String content = "c12345"; + + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key23456"); + configInfo.setMd5("casMd5"); + //mock query config state empty and return obj after insert + ConfigInfoStateWrapper configInfoStateWrapper = new ConfigInfoStateWrapper(); + configInfoStateWrapper.setLastModified(System.currentTimeMillis()); + configInfoStateWrapper.setId(234567890L); + String tag = "tag123"; + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, tag}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenThrow(new EmptyResultDataAccessException(1)) + .thenReturn(configInfoStateWrapper); + String srcIp = "ip345678"; + String srcUser = "user1234567"; + ConfigOperateResult configOperateResult = externalConfigInfoTagPersistService.insertOrUpdateTagCas(configInfo, + tag, srcIp, srcUser); + //verify insert to be invoked + Mockito.verify(jdbcTemplate, times(1)) + .update(anyString(), eq(dataId), eq(group), eq(tenant), eq(tag), eq(appName), + eq(configInfo.getContent()), + eq(MD5Utils.md5Hex(configInfo.getContent(), Constants.PERSIST_ENCODE)), eq(srcIp), eq(srcUser), + any(Timestamp.class), any(Timestamp.class)); + Assert.assertEquals(configInfoStateWrapper.getId(), configOperateResult.getId()); + Assert.assertEquals(configInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + + } + + @Test + public void testInsertOrUpdateTagCasOfUpdate() { + String dataId = "dataId111222"; + String group = "group"; + String tenant = "tenant"; + String appName = "appname1234"; + String content = "c12345"; + + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key23456"); + configInfo.setMd5("casMd5"); + //mock query config state and return obj after update + ConfigInfoStateWrapper configInfoStateWrapper = new ConfigInfoStateWrapper(); + configInfoStateWrapper.setLastModified(System.currentTimeMillis()); + configInfoStateWrapper.setId(234567890L); + String tag = "tag123"; + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, tag}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(new ConfigInfoStateWrapper()) + .thenReturn(configInfoStateWrapper); + String srcIp = "ip345678"; + String srcUser = "user1234567"; + + //mock cas update return 1 + Mockito.when(jdbcTemplate.update(anyString(), eq(configInfo.getContent()), + eq(MD5Utils.md5Hex(configInfo.getContent(), Constants.PERSIST_ENCODE)), eq(srcIp), eq(srcUser), + any(Timestamp.class), eq(appName), eq(dataId), eq(group), eq(tenant), eq(tag), eq(configInfo.getMd5()))) + .thenReturn(1); + ConfigOperateResult configOperateResult = externalConfigInfoTagPersistService.insertOrUpdateTagCas(configInfo, + tag, srcIp, srcUser); + //verify update to be invoked + Mockito.verify(jdbcTemplate, times(1)).update(anyString(), eq(configInfo.getContent()), + eq(MD5Utils.md5Hex(configInfo.getContent(), Constants.PERSIST_ENCODE)), eq(srcIp), eq(srcUser), + any(Timestamp.class), eq(appName), eq(dataId), eq(group), eq(tenant), eq(tag), eq(configInfo.getMd5())); + Assert.assertEquals(configInfoStateWrapper.getId(), configOperateResult.getId()); + Assert.assertEquals(configInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + } + + @Test + public void testInsertOrUpdateTagCasOfException() { + String dataId = "dataId111222"; + String group = "group"; + String tenant = "tenant"; + String appName = "appname1234"; + String content = "c12345"; + + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key23456"); + configInfo.setMd5("casMd5"); + //mock query config state CannotGetJdbcConnectionException + ConfigInfoStateWrapper configInfoStateWrapper = new ConfigInfoStateWrapper(); + configInfoStateWrapper.setLastModified(System.currentTimeMillis()); + configInfoStateWrapper.setId(234567890L); + String tag = "tag123"; + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, tag}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))) + .thenThrow(new CannotGetJdbcConnectionException("state query throw exception")); + String srcIp = "ip345678"; + String srcUser = "user1234567"; + try { + externalConfigInfoTagPersistService.insertOrUpdateTagCas(configInfo, tag, srcIp, srcUser); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertEquals("state query throw exception", e.getMessage()); + } + //mock get state return null,and execute add throw CannotGetJdbcConnectionException + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, tag}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(null); + Mockito.when(jdbcTemplate.update(anyString(), eq(dataId), eq(group), eq(tenant), eq(tag), eq(appName), + eq(configInfo.getContent()), eq(MD5Utils.md5Hex(configInfo.getContent(), Constants.PERSIST_ENCODE)), + eq(srcIp), eq(srcUser), any(Timestamp.class), any(Timestamp.class))) + .thenThrow(new CannotGetJdbcConnectionException("throw exception add config tag")); + try { + externalConfigInfoTagPersistService.insertOrUpdateTagCas(configInfo, tag, srcIp, srcUser); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertEquals("throw exception add config tag", e.getMessage()); + } + + //mock get state return obj,and execute update throw CannotGetJdbcConnectionException + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, tag}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(configInfoStateWrapper); + Mockito.when(jdbcTemplate.update(anyString(), eq(configInfo.getContent()), + eq(MD5Utils.md5Hex(configInfo.getContent(), Constants.PERSIST_ENCODE)), eq(srcIp), eq(srcUser), + any(Timestamp.class), eq(appName), eq(dataId), eq(group), eq(tenant), eq(tag), eq(configInfo.getMd5()))) + .thenThrow(new CannotGetJdbcConnectionException("throw exception update config tag")); + try { + externalConfigInfoTagPersistService.insertOrUpdateTagCas(configInfo, tag, srcIp, srcUser); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertEquals("throw exception update config tag", e.getMessage()); + } + } + + @Test + public void testRemoveConfigInfoTag() { + String dataId = "dataId1112222"; + String group = "group22"; + String tenant = "tenant2"; + String tag = "tag123345"; + String srcIp = "ip345678"; + String srcUser = "user1234567"; + //Mockito.when(jdbcTemplate.update(anyString(),eq(dataId),eq(group),eq(tenant),eq(tag))).thenReturn() + //verify delete sql invoked. + externalConfigInfoTagPersistService.removeConfigInfoTag(dataId, group, tenant, tag, srcIp, srcUser); + Mockito.verify(jdbcTemplate, times(1)).update(anyString(), eq(dataId), eq(group), eq(tenant), eq(tag)); + + //mock delete throw CannotGetJdbcConnectionException + Mockito.when(jdbcTemplate.update(anyString(), eq(dataId), eq(group), eq(tenant), eq(tag))) + .thenThrow(new CannotGetJdbcConnectionException("delete fail")); + try { + externalConfigInfoTagPersistService.removeConfigInfoTag(dataId, group, tenant, tag, srcIp, srcUser); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertEquals("delete fail", e.getMessage()); + } + } + + @Test + public void testFindConfigInfo4Tag() { + String dataId = "dataId1112222"; + String group = "group22"; + String tenant = "tenant2"; + String tag = "tag123345"; + + //mock query tag return obj + ConfigInfoTagWrapper configInfoTagWrapperMocked = new ConfigInfoTagWrapper(); + configInfoTagWrapperMocked.setLastModified(System.currentTimeMillis()); + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, tag}), + eq(CONFIG_INFO_TAG_WRAPPER_ROW_MAPPER))).thenReturn(configInfoTagWrapperMocked); + + ConfigInfoTagWrapper configInfo4TagReturn = externalConfigInfoTagPersistService.findConfigInfo4Tag(dataId, + group, tenant, tag); + Assert.assertEquals(configInfoTagWrapperMocked, configInfo4TagReturn); + //mock query tag throw EmptyResultDataAccessException + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, tag}), + eq(CONFIG_INFO_TAG_WRAPPER_ROW_MAPPER))).thenThrow(new EmptyResultDataAccessException(1)); + ConfigInfoTagWrapper configInfo4Tag = externalConfigInfoTagPersistService.findConfigInfo4Tag(dataId, group, + tenant, tag); + Assert.assertNull(configInfo4Tag); + + //mock query tag throw CannotGetJdbcConnectionException + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, tag}), + eq(CONFIG_INFO_TAG_WRAPPER_ROW_MAPPER))).thenThrow(new CannotGetJdbcConnectionException("con error")); + try { + externalConfigInfoTagPersistService.findConfigInfo4Tag(dataId, group, tenant, tag); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertEquals("con error", e.getMessage()); + } + } + + @Test + public void testConfigInfoTagCount() { + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + + //mock count + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(Integer.class))).thenReturn(308); + //execute & verify + int count = externalConfigInfoTagPersistService.configInfoTagCount(); + Assert.assertEquals(308, count); + + //mock count is null + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(Integer.class))).thenReturn(null); + //execute & verify + try { + externalConfigInfoTagPersistService.configInfoTagCount(); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertEquals("configInfoTagCount error", e.getMessage()); + } + } + + @Test + public void testFindAllConfigInfoTagForDumpAll() { + + //mock count + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(Integer.class))).thenReturn(308); + List mockTagList = new ArrayList<>(); + mockTagList.add(new ConfigInfoTagWrapper()); + mockTagList.add(new ConfigInfoTagWrapper()); + mockTagList.add(new ConfigInfoTagWrapper()); + mockTagList.get(0).setLastModified(System.currentTimeMillis()); + mockTagList.get(1).setLastModified(System.currentTimeMillis()); + mockTagList.get(2).setLastModified(System.currentTimeMillis()); + //mock query list + Mockito.when(jdbcTemplate.query(anyString(), eq(new Object[] {}), eq(CONFIG_INFO_TAG_WRAPPER_ROW_MAPPER))) + .thenReturn(mockTagList); + int pageNo = 3; + int pageSize = 100; + //execute & verify + Page returnTagPage = externalConfigInfoTagPersistService.findAllConfigInfoTagForDumpAll( + pageNo, pageSize); + Assert.assertEquals(308, returnTagPage.getTotalCount()); + Assert.assertEquals(mockTagList, returnTagPage.getPageItems()); + + //mock count CannotGetJdbcConnectionException + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(Integer.class))) + .thenThrow(new CannotGetJdbcConnectionException("conn error111")); + //execute & verify + try { + externalConfigInfoTagPersistService.findAllConfigInfoTagForDumpAll(pageNo, pageSize); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertEquals("conn error111", e.getMessage()); + } + } + + @Test + public void testFindConfigInfoTags() { + String dataId = "dataId1112222"; + String group = "group22"; + String tenant = "tenant2"; + List mockedTags = Arrays.asList("tags1", "tags11", "tags111"); + Mockito.when(jdbcTemplate.queryForList(anyString(), eq(new Object[] {dataId, group, tenant}), eq(String.class))) + .thenReturn(mockedTags); + + List configInfoTags = externalConfigInfoTagPersistService.findConfigInfoTags(dataId, group, tenant); + Assert.assertEquals(mockedTags, configInfoTags); + + } + +} diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalHistoryConfigInfoPersistServiceImplTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalHistoryConfigInfoPersistServiceImplTest.java new file mode 100644 index 00000000000..1560aa22773 --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalHistoryConfigInfoPersistServiceImplTest.java @@ -0,0 +1,333 @@ +/* + * 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.config.server.service.repository.extrnal; + +import com.alibaba.nacos.config.server.model.ConfigHistoryInfo; +import com.alibaba.nacos.config.server.model.ConfigInfo; +import com.alibaba.nacos.config.server.model.ConfigInfoWrapper; +import com.alibaba.nacos.config.server.service.sql.ExternalStorageUtils; +import com.alibaba.nacos.config.server.utils.TestCaseUtils; +import com.alibaba.nacos.persistence.datasource.DataSourceService; +import com.alibaba.nacos.persistence.datasource.DynamicDataSource; +import com.alibaba.nacos.persistence.model.Page; +import com.alibaba.nacos.sys.env.EnvUtil; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.CannotGetJdbcConnectionException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.support.TransactionTemplate; + +import java.math.BigInteger; +import java.sql.Timestamp; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneOffset; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.HISTORY_DETAIL_ROW_MAPPER; +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.HISTORY_LIST_ROW_MAPPER; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; + +@RunWith(SpringJUnit4ClassRunner.class) +public class ExternalHistoryConfigInfoPersistServiceImplTest { + + private ExternalHistoryConfigInfoPersistServiceImpl externalHistoryConfigInfoPersistService; + + @Mock + private DataSourceService dataSourceService; + + @Mock + private JdbcTemplate jdbcTemplate; + + private TransactionTemplate transactionTemplate = TestCaseUtils.createMockTransactionTemplate(); + + MockedStatic envUtilMockedStatic; + + MockedStatic externalStorageUtilsMockedStatic; + + MockedStatic dynamicDataSourceMockedStatic; + + @Mock + DynamicDataSource dynamicDataSource; + + @Before + public void before() { + dynamicDataSourceMockedStatic = Mockito.mockStatic(DynamicDataSource.class); + envUtilMockedStatic = Mockito.mockStatic(EnvUtil.class); + externalStorageUtilsMockedStatic = Mockito.mockStatic(ExternalStorageUtils.class); + when(DynamicDataSource.getInstance()).thenReturn(dynamicDataSource); + when(dynamicDataSource.getDataSource()).thenReturn(dataSourceService); + when(dataSourceService.getTransactionTemplate()).thenReturn(transactionTemplate); + when(dataSourceService.getJdbcTemplate()).thenReturn(jdbcTemplate); + when(dataSourceService.getDataSourceType()).thenReturn("mysql"); + envUtilMockedStatic.when(() -> EnvUtil.getProperty(anyString(), eq(Boolean.class), eq(false))) + .thenReturn(false); + externalHistoryConfigInfoPersistService = new ExternalHistoryConfigInfoPersistServiceImpl(); + } + + @After + public void after() { + dynamicDataSourceMockedStatic.close(); + envUtilMockedStatic.close(); + externalStorageUtilsMockedStatic.close(); + } + + @Test + public void testInsertConfigHistoryAtomic() { + String dataId = "dateId243"; + String group = "group243"; + String tenant = "tenant243"; + String content = "content243"; + String appName = "appName243"; + long id = 123456787765432L; + String srcUser = "user12345"; + String srcIp = "ip1234"; + String ops = "D"; + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key23456"); + //expect insert success,verify insert invoked + externalHistoryConfigInfoPersistService.insertConfigHistoryAtomic(id, configInfo, srcIp, srcUser, timestamp, + ops); + Mockito.verify(jdbcTemplate, times(1)) + .update(anyString(), eq(id), eq(dataId), eq(group), eq(tenant), eq(appName), eq(content), + eq(configInfo.getMd5()), eq(srcIp), eq(srcUser), eq(timestamp), eq(ops), + eq(configInfo.getEncryptedDataKey())); + + Mockito.when( + jdbcTemplate.update(anyString(), eq(id), eq(dataId), eq(group), eq(tenant), eq(appName), eq(content), + eq(configInfo.getMd5()), eq(srcIp), eq(srcUser), eq(timestamp), eq(ops), + eq(configInfo.getEncryptedDataKey()))) + .thenThrow(new CannotGetJdbcConnectionException("mock ex...")); + try { + externalHistoryConfigInfoPersistService.insertConfigHistoryAtomic(id, configInfo, srcIp, srcUser, timestamp, + ops); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertEquals("mock ex...", e.getMessage()); + } + } + + @Test + public void testRemoveConfigHistory() { + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + int pageSize = 1233; + externalHistoryConfigInfoPersistService.removeConfigHistory(timestamp, pageSize); + //verify delete by time and size invoked. + Mockito.verify(jdbcTemplate, times(1)).update(anyString(), eq(timestamp), eq(pageSize)); + } + + @Test + public void testFindDeletedConfig() { + + //mock query list return + Map mockObj1 = new HashMap<>(); + mockObj1.put("nid", new BigInteger("1234")); + mockObj1.put("data_id", "data_id1"); + mockObj1.put("group_id", "group_id1"); + mockObj1.put("tenant_id", "tenant_id1"); + LocalDateTime now = LocalDateTime.of(LocalDate.now(), LocalTime.now()); + mockObj1.put("gmt_modified", now); + List> list = new ArrayList<>(); + list.add(mockObj1); + Map mockObj2 = new HashMap<>(); + mockObj2.put("nid", new BigInteger("12345")); + mockObj2.put("data_id", "data_id2"); + mockObj2.put("group_id", "group_id2"); + mockObj2.put("tenant_id", "tenant_id2"); + LocalDateTime now2 = LocalDateTime.of(LocalDate.now(), LocalTime.now()); + mockObj2.put("gmt_modified", now2); + list.add(mockObj2); + int pageSize = 1233; + long startId = 23456; + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + Mockito.when(jdbcTemplate.queryForList(anyString(), eq(timestamp), eq(startId), eq(pageSize))).thenReturn(list); + //execute + List deletedConfig = externalHistoryConfigInfoPersistService.findDeletedConfig(timestamp, + startId, pageSize); + //expect verify + Assert.assertEquals("data_id1", deletedConfig.get(0).getDataId()); + Assert.assertEquals("group_id1", deletedConfig.get(0).getGroup()); + Assert.assertEquals("tenant_id1", deletedConfig.get(0).getTenant()); + Assert.assertEquals(now.toInstant(ZoneOffset.ofHours(8)).toEpochMilli(), + deletedConfig.get(0).getLastModified()); + Assert.assertEquals("data_id2", deletedConfig.get(1).getDataId()); + Assert.assertEquals("group_id2", deletedConfig.get(1).getGroup()); + Assert.assertEquals("tenant_id2", deletedConfig.get(1).getTenant()); + Assert.assertEquals(now2.toInstant(ZoneOffset.ofHours(8)).toEpochMilli(), + deletedConfig.get(1).getLastModified()); + + //mock exception + Mockito.when(jdbcTemplate.queryForList(anyString(), eq(timestamp), eq(startId), eq(pageSize))) + .thenThrow(new CannotGetJdbcConnectionException("conn error")); + + try { + externalHistoryConfigInfoPersistService.findDeletedConfig(timestamp, startId, pageSize); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertEquals("conn error", e.getMessage()); + } + + } + + @Test + public void testFindConfigHistory() { + String dataId = "dataId34567"; + String group = "group34567"; + String tenant = "tenant34567"; + + //mock count + Mockito.when( + jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), eq(Integer.class))) + .thenReturn(300); + //mock list + List mockList = new ArrayList<>(); + mockList.add(createMockConfigHistoryInfo(0)); + mockList.add(createMockConfigHistoryInfo(1)); + mockList.add(createMockConfigHistoryInfo(2)); + Mockito.when( + jdbcTemplate.query(anyString(), eq(new Object[] {dataId, group, tenant}), eq(HISTORY_LIST_ROW_MAPPER))) + .thenReturn(mockList); + int pageSize = 100; + int pageNo = 2; + //execute & verify + Page historyReturn = externalHistoryConfigInfoPersistService.findConfigHistory(dataId, group, + tenant, pageNo, pageSize); + Assert.assertEquals(mockList, historyReturn.getPageItems()); + Assert.assertEquals(300, historyReturn.getTotalCount()); + + //mock exception + Mockito.when( + jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), eq(Integer.class))) + .thenThrow(new CannotGetJdbcConnectionException("conn error111")); + try { + externalHistoryConfigInfoPersistService.findConfigHistory(dataId, group, tenant, pageNo, pageSize); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertEquals("conn error111", e.getMessage()); + } + } + + @Test + public void testDetailConfigHistory() { + long nid = 256789; + + //mock query + ConfigHistoryInfo mockConfigHistoryInfo = createMockConfigHistoryInfo(0); + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {nid}), eq(HISTORY_DETAIL_ROW_MAPPER))) + .thenReturn(mockConfigHistoryInfo); + //execute & verify + ConfigHistoryInfo historyReturn = externalHistoryConfigInfoPersistService.detailConfigHistory(nid); + Assert.assertEquals(mockConfigHistoryInfo, historyReturn); + + //mock exception EmptyResultDataAccessException + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {nid}), eq(HISTORY_DETAIL_ROW_MAPPER))) + .thenThrow(new EmptyResultDataAccessException(1)); + ConfigHistoryInfo historyReturnNull = externalHistoryConfigInfoPersistService.detailConfigHistory(nid); + Assert.assertNull(historyReturnNull); + + //mock exception CannotGetJdbcConnectionException + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {nid}), eq(HISTORY_DETAIL_ROW_MAPPER))) + .thenThrow(new CannotGetJdbcConnectionException("conn error111")); + try { + externalHistoryConfigInfoPersistService.detailConfigHistory(nid); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertEquals("conn error111", e.getMessage()); + } + } + + @Test + public void testDetailPreviousConfigHistory() { + long nid = 256789; + //mock query + ConfigHistoryInfo mockConfigHistoryInfo = createMockConfigHistoryInfo(0); + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {nid}), eq(HISTORY_DETAIL_ROW_MAPPER))) + .thenReturn(mockConfigHistoryInfo); + //execute & verify + ConfigHistoryInfo historyReturn = externalHistoryConfigInfoPersistService.detailPreviousConfigHistory(nid); + Assert.assertEquals(mockConfigHistoryInfo, historyReturn); + + //mock exception EmptyResultDataAccessException + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {nid}), eq(HISTORY_DETAIL_ROW_MAPPER))) + .thenThrow(new EmptyResultDataAccessException(1)); + ConfigHistoryInfo historyReturnNull = externalHistoryConfigInfoPersistService.detailPreviousConfigHistory(nid); + Assert.assertNull(historyReturnNull); + + //mock exception CannotGetJdbcConnectionException + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {nid}), eq(HISTORY_DETAIL_ROW_MAPPER))) + .thenThrow(new CannotGetJdbcConnectionException("conn error111")); + try { + externalHistoryConfigInfoPersistService.detailPreviousConfigHistory(nid); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertEquals("conn error111", e.getMessage()); + } + } + + @Test + public void testFindConfigHistoryCountByTime() { + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + + //mock count + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {timestamp}), eq(Integer.class))) + .thenReturn(308); + //execute & verify + int count = externalHistoryConfigInfoPersistService.findConfigHistoryCountByTime(timestamp); + Assert.assertEquals(308, count); + + //mock count is null + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {timestamp}), eq(Integer.class))) + .thenReturn(null); + //execute & verify + try { + externalHistoryConfigInfoPersistService.findConfigHistoryCountByTime(timestamp); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertEquals("findConfigHistoryCountByTime error", e.getMessage()); + } + } + + private ConfigHistoryInfo createMockConfigHistoryInfo(long mockId) { + ConfigHistoryInfo configAllInfo = new ConfigHistoryInfo(); + configAllInfo.setDataId("test" + mockId + ".yaml"); + configAllInfo.setGroup("test"); + configAllInfo.setContent("23456789000content"); + configAllInfo.setOpType("D"); + configAllInfo.setEncryptedDataKey("key4567"); + configAllInfo.setSrcIp("ip567"); + configAllInfo.setSrcUser("user1234"); + configAllInfo.setMd5("md52345678"); + return configAllInfo; + } +} + diff --git a/config/src/test/java/com/alibaba/nacos/config/server/utils/DiskUtilsTest.java b/config/src/test/java/com/alibaba/nacos/config/server/utils/DiskUtilsTest.java deleted file mode 100644 index 137214df7ab..00000000000 --- a/config/src/test/java/com/alibaba/nacos/config/server/utils/DiskUtilsTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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.config.server.utils; - -import org.apache.commons.io.FileUtils; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import java.io.File; -import java.io.IOException; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; - -@RunWith(SpringJUnit4ClassRunner.class) -public class DiskUtilsTest { - - static MockedStatic fileUtils; - - @BeforeClass - public static void before() { - fileUtils = Mockito.mockStatic(FileUtils.class); - } - - @AfterClass - public static void after() { - fileUtils.close(); - } - - @Test - public void testSaveHeartBeatToDisk() throws IOException { - String heartBeatTime = System.currentTimeMillis() + ""; - DiskUtil.saveHeartBeatToDisk(heartBeatTime); - fileUtils.verify(() -> FileUtils.writeStringToFile(any(), eq(heartBeatTime), eq(UTF_8.displayName())), Mockito.times(1)); - } - - @Test - public void testRemoveHeartHeat() { - File targetFile = DiskUtil.heartBeatFile(); - DiskUtil.removeHeartHeat(); - fileUtils.verify(() -> FileUtils.deleteQuietly(targetFile), Mockito.times(1)); - } - - @Test - public void testHeartBeatFile() { - File file = DiskUtil.heartBeatFile(); - String[] arr = file.getPath().split("/"); - Assert.assertEquals("heartBeat.txt", arr[arr.length - 1]); - Assert.assertEquals("status", arr[arr.length - 2]); - Assert.assertEquals("nacos", arr[arr.length - 3]); - } -} diff --git a/config/src/test/java/com/alibaba/nacos/config/server/utils/TestCaseUtils.java b/config/src/test/java/com/alibaba/nacos/config/server/utils/TestCaseUtils.java index 869dcacf858..a9c9af03392 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/utils/TestCaseUtils.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/utils/TestCaseUtils.java @@ -17,11 +17,14 @@ package com.alibaba.nacos.config.server.utils; import org.mockito.Mockito; +import org.springframework.jdbc.support.GeneratedKeyHolder; import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.support.DefaultTransactionStatus; import org.springframework.transaction.support.TransactionTemplate; +import java.util.HashMap; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; @@ -29,6 +32,7 @@ public class TestCaseUtils { /** * create mocked transaction template with transact ability. + * * @return */ public static TransactionTemplate createMockTransactionTemplate() { @@ -40,4 +44,18 @@ public static TransactionTemplate createMockTransactionTemplate() { return transactionTemplate; } + + /** + * create mocked transaction template with transact ability. + * + * @return + */ + public static GeneratedKeyHolder createGeneratedKeyHolder(long wantedId) { + GeneratedKeyHolder generatedKeyHolder = new GeneratedKeyHolder(); + HashMap objectObjectHashMap = new HashMap<>(); + objectObjectHashMap.put("whatever", wantedId); + generatedKeyHolder.getKeyList().add(objectObjectHashMap); + + return generatedKeyHolder; + } } diff --git a/plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/mapper/ConfigTagsRelationMapper.java b/plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/mapper/ConfigTagsRelationMapper.java index e3b8f90ec83..0440c5b8025 100644 --- a/plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/mapper/ConfigTagsRelationMapper.java +++ b/plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/mapper/ConfigTagsRelationMapper.java @@ -44,6 +44,7 @@ public interface ConfigTagsRelationMapper extends Mapper { */ default MapperResult findConfigInfo4PageCountRows(final MapperContext context) { final String appName = (String) context.getWhereParameter(FieldConstant.APP_NAME); + final String tenantId = (String) context.getWhereParameter(FieldConstant.TENANT_ID); final String dataId = (String) context.getWhereParameter(FieldConstant.DATA_ID); final String group = (String) context.getWhereParameter(FieldConstant.GROUP_ID); final String content = (String) context.getWhereParameter(FieldConstant.CONTENT); @@ -54,7 +55,7 @@ default MapperResult findConfigInfo4PageCountRows(final MapperContext context) { final String sqlCount = "SELECT count(*) FROM config_info a LEFT JOIN config_tags_relation b ON a.id=b.id"; where.append(" a.tenant_id=? "); - + paramList.add(tenantId); if (StringUtils.isNotBlank(dataId)) { where.append(" AND a.data_id=? "); paramList.add(dataId); @@ -77,6 +78,8 @@ default MapperResult findConfigInfo4PageCountRows(final MapperContext context) { where.append(", "); } where.append('?'); + paramList.add(tagArr[i]); + } where.append(") "); return new MapperResult(sqlCount + where, paramList); diff --git a/plugin/datasource/src/test/java/com/alibaba/nacos/plugin/datasource/impl/mysql/ConfigTagsRelationMapperByMySqlTest.java b/plugin/datasource/src/test/java/com/alibaba/nacos/plugin/datasource/impl/mysql/ConfigTagsRelationMapperByMySqlTest.java index 995eb14f242..78899040a95 100644 --- a/plugin/datasource/src/test/java/com/alibaba/nacos/plugin/datasource/impl/mysql/ConfigTagsRelationMapperByMySqlTest.java +++ b/plugin/datasource/src/test/java/com/alibaba/nacos/plugin/datasource/impl/mysql/ConfigTagsRelationMapperByMySqlTest.java @@ -52,7 +52,7 @@ public void setUp() throws Exception { } @Test - public void testFindConfigInfo4PageCountRows() { + public void testFindConfigInfoLike4PageCountRows() { MapperResult mapperResult = configTagsRelationMapperByMySql.findConfigInfoLike4PageCountRows(context); Assert.assertEquals(mapperResult.getSql(), "SELECT count(*) FROM config_info a LEFT JOIN config_tags_relation b ON a.id=b.id WHERE " @@ -62,37 +62,76 @@ public void testFindConfigInfo4PageCountRows() { Assert.assertArrayEquals(mapperResult.getParamList().toArray(), list.toArray()); } + @Test + public void testFindConfigInfo4PageCountRows() { + MapperResult mapperResult = configTagsRelationMapperByMySql.findConfigInfo4PageCountRows(context); + Assert.assertEquals(mapperResult.getSql(), + "SELECT count(*) FROM config_info a LEFT JOIN config_tags_relation b ON a.id=b.id " + + "WHERE a.tenant_id=? AND b.tag_name IN (?, ?, ?, ?, ?) "); + List list = CollectionUtils.list(tenantId); + list.addAll(Arrays.asList(tagArr)); + Assert.assertArrayEquals(mapperResult.getParamList().toArray(), list.toArray()); + } + @Test public void testFindConfigInfo4PageFetchRows() { + context.putWhereParameter(FieldConstant.DATA_ID, "dataID1"); + context.putWhereParameter(FieldConstant.GROUP_ID, "groupID1"); + context.putWhereParameter(FieldConstant.APP_NAME, "AppName1"); + context.putWhereParameter(FieldConstant.CONTENT, "Content1"); + MapperResult mapperResult = configTagsRelationMapperByMySql.findConfigInfo4PageFetchRows(context); - Assert.assertEquals(mapperResult.getSql(), - "SELECT a.id,a.data_id,a.group_id,a.tenant_id,a.app_name,a.content FROM config_info a LEFT JOIN " - + "config_tags_relation b ON a.id=b.id WHERE a.tenant_id=? AND b.tag_name IN (?, ?, ?, ?, ?) LIMIT " - + startRow + "," + pageSize); + Assert.assertEquals( + "SELECT a.id,a.data_id,a.group_id,a.tenant_id,a.app_name,a.content FROM config_info " + + "a LEFT JOIN config_tags_relation b ON a.id=b.id " + + "WHERE a.tenant_id=? AND a.data_id=? AND a.group_id=? AND a.app_name=? AND a.content LIKE ? " + + " AND b.tag_name IN (?, ?, ?, ?, ?) LIMIT " + + startRow + "," + pageSize, mapperResult.getSql()); List list = CollectionUtils.list(tenantId); + list.add("dataID1"); + list.add("groupID1"); + list.add("AppName1"); + list.add("Content1"); list.addAll(Arrays.asList(tagArr)); Assert.assertArrayEquals(mapperResult.getParamList().toArray(), list.toArray()); } @Test - public void testFindConfigInfoLike4PageCountRows() { + public void testFindConfigInfoLike4PageCountRowss() { + context.putWhereParameter(FieldConstant.DATA_ID, "dataID1"); + context.putWhereParameter(FieldConstant.GROUP_ID, "groupID1"); + context.putWhereParameter(FieldConstant.APP_NAME, "AppName1"); + context.putWhereParameter(FieldConstant.CONTENT, "Content1"); MapperResult mapperResult = configTagsRelationMapperByMySql.findConfigInfoLike4PageCountRows(context); - Assert.assertEquals(mapperResult.getSql(), - "SELECT count(*) FROM config_info a LEFT JOIN config_tags_relation b ON a.id=b.id " - + "WHERE a.tenant_id LIKE ? AND b.tag_name IN (?, ?, ?, ?, ?) "); + Assert.assertEquals("SELECT count(*) FROM config_info a LEFT JOIN config_tags_relation b ON a.id=b.id " + + "WHERE a.tenant_id LIKE ? AND a.data_id LIKE ? AND a.group_id LIKE ? AND a.app_name = ? " + + "AND a.content LIKE ? AND b.tag_name IN (?, ?, ?, ?, ?) ", mapperResult.getSql()); List list = CollectionUtils.list(tenantId); + list.add("dataID1"); + list.add("groupID1"); + list.add("AppName1"); + list.add("Content1"); list.addAll(Arrays.asList(tagArr)); Assert.assertArrayEquals(mapperResult.getParamList().toArray(), list.toArray()); } @Test public void tsetFindConfigInfoLike4PageFetchRows() { + context.putWhereParameter(FieldConstant.DATA_ID, "dataID1"); + context.putWhereParameter(FieldConstant.GROUP_ID, "groupID1"); + context.putWhereParameter(FieldConstant.APP_NAME, "AppName1"); + context.putWhereParameter(FieldConstant.CONTENT, "Content1"); MapperResult mapperResult = configTagsRelationMapperByMySql.findConfigInfoLike4PageFetchRows(context); Assert.assertEquals(mapperResult.getSql(), "SELECT a.id,a.data_id,a.group_id,a.tenant_id,a.app_name,a.content FROM config_info a LEFT JOIN" - + " config_tags_relation b ON a.id=b.id WHERE a.tenant_id LIKE ? AND b.tag_name IN (?, ?, ?, ?, ?) LIMIT " + + " config_tags_relation b ON a.id=b.id WHERE a.tenant_id LIKE ? AND a.data_id LIKE ? " + + "AND a.group_id LIKE ? AND a.app_name = ? AND a.content LIKE ? AND b.tag_name IN (?, ?, ?, ?, ?) LIMIT " + startRow + "," + pageSize); List list = CollectionUtils.list(tenantId); + list.add("dataID1"); + list.add("groupID1"); + list.add("AppName1"); + list.add("Content1"); list.addAll(Arrays.asList(tagArr)); Assert.assertArrayEquals(mapperResult.getParamList().toArray(), list.toArray()); }