diff --git a/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigController.java b/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigController.java index 8f7264d8e..46bf748a9 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigController.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigController.java @@ -18,6 +18,8 @@ package com.alibaba.nacos.config.server.controller; import com.alibaba.nacos.config.server.constant.Constants; import com.alibaba.nacos.config.server.exception.NacosException; import com.alibaba.nacos.config.server.model.*; +import com.alibaba.nacos.config.server.result.ResultBuilder; +import com.alibaba.nacos.config.server.result.code.ResultCodeEnum; import com.alibaba.nacos.config.server.service.AggrWhitelist; import com.alibaba.nacos.config.server.service.ConfigDataChangeEvent; import com.alibaba.nacos.config.server.service.ConfigSubService; @@ -25,6 +27,7 @@ import com.alibaba.nacos.config.server.service.PersistService; import com.alibaba.nacos.config.server.service.trace.ConfigTraceService; import com.alibaba.nacos.config.server.utils.*; import com.alibaba.nacos.config.server.utils.event.EventDispatcher; +import com.google.common.base.Joiner; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateFormatUtils; import org.slf4j.Logger; @@ -63,6 +66,12 @@ public class ConfigController { private static final String NAMESPACE_PUBLIC_KEY = "public"; + public static final String EXPORT_CONFIG_FILE_NAME = "nacos_config_export_"; + + public static final String EXPORT_CONFIG_FILE_NAME_EXT = ".zip"; + + public static final String EXPORT_CONFIG_FILE_NAME_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; + private final transient ConfigServletInner inner; private final transient PersistService persistService; @@ -398,8 +407,9 @@ public class ConfigController { @RequestParam(value = "tenant", required = false, defaultValue = StringUtils.EMPTY) String tenant, @RequestParam(value = "ids", required = false)List ids) { - String idsStr = idList2String(ids); - List dataList = persistService.findAllConfigInfo4eExport(group, tenant, appName, idsStr); + ids.removeAll(Collections.singleton(null)); + String idsStr = Joiner.on(",").join(ids); + List dataList = persistService.findAllConfigInfo4Export(group, tenant, appName, idsStr); List zipItemList = new ArrayList<>(); StringBuilder metaData = null; for(ConfigInfo ci : dataList){ @@ -425,7 +435,7 @@ public class ConfigController { } HttpHeaders headers = new HttpHeaders(); - String fileName="nacos_config_export_" + DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss") + ".zip"; + String fileName=EXPORT_CONFIG_FILE_NAME + DateFormatUtils.format(new Date(), EXPORT_CONFIG_FILE_NAME_DATE_FORMAT) + EXPORT_CONFIG_FILE_NAME_EXT; headers.add("Content-Disposition", "attachment;filename="+fileName); return new ResponseEntity(ZipUtils.zip(zipItemList), headers, HttpStatus.OK); } @@ -438,16 +448,12 @@ public class ConfigController { @RequestParam(value = "policy", defaultValue = "ABORT") SameConfigPolicy policy, MultipartFile file) throws NacosException { - RestResult> rr = new RestResult<>(); Map failedData = new HashMap<>(4); - rr.setData(failedData); if(StringUtils.isNotBlank(namespace)){ if(persistService.tenantInfoCountByTenantId(namespace) <= 0){ - rr.setCode(5001); failedData.put("succCount", 0); - rr.setMessage("namespace does not exist"); - return rr; + return ResultBuilder.buildResult(ResultCodeEnum.NAMESPACE_NOT_EXIST, failedData); } } List configInfoList = null; @@ -461,10 +467,8 @@ public class ConfigController { for(String metaDataItem : metaDataArr){ String[] metaDataItemArr = metaDataItem.split("="); if(metaDataItemArr.length != 2){ - rr.setCode(5002); failedData.put("succCount", 0); - rr.setMessage("The imported metadata file is illegal"); - return rr; + return ResultBuilder.buildResult(ResultCodeEnum.METADATA_ILLEGAL, failedData); } metaDataMap.put(metaDataItemArr[0], metaDataItemArr[1]); } @@ -475,10 +479,8 @@ public class ConfigController { for(ZipUtils.ZipItem item : itemList){ String[] groupAdnDataId = item.getItemName().split("/"); if(!item.getItemName().contains("/") || groupAdnDataId.length != 2){ - rr.setCode(5003); failedData.put("succCount", 0); - rr.setMessage("No legitimate data was read, please check the imported data file"); - return rr; + return ResultBuilder.buildResult(ResultCodeEnum.DATA_VALIDATION_FAILED, failedData); } String group = groupAdnDataId[0]; String dataId = groupAdnDataId[1]; @@ -500,17 +502,13 @@ public class ConfigController { } } } catch (IOException e) { - rr.setCode(5004); failedData.put("succCount", 0); - rr.setMessage("parsing data failed"); log.error("parsing data failed", e); - return rr; + return ResultBuilder.buildResult(ResultCodeEnum.PARSING_DATA_FAILED, failedData); } if (configInfoList == null || configInfoList.isEmpty()) { - rr.setCode(5005); failedData.put("succCount", 0); - rr.setMessage("data is empty"); - return rr; + return ResultBuilder.buildResult(ResultCodeEnum.DATA_EMPTY, failedData); } final String srcIp = RequestUtil.getRemoteIp(request); String requestIpApp = RequestUtil.getAppName(request); @@ -524,10 +522,7 @@ public class ConfigController { configInfo.getTenant(), requestIpApp, time.getTime(), LOCAL_IP, ConfigTraceService.PERSISTENCE_EVENT_PUB, configInfo.getContent()); } - rr.setCode(200); - rr.setData(saveResult); - rr.setMessage("import ok"); - return rr; + return ResultBuilder.buildSuccessResult("导入成功", saveResult); } @RequestMapping(params = "clone=true", method = RequestMethod.GET) @@ -539,27 +534,22 @@ public class ConfigController { @RequestParam(value = "ids", required = true) List ids, @RequestParam(value = "policy", defaultValue = "ABORT") SameConfigPolicy policy) throws NacosException { - RestResult> rr = new RestResult<>(); Map failedData = new HashMap<>(4); - rr.setData(failedData); if(NAMESPACE_PUBLIC_KEY.equals(namespace.toLowerCase())){ namespace = ""; } else if(persistService.tenantInfoCountByTenantId(namespace) <= 0){ - rr.setCode(5001); failedData.put("succCount", 0); - rr.setMessage("namespace does not exist"); - return rr; + return ResultBuilder.buildResult(ResultCodeEnum.NAMESPACE_NOT_EXIST, failedData); } - String idsStr = idList2String(ids); - List queryedDataList = persistService.findAllConfigInfo4eExport(null, null, null, idsStr); + ids.removeAll(Collections.singleton(null)); + String idsStr = Joiner.on(",").join(ids); + List queryedDataList = persistService.findAllConfigInfo4Export(null, null, null, idsStr); if(queryedDataList == null || queryedDataList.isEmpty()){ - rr.setCode(5005); failedData.put("succCount", 0); - rr.setMessage("data is empty"); - return rr; + return ResultBuilder.buildResult(ResultCodeEnum.DATA_EMPTY, failedData); } List configInfoList4Clone = new ArrayList<>(queryedDataList.size()); @@ -577,10 +567,8 @@ public class ConfigController { } if (configInfoList4Clone.isEmpty()) { - rr.setCode(5005); failedData.put("succCount", 0); - rr.setMessage("data is empty"); - return rr; + return ResultBuilder.buildResult(ResultCodeEnum.DATA_EMPTY, failedData); } final String srcIp = RequestUtil.getRemoteIp(request); String requestIpApp = RequestUtil.getAppName(request); @@ -594,23 +582,7 @@ public class ConfigController { configInfo.getTenant(), requestIpApp, time.getTime(), LOCAL_IP, ConfigTraceService.PERSISTENCE_EVENT_PUB, configInfo.getContent()); } - rr.setCode(200); - rr.setData(saveResult); - rr.setMessage("import ok"); - return rr; + return ResultBuilder.buildSuccessResult("导入成功", saveResult); } - private String idList2String(List ids){ - StringBuilder idsSb = new StringBuilder(); - if(ids != null && !ids.isEmpty()){ - for(int i = 0; i < ids.size(); i++){ - Long id = ids.get(i); - idsSb.append(id); - if((i + 1) < ids.size()){ - idsSb.append(","); - } - } - } - return idsSb.toString(); - } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/enums/FileTypeEnum.java b/config/src/main/java/com/alibaba/nacos/config/server/enums/FileTypeEnum.java new file mode 100644 index 000000000..88a9e9ecb --- /dev/null +++ b/config/src/main/java/com/alibaba/nacos/config/server/enums/FileTypeEnum.java @@ -0,0 +1,98 @@ +/* + * 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.enums; + +/** + * @author klw + * @ClassName: FileTypeEnum + * @Description: config file type enum + * @date 2019/7/1 10:21 + */ +public enum FileTypeEnum { + + /** + * @author klw + * @Description: yaml file + */ + YML("yaml"), + + /** + * @author klw + * @Description: yaml file + */ + YAML("yaml"), + + /** + * @author klw + * @Description: text file + */ + TXT("text"), + + /** + * @author klw + * @Description: text file + */ + TEXT("text"), + + /** + * @author klw + * @Description: json file + */ + JSON("json"), + + /** + * @author klw + * @Description: xml file + */ + XML("xml"), + + /** + * @author klw + * @Description: html file + */ + HTM("html"), + + /** + * @author klw + * @Description: html file + */ + HTML("html"), + + /** + * @author klw + * @Description: properties file + */ + PROPERTIES("properties") + + ; + + /** + * @author klw + * @Description: file type corresponding to file extension + */ + private String fileType; + + FileTypeEnum(String fileType){ + this.fileType = fileType; + } + + public String getFileType(){ + return this.fileType; + } + + + +} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/SameConfigPolicy.java b/config/src/main/java/com/alibaba/nacos/config/server/model/SameConfigPolicy.java index f27446406..db3e95a52 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/SameConfigPolicy.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/SameConfigPolicy.java @@ -36,6 +36,6 @@ public enum SameConfigPolicy { /** * @Description: overwrite on duplicate */ - OVERWRITE; + OVERWRITE } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/result/ResultBuilder.java b/config/src/main/java/com/alibaba/nacos/config/server/result/ResultBuilder.java index 0f25961c2..2a85cef58 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/result/ResultBuilder.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/result/ResultBuilder.java @@ -1,3 +1,18 @@ +/* + * 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.result; import com.alibaba.nacos.config.server.model.RestResult; @@ -23,7 +38,19 @@ public class ResultBuilder { return buildResult(ResultCodeEnum.SUCCESS, resultData); } + public static RestResult buildSuccessResult(String successMsg, T resultData){ + RestResult rr = buildResult(ResultCodeEnum.SUCCESS, resultData); + rr.setMessage(successMsg); + return rr; + } + public static RestResult buildSuccessResult(){ return buildResult(ResultCodeEnum.SUCCESS, null); } + + public static RestResult buildSuccessResult(String successMsg){ + RestResult rr = buildResult(ResultCodeEnum.SUCCESS, null); + rr.setMessage(successMsg); + return rr; + } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/result/code/ResultCodeEnum.java b/config/src/main/java/com/alibaba/nacos/config/server/result/code/ResultCodeEnum.java index 5261289f5..b3e5e2d16 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/result/code/ResultCodeEnum.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/result/code/ResultCodeEnum.java @@ -1,3 +1,18 @@ +/* + * 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.result.code; import com.alibaba.nacos.config.server.result.core.IResultCode; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/result/core/IResultCode.java b/config/src/main/java/com/alibaba/nacos/config/server/result/core/IResultCode.java index ac0d58fe5..b93884095 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/result/core/IResultCode.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/result/core/IResultCode.java @@ -1,3 +1,18 @@ +/* + * 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.result.core; /** @@ -9,8 +24,9 @@ package com.alibaba.nacos.config.server.result.core; public interface IResultCode { /** + * get the result code + * * @author klw - * @Description: get the result code * @Date 2019/6/28 14:56 * @Param [] * @return java.lang.String @@ -18,8 +34,9 @@ public interface IResultCode { int getCode(); /** + * get the result code's message + * * @author klw - * @Description: get the result code's message * @Date 2019/6/28 14:56 * @Param [] * @return java.lang.String diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/PersistService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/PersistService.java index f7bc4ae3b..7bb1608d8 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/PersistService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/PersistService.java @@ -15,6 +15,7 @@ */ package com.alibaba.nacos.config.server.service; +import com.alibaba.nacos.config.server.enums.FileTypeEnum; import com.alibaba.nacos.config.server.exception.NacosException; import com.alibaba.nacos.config.server.model.*; import com.alibaba.nacos.config.server.utils.LogUtil; @@ -70,6 +71,16 @@ public class PersistService { private DataSourceService dataSourceService; + private static final String SQL_FIND_ALL_CONFIG_INFO = "select data_id,group_id,tenant_id,app_name,content,type from config_info"; + + private static final String SQL_TENANT_INFO_COUNT_BY_TENANT_ID = "select count(1) from tenant_info where tenant_id = ?"; + + /** + * @author klw + * @Description: constant variables + */ + public static final String SPOT = "."; + @PostConstruct public void init() { dataSourceService = dynamicDataSource.getDataSource(); @@ -3270,10 +3281,9 @@ public class PersistService { * @param group * @return Collection of ConfigInfo objects */ - public List findAllConfigInfo4eExport(final String group, final String tenant, + public List findAllConfigInfo4Export(final String group, final String tenant, final String appName, final String ids) { String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - String sql = "select data_id,group_id,tenant_id,app_name,content,type from config_info"; StringBuilder where = new StringBuilder(" where "); List paramList = new ArrayList<>(); if(StringUtils.isNotBlank(ids)){ @@ -3291,7 +3301,7 @@ public class PersistService { } } try { - return this.jt.query(sql + where, paramList.toArray(), CONFIG_INFO_ROW_MAPPER); + return this.jt.query(SQL_FIND_ALL_CONFIG_INFO + where, paramList.toArray(), CONFIG_INFO_ROW_MAPPER); } catch (CannotGetJdbcConnectionException e) { fatalLog.error("[db-error] " + e.toString(), e); throw e; @@ -3326,32 +3336,12 @@ public class PersistService { // simple judgment of file type based on suffix String type = null; - if (configInfo.getDataId().contains(".")) { - String extName = configInfo.getDataId().substring(configInfo.getDataId().lastIndexOf(".") + 1).toLowerCase(); - switch (extName) { - case "yml": - case "yaml": - type = "yaml"; - break; - case "txt": - case "text": - type = "text"; - break; - case "json": - type = "json"; - break; - case "xml": - type = "xml"; - break; - case "htm": - case "html": - type = "html"; - break; - case "properties": - type = "Properties"; - break; - default: - break; + if (configInfo.getDataId().contains(SPOT)) { + String extName = configInfo.getDataId().substring(configInfo.getDataId().lastIndexOf(SPOT) + 1).toLowerCase(); + try{ + type = FileTypeEnum.valueOf(extName).getFileType(); + }catch (Exception ex){ + type = FileTypeEnum.TEXT.getFileType(); } } if (configAdvanceInfo == null) { @@ -3414,10 +3404,9 @@ public class PersistService { */ public int tenantInfoCountByTenantId(String tenantId) { Assert.hasText(tenantId, "tenantId can not be null"); - String sql = "select count(1) from tenant_info where tenant_id = ?"; List paramList = new ArrayList<>(); paramList.add(tenantId); - Integer result = this.jt.queryForObject(sql, paramList.toArray(), Integer.class); + Integer result = this.jt.queryForObject(SQL_TENANT_INFO_COUNT_BY_TENANT_ID, paramList.toArray(), Integer.class); if (result == null) { return 0; } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/utils/ZipUtils.java b/config/src/main/java/com/alibaba/nacos/config/server/utils/ZipUtils.java index 786ef1dad..6dc1766ac 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/utils/ZipUtils.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/utils/ZipUtils.java @@ -15,6 +15,9 @@ */ package com.alibaba.nacos.config.server.utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.*; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -30,6 +33,8 @@ import java.util.zip.ZipOutputStream; */ public class ZipUtils { + private static final Logger log = LoggerFactory.getLogger(ZipUtils.class); + public static class ZipItem{ @@ -89,53 +94,31 @@ public class ZipUtils { } public static byte[] zip(List source){ - ByteArrayOutputStream byteOut = null; - ZipOutputStream zipOut = null; byte[] result = null; - try { - byteOut = new ByteArrayOutputStream(); - zipOut = new ZipOutputStream(byteOut); + try (ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); ZipOutputStream zipOut = new ZipOutputStream(byteOut)){ for (ZipItem item : source) { zipOut.putNextEntry(new ZipEntry(item.getItemName())); zipOut.write(item.getItemData().getBytes(StandardCharsets.UTF_8)); } + zipOut.flush(); + zipOut.finish(); + result = byteOut.toByteArray(); } catch (IOException e) { - e.printStackTrace(); - } finally { - if (zipOut != null) { - try { - zipOut.flush(); - zipOut.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - if (byteOut != null) { - try { - byteOut.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } + log.error("an error occurred while compressing data.", e); } - result = byteOut.toByteArray(); return result; } public static UnZipResult unzip(byte[] source) { - ZipInputStream zipIn = null; List itemList = new ArrayList<>(); ZipItem metaDataItem = null; - try { - zipIn = new ZipInputStream(new ByteArrayInputStream(source)); - ZipEntry entry = null; + try (ZipInputStream zipIn = new ZipInputStream(new ByteArrayInputStream(source))) { + ZipEntry entry; while ((entry = zipIn.getNextEntry()) != null && !entry.isDirectory()) { - ByteArrayOutputStream out = null; - try { - out = new ByteArrayOutputStream(); + try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { byte[] buffer = new byte[1024]; - int offset = -1; + int offset; while ((offset = zipIn.read(buffer)) != -1) { out.write(buffer, 0, offset); } @@ -145,23 +128,11 @@ public class ZipUtils { itemList.add(new ZipItem(entry.getName(), out.toString("UTF-8"))); } } catch (IOException e) { - e.printStackTrace(); - } finally { - if (out != null) { - out.close(); - } + log.error("unzip error", e); } } } catch (IOException e) { - e.printStackTrace(); - } finally { - if (zipIn != null) { - try { - zipIn.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } + log.error("unzip error", e); } return new UnZipResult(itemList, metaDataItem); } diff --git a/config/src/main/resources/META-INF/logback/nacos-included.xml b/config/src/main/resources/META-INF/logback/nacos-included.xml index 515a5fb47..a84b68335 100755 --- a/config/src/main/resources/META-INF/logback/nacos-included.xml +++ b/config/src/main/resources/META-INF/logback/nacos-included.xml @@ -258,5 +258,15 @@ + + + %d{yyyy-MM-dd HH:mm:ss,SSS} %5p [%t] %replace(%caller{1}){'\t|Caller.{1}0|\r\n', ''} - %m%n + + + + + + + diff --git a/console/src/main/resources/application.properties b/console/src/main/resources/application.properties index 64c42676e..6fc061399 100644 --- a/console/src/main/resources/application.properties +++ b/console/src/main/resources/application.properties @@ -1,3 +1,9 @@ +# mysql +spring.datasource.platform=mysql +db.num=1 +db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true +db.user=root +db.password=123456 # spring server.contextPath=/nacos