按照review意见修改

This commit is contained in:
keran 2019-07-01 17:48:45 +08:00
parent 98edb0edfa
commit 61b6302625
10 changed files with 238 additions and 133 deletions

View File

@ -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<Long> ids) {
String idsStr = idList2String(ids);
List<ConfigInfo> dataList = persistService.findAllConfigInfo4eExport(group, tenant, appName, idsStr);
ids.removeAll(Collections.singleton(null));
String idsStr = Joiner.on(",").join(ids);
List<ConfigInfo> dataList = persistService.findAllConfigInfo4Export(group, tenant, appName, idsStr);
List<ZipUtils.ZipItem> 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<byte[]>(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<Map<String, Object>> rr = new RestResult<>();
Map<String, Object> 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<ConfigInfo> 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<Long> ids,
@RequestParam(value = "policy", defaultValue = "ABORT")
SameConfigPolicy policy) throws NacosException {
RestResult<Map<String, Object>> rr = new RestResult<>();
Map<String, Object> 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<ConfigInfo> queryedDataList = persistService.findAllConfigInfo4eExport(null, null, null, idsStr);
ids.removeAll(Collections.singleton(null));
String idsStr = Joiner.on(",").join(ids);
List<ConfigInfo> 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<ConfigInfo> 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<Long> 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();
}
}

View File

@ -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;
}
}

View File

@ -36,6 +36,6 @@ public enum SameConfigPolicy {
/**
* @Description: overwrite on duplicate
*/
OVERWRITE;
OVERWRITE
}

View File

@ -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 <T extends Object> RestResult<T> buildSuccessResult(String successMsg, T resultData){
RestResult<T> rr = buildResult(ResultCodeEnum.SUCCESS, resultData);
rr.setMessage(successMsg);
return rr;
}
public static <T extends Object> RestResult<T> buildSuccessResult(){
return buildResult(ResultCodeEnum.SUCCESS, null);
}
public static <T extends Object> RestResult<T> buildSuccessResult(String successMsg){
RestResult<T> rr = buildResult(ResultCodeEnum.SUCCESS, null);
rr.setMessage(successMsg);
return rr;
}
}

View File

@ -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;

View File

@ -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

View File

@ -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<ConfigInfo> findAllConfigInfo4eExport(final String group, final String tenant,
public List<ConfigInfo> 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<String> 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<String> 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;
}

View File

@ -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<ZipItem> 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));
}
} 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();
}
}
}
zipOut.finish();
result = byteOut.toByteArray();
} catch (IOException e) {
log.error("an error occurred while compressing data.", e);
}
return result;
}
public static UnZipResult unzip(byte[] source) {
ZipInputStream zipIn = null;
List<ZipItem> 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);
}

View File

@ -258,5 +258,15 @@
<appender-ref ref="startLog"/>
</logger>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<layout name="StandardFormat" class="ch.qos.logback.classic.PatternLayout">
<pattern>%d{yyyy-MM-dd HH:mm:ss,SSS} %5p [%t] %replace(%caller{1}){'\t|Caller.{1}0|\r\n', ''} - %m%n</pattern>
</layout>
</appender>
<logger name="org.springframework.jdbc.core" additivity="false">
<level value="INFO"/>
<appender-ref ref="CONSOLE" />
</logger>
</included>

View File

@ -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