一.获取操作nacos 常用操作类,并包装为方法类,方便调用
@Component
@Slf4j
public class NacosConfigUtils {
private static String type = ".yaml";
private static String ip;
private static ConfigService configService;
private static NamingService namingService;
private static RestTemplate restTemplate = new RestTemplate();
public static void getNacosService(String ipAddress) {
try {
ip = ipAddress;
configService = NacosFactory.createConfigService(ip);
namingService = NamingFactory.createNamingService(ip);
} catch (NacosException e) {
e.printStackTrace();
}
}
public static Map getYamlConfig(String serviceName, String group) throws NacosException {
String dataId = serviceName.concat(type);
String contentInfo = configService.getConfig(dataId, group, 1000L);
Map amp = new HashMap(100);
try {
Yaml yaml = new Yaml();
if (contentInfo != null) {
//可以将值转换为Map
amp = yaml.load(new ByteArrayInputStream(contentInfo.getBytes()));
}
} catch (Exception e) {
log.error("get service config dataId :{},group:{}", dataId, group);
e.printStackTrace();
}
return amp;
}
public static Map setYamlConfig(Map map, String key, Object value) {
String[] keys = key.split("\\.");
int len = keys.length;
Map temp = map;
for (int i = 0; i < len - 1; i++) {
if (temp.containsKey(keys[i])) {
temp = (Map) temp.get(keys[i]);
} else {
return null;
}
if (i == len - 2) {
temp.put(keys[i + 1], value);
}
}
if (len == 1) {
temp.put(keys[0], value);
}
log.info("reset service config key :{},value:{}, reSetValue:{}", key, value, map);
return map;
}
public static Boolean publish(String serviceName, String group, Map map) throws NacosException {
String dataId = serviceName.concat(type);
DumperOptions dumperOptions = new DumperOptions();
dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
Yaml yaml = new Yaml(dumperOptions);
String content = yaml.dump(map);
log.info("publish service config dataId :{},group:{}, content:{}", dataId, group, content);
return configService.publishConfig(dataId, group, content);
}
public static Instance getHealthInstance(String serviceName) throws NacosException {
return namingService.selectOneHealthyInstance(serviceName, true);
}
public static List getRegisterServiceList() {
String url = String.format("http://%s:8848/nacos/v1/ns/service/list?pageNo=1&pageSize=20", ip);
Map map = restTemplate.getForObject(url, Map.class);
if (null != map) {
return (List) map.get("doms");
}
return null;
}
public static Boolean isExistKey(String key, Map map) {
String[] keys = key.split("\\.");
int len = keys.length;
Map temp = map;
for (int i = 0; i < len; i++) {
if (temp.containsKey(keys[i])) {
if (i == len - 1) {
return true;
}
temp = (Map) temp.get(keys[i]);
} else {
return false;
}
}
return true;
}
}
二:具体应用(仅供参考)
(一)读取nacos ,暂存本地后,再读取为map
private static final String filePath = "/webConfig/webconfig.yaml";
public static Map getConfig(String contentInfo) throws Exception {
File directory = new File("");
String courseFile = directory.getCanonicalPath();
File distFile = new File(courseFile.concat(filePath));
if (!distFile.getParentFile().exists()) {
distFile.getParentFile().mkdirs();
}
Map map = new HashMap<>();
// 将配置内容放置到固定的文件中去
BufferedReader bufferedReader = null;
BufferedWriter bufferedWriter = null;
try {
// 本地调试访问形式
if (!distFile.getParentFile().exists()) {
distFile.getParentFile().mkdirs();
}
bufferedReader = new BufferedReader(new StringReader(contentInfo));
bufferedWriter = new BufferedWriter(new FileWriter(distFile));
char buf[] = new char[1024];
int len;
while ((len = bufferedReader.read(buf)) != -1) {
bufferedWriter.write(buf, 0, len);
}
bufferedWriter.flush();
bufferedReader.close();
bufferedWriter.close();
// 重新读取放入配置内容的config文件
Yaml yaml = new Yaml();
InputStream yamlFile = new FileInputStream(distFile);
// 特殊说明 本地window环境设置编码utf-8,服务器环境设置编码GB2312
InputStreamReader isr = new InputStreamReader(yamlFile, "UTF-8");
BufferedReader reader = new BufferedReader(isr);
if (yamlFile != null) {
map = yaml.load(reader);
}
reader.close();
isr.close();
} catch (Exception e) {
System.out.println(e);
} finally {
Boolean delete = distFile.delete();
}
return map;
}
(二).针对NacosUtils类具体应用(仅参考)
@Slf4j
@Service
public class WebConfigServiceImpl implements WebConfigService {
private static final String servicePlatFormGroup = "serviceGroup";
private static final String serviceKey = "serviceKey";
private static final String platFormService = "platFormService";
private static final char middleLine = '-';
private static final String features = "features";
private static final String settings = "settings";
private static final String servicePrefix = "servicePrefix";
private static final String serviceList = "serviceList";
private static final String webConfig = "webConfig";
private static final String namespace = "namespace";
private static final String platform = "platform";
@Value("${spring.application.name}")
private String serviceName;
@Value("${spring.application.group}")
private String group;
@Value("${spring.cloud.nacos.discovery.ip}")
private String ip;
@Autowired
private ConfigurableApplicationContext applicationContext;
@Override
public Map getWebConfig() {
try {
NacosConfigUtils.getNacosService(ip);
String platFormList = applicationContext.getEnvironment().getProperty(platFormService);
Map map = new LinkedHashMap<>();
Map basicConfig = NacosConfigUtils.getYamlConfig(serviceName, group);
LinkedHashMap webMap = (LinkedHashMap) basicConfig.get(webConfig);
String basicPlatform = (String) webMap.get(platform);
String basicNameSpace = (String) webMap.get(namespace);
map.put(platform, basicPlatform);
map.put(basicNameSpace, getProcessData(webMap, basicNameSpace));
if (null != platFormList) {
String[] split = platFormList.split(",");
for (String s : split) {
String[] str = s.split("\\|");
Map map1 = NacosConfigUtils.getYamlConfig(str[0], str[1]);
if (null != map1 && map1.isEmpty()) {
continue;
}
LinkedHashMap result = (LinkedHashMap) map1.get(webConfig);
String nsp = (String) result.get(namespace);
map.put(nsp, getProcessData(result, nsp));
}
}
return map;
} catch (Exception e) {
log.error("get web config error,reason: ", ExceptionUtils.getStackTrace(e));
throw new InterfaceException(Errorcode.GET_WEB_CONFIG_ERROR, "get web config error");
}
}
@Override
public void updateServiceList(ServiceUpdateVO serviceUpdateVO) {
String serviceName = serviceUpdateVO.getServiceName();
String group = serviceUpdateVO.getGroup();
String platFormList = applicationContext.getEnvironment().getProperty(platFormService);
if (null != platFormList) {
boolean contains = platFormList.contains(serviceName.concat("|").concat(group));
if (!contains) {
String str = String.format(",%s|%s", serviceName, group);
platFormList = platFormList.concat(str);
} else {
log.info("this service has existed with platformList,service name: {} ---group:{}", serviceName, group);
}
} else {
String str = String.format("%s|%s", serviceName, group);
platFormList = str;
}
//更新config;
try {
NacosConfigUtils.getNacosService(ip);
Map config = NacosConfigUtils.getYamlConfig(this.serviceName, this.group);
Map newConfig = NacosConfigUtils.setYamlConfig(config, platFormService, platFormList);
NacosConfigUtils.publish(this.serviceName, this.group, newConfig);
} catch (Exception e) {
log.error("reset service list error, service name: {}---- group:{}", this.serviceName, this.group);
}
}
private Map getServiceList(String namespace) {
//获取namespace
Map map = new HashMap<>(100);
List registerServiceList = NacosConfigUtils.getRegisterServiceList();
if (!CollectionUtils.isEmpty(registerServiceList)) {
for (String serviceName : registerServiceList) {
try {
Instance healthInstance = NacosConfigUtils.getHealthInstance(serviceName);
Map metadata = healthInstance.getMetadata();
String group = metadata.get(servicePlatFormGroup);
if (namespace.equals(group)) {
String serviceKeys = metadata.get(serviceKey);
if (null != serviceKeys) {
String[] str = serviceKeys.split(",");
if (str.length > 1) {
for (String i : str) {
map.put(i, camelToMiddleLine(i));
}
} else {
map.put(str[0], serviceName);
}
} else {
map.put(middleLineToCamel(serviceName), serviceName);
}
}
} catch (Exception e) {
log.error(ExceptionUtils.getStackTrace(e));
continue;
}
}
}
return map;
}
@Override
public void saveWebConfig(Map map) {
NacosConfigUtils.getNacosService(ip);
try {
Map config = NacosConfigUtils.getYamlConfig(serviceName, group);
for (String str : map.keySet()) {
if (NacosConfigUtils.isExistKey(str, config)) {
config = NacosConfigUtils.setYamlConfig(config, str, map.get(str));
} else {
log.error("update basic config error");
throw new InterfaceException(Errorcode.UPDATE_NACOS_ERROR, "nacos key does't exist");
}
}
NacosConfigUtils.publish(serviceName, group, config);
} catch (NacosException e) {
log.error("get basic config error");
throw new InterfaceException(Errorcode.UPDATE_NACOS_ERROR, "update nacos error,please try again");
}
}
//去掉中横线
private String middleLineToCamel(String param) {
if (param == null || "".equals(param.trim())) {
return "";
}
int len = param.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char c = param.charAt(i);
if (c == middleLine) {
if (++i < len) {
sb.append(Character.toUpperCase(param.charAt(i)));
}
} else {
sb.append(c);
}
}
return sb.toString();
}
//添加中横线
public static String camelToMiddleLine(String param) {
if (param == null || "".equals(param.trim())) {
return "";
}
int len = param.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char c = param.charAt(i);
if (Character.isUpperCase(c)) {
sb.append(middleLine);
sb.append(Character.toLowerCase(c));
} else {
sb.append(c);
}
}
return sb.toString();
}
private Map getProcessData(LinkedHashMap map, String namespace) {
Map data = new LinkedHashMap<>();
Object feature = map.get(features);
Object setting = map.get(settings);
String servicePref = (String) map.get(servicePrefix);
data.put(features, feature);
data.put(settings, setting);
data.put(servicePrefix, servicePref);
data.put(serviceList, getServiceList(namespace));
return data;
}
(三).配置中添加元数据,并代码读取。
读取元数据:
Instance healthInstance = NacosConfigUtils.getHealthInstance(serviceName);
Map metadata = healthInstance.getMetadata();
String group = metadata.get(servicePlatFormGroup);
if (namespace.equals(group)) {
String serviceKeys = metadata.get(serviceKey);
if (null != serviceKeys) {
String[] str = serviceKeys.split(",");
if (str.length > 1) {
for (String i : str) {
map.put(i, camelToMiddleLine(i));
}
} else {
map.put(str[0], serviceName);
}
} else {
map.put(middleLineToCamel(serviceName), serviceName);
}
}