package com.ruoyi.cc.service.impl; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.ruoyi.cc.model.FsConfProfile; import com.ruoyi.cc.service.ICcParamsService; import com.ruoyi.cc.service.IFsConfService; import com.ruoyi.cc.utils.ShellUtil; import com.ruoyi.common.utils.CommonUtils; import com.ruoyi.common.utils.ExceptionUtil; import com.ruoyi.common.utils.StringUtils; import link.thingscloud.freeswitch.esl.EslConnectionUtil; import link.thingscloud.freeswitch.esl.transport.message.EslMessage; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.*; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.ArrayList; import java.util.List; /** * freeswitch配置文件控制service层 */ @Service @Slf4j public class FsConfServiceImpl implements IFsConfService { @Autowired private ICcParamsService ccParamsService; @Value("${sysconfig.hide-secret}") private String sysConfigHideSecret; @Value("${sysconfig.hidden-key-list}") private String sysConfigHideKeyList; /** * 检查是否需要隐藏指定的字段值 * @param fieldName * @return */ @Override public boolean checkNeedHidden(String fieldName){ boolean hidden = Boolean.parseBoolean(sysConfigHideSecret); if(!hidden){ return false; } String[] array = sysConfigHideKeyList.split("/"); for (String s : array) { if(fieldName.toLowerCase().contains(s)){ return true; } } return false; } @Override public void setSwitchConf(JSONArray params) { String fsConfDirectory = ccParamsService.getParamValueByCode("fs_conf_directory", ""); try { // 创建DocumentBuilderFactory对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 创建DocumentBuilder对象 DocumentBuilder builder = factory.newDocumentBuilder(); // 解析XML文件获取Document对象 String switchConfXmlPath = fsConfDirectory + "/autoload_configs/switch.conf.xml"; Document document = builder.parse(new File(switchConfXmlPath)); // 获取settings元素 Element settings = (Element)document.getElementsByTagName("settings").item(0); // 更新属性值 NodeList nodes = settings.getElementsByTagName("param"); for (int i = 0; i < nodes.getLength(); i++) { if (nodes.item(i) instanceof Element) { Element element = (Element) nodes.item(i); log.info(JSONObject.toJSONString(element)); for (int j = 0; j < params.size(); j++) { JSONObject param = params.getJSONObject(j); String attrName = param.getString("name"); if (attrName.equals(element.getAttribute("name"))) { element.setAttribute("value", param.getString("value").trim()); } } } } // 将更新后的Document对象写回XML文件 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); DOMSource source = new DOMSource(document); StringWriter writer = new StringWriter(); transformer.transform(source, new StreamResult(writer)); String updatedXML = writer.toString(); // 将updatedXML写入文件 java.nio.file.Files.write(java.nio.file.Paths.get(switchConfXmlPath), updatedXML.getBytes()); } catch (Exception e) { e.printStackTrace(); } } @Override public void restartFs() { // 使用ProcessBuilder来正确处理命令字符串 List commands = new ArrayList<>(); String fsDeployType = ccParamsService.getParamValueByCode("fs-deploy-type", "native"); if("native".equalsIgnoreCase(fsDeployType)){ String fsNativeStartUpScript = ccParamsService.getParamValueByCode( "fs-deploy-native-start-up-script", "/usr/local/freeswitchvideo/bin/freeswitch.sh" ); commands.add("/usr/bin/sh"); commands.add(fsNativeStartUpScript); }else if("docker".equalsIgnoreCase(fsDeployType)){ String fsDockerContainerName = ccParamsService.getParamValueByCode( "fs_docker_container_name", "freeswitchvideo-debian12" ); commands.add("docker"); commands.add("restart"); commands.add(fsDockerContainerName); } if(commands.size() == 0){ log.error("fs-deploy-type 参数错误!"); return; } try { // 使用ProcessBuilder执行命令 ProcessBuilder processBuilder = new ProcessBuilder(commands); Process process = processBuilder.start(); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { log.info(line); } // 读取命令的错误输出 BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); String errorLine; while ((errorLine = errorReader.readLine()) != null) { log.info(errorLine); } int exitCode = process.waitFor(); // 等待进程结束并获取退出值 if (exitCode == 0) { log.info(StringUtils.join(commands.toArray(), " ") + " executed successfully."); } else { log.info("exitCode:" + exitCode); log.info(StringUtils.join(commands.toArray(), " ") + " execution failed."); } } catch (IOException | InterruptedException e) { e.printStackTrace(); } } @Override public JSONObject getSwitchConf() { String fsConfDirectory = ccParamsService.getParamValueByCode("fs_conf_directory", ""); JSONObject confAllVars = new JSONObject(); try { // 创建DocumentBuilderFactory对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 创建DocumentBuilder对象 DocumentBuilder builder = factory.newDocumentBuilder(); // 解析XML文件获取Document对象 String switchConfXmlPath = fsConfDirectory + "/autoload_configs/switch.conf.xml"; Document document = builder.parse(new File(switchConfXmlPath)); // 获取settings元素 Element settings = (Element)document.getElementsByTagName("settings").item(0); // 获取属性值 NodeList nodes = settings.getElementsByTagName("param"); for (int i = 0; i < nodes.getLength(); i++) { if (nodes.item(i) instanceof Element) { Element element = (Element) nodes.item(i); confAllVars.put(element.getAttribute("name"), element.getAttribute("value")); } } } catch (Exception e) { e.printStackTrace(); } return confAllVars; } @Override public String getAsrengine() { String fsConfDirectory = ccParamsService.getParamValueByCode("fs_conf_directory", ""); try { // 创建DocumentBuilderFactory对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 创建DocumentBuilder对象 DocumentBuilder builder = factory.newDocumentBuilder(); // 解析XML文件获取Document对象 String modulesConfXmlPath = fsConfDirectory + "/autoload_configs/modules.conf.xml"; Document document = builder.parse(new File(modulesConfXmlPath)); // 获取modules元素 Element modules = (Element)document.getElementsByTagName("modules").item(0); // 获取属性值 NodeList nodes = modules.getElementsByTagName("load"); for (int i = 0; i < nodes.getLength(); i++) { if (nodes.item(i) instanceof Element) { Element element = (Element) nodes.item(i); if ("mod_xunfei_asr".equals(element.getAttribute("module"))){ return "mod_xunfei_asr"; } if ("mod_aliyun_asr".equals(element.getAttribute("module"))){ return "mod_aliyun_asr"; } if ("mod_funasr".equals(element.getAttribute("module"))){ return "mod_funasr"; } } } } catch (Exception e) { e.printStackTrace(); } return ""; } @Override public String setAsrengine(String asrengine) { String fsConfDirectory = ccParamsService.getParamValueByCode("fs_conf_directory", ""); try { // 创建DocumentBuilderFactory对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 创建DocumentBuilder对象 DocumentBuilder builder = factory.newDocumentBuilder(); // 解析XML文件获取Document对象 String modulesConfXmlPath = fsConfDirectory + "/autoload_configs/modules.conf.xml"; Document document = builder.parse(new File(modulesConfXmlPath)); // 获取modules元素 Element modules = (Element)document.getElementsByTagName("modules").item(0); // 获取属性值 NodeList nodes = modules.getElementsByTagName("load"); Boolean existAsrMod = false; for (int i = 0; i < nodes.getLength(); i++) { if (nodes.item(i) instanceof Element) { Element element = (Element) nodes.item(i); if ("mod_xunfei_asr".equals(element.getAttribute("module")) || "mod_funasr".equals(element.getAttribute("module")) || "mod_aliyun_asr".equals(element.getAttribute("module"))){ existAsrMod = true; if (StringUtils.isNotEmpty(asrengine)) { element.setAttribute("module", asrengine); } else { modules.removeChild(element); } } } } if (!existAsrMod && StringUtils.isNotEmpty(asrengine)) { Element element = document.createElement("load"); element.setAttribute("module", asrengine); modules.appendChild(element); } // 将更新后的Document对象写回XML文件 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); DOMSource source = new DOMSource(document); StringWriter writer = new StringWriter(); transformer.transform(source, new StreamResult(writer)); String updatedXML = writer.toString(); // 将updatedXML写入文件 java.nio.file.Files.write(java.nio.file.Paths.get(modulesConfXmlPath), updatedXML.getBytes()); } catch (Throwable e) { String tips = String.format("更新配置文件 modules.conf.xml 失败, {} {}", e.toString(), CommonUtils.getStackTraceString(e.getStackTrace())); log.error(tips); return tips; } return ""; } @Override public void setVarsConf(JSONArray params) { String fsConfDirectory = ccParamsService.getParamValueByCode("fs_conf_directory", ""); try { // 创建DocumentBuilderFactory对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 创建DocumentBuilder对象 DocumentBuilder builder = factory.newDocumentBuilder(); // 解析XML文件获取Document对象 String varsConfXmlPath = fsConfDirectory + "/vars.xml"; Document document = builder.parse(new File(varsConfXmlPath)); NodeList nodes = document.getElementsByTagName("X-PRE-PROCESS"); for (int i = 0; i < nodes.getLength(); i++) { if (nodes.item(i) instanceof Element) { Element element = (Element) nodes.item(i); log.info(JSONObject.toJSONString(element)); for (int j = 0; j < params.size(); j++) { JSONObject param = params.getJSONObject(j); String data = element.getAttribute("data"); String name = data.substring(0, data.indexOf("=")); String attrName = param.getString("name"); if (attrName.equals(name)) { element.setAttribute("data", attrName + "=" + param.getString("value").trim()); } } } } // 将更新后的Document对象写回XML文件 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); DOMSource source = new DOMSource(document); StringWriter writer = new StringWriter(); transformer.transform(source, new StreamResult(writer)); String updatedXML = writer.toString(); // 将updatedXML写入文件 java.nio.file.Files.write(java.nio.file.Paths.get(varsConfXmlPath), updatedXML.getBytes()); } catch (Exception e) { e.printStackTrace(); } } @Override public JSONObject getVarsConf() { JSONObject confAllVars = new JSONObject(); String fsConfDirectory = ccParamsService.getParamValueByCode("fs_conf_directory", ""); try { // 创建DocumentBuilderFactory对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 创建DocumentBuilder对象 DocumentBuilder builder = factory.newDocumentBuilder(); // 解析XML文件获取Document对象 String varsConfXmlPath = fsConfDirectory + "/vars.xml"; Document document = builder.parse(new File(varsConfXmlPath)); // 获取属性值 NodeList nodes = document.getElementsByTagName("X-PRE-PROCESS"); for (int i = 0; i < nodes.getLength(); i++) { if (nodes.item(i) instanceof Element) { Element element = (Element) nodes.item(i); String data = element.getAttribute("data"); if (StringUtils.isNotEmpty(data)) { String name = data.substring(0, data.indexOf("=")); String value = data.substring(data.indexOf("=") + 1); confAllVars.put(name, value); } } } } catch (Exception e) { e.printStackTrace(); } return confAllVars; } @Override public JSONObject getAsrConf(String asrFileName) { JSONObject confAllVars = new JSONObject(); String fsConfDirectory = ccParamsService.getParamValueByCode("fs_conf_directory", ""); try { // 创建DocumentBuilderFactory对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 创建DocumentBuilder对象 DocumentBuilder builder = factory.newDocumentBuilder(); // 解析XML文件获取Document对象 String asrConfXmlPath = fsConfDirectory + asrFileName; Document document = builder.parse(new File(asrConfXmlPath)); // 获取settings元素 Element settings = (Element)document.getElementsByTagName("settings").item(0); // 获取属性值 NodeList nodes = settings.getElementsByTagName("param"); for (int i = 0; i < nodes.getLength(); i++) { if (nodes.item(i) instanceof Element) { Element element = (Element) nodes.item(i); confAllVars.put(element.getAttribute("name"), element.getAttribute("value")); } } } catch (Exception e) { e.printStackTrace(); } return confAllVars; } @Override public String setAsrConf(JSONArray params, String asrFileName) { String fsConfDirectory = ccParamsService.getParamValueByCode("fs_conf_directory", ""); try { // 创建DocumentBuilderFactory对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 创建DocumentBuilder对象 DocumentBuilder builder = factory.newDocumentBuilder(); // 解析XML文件获取Document对象 String asrConfXmlPath = fsConfDirectory + asrFileName; Document document = builder.parse(new File(asrConfXmlPath)); // 获取settings元素 Element settings = (Element)document.getElementsByTagName("settings").item(0); // 更新属性值 NodeList nodes = settings.getElementsByTagName("param"); for (int i = 0; i < nodes.getLength(); i++) { if (nodes.item(i) instanceof Element) { Element element = (Element) nodes.item(i); log.info(JSONObject.toJSONString(element)); for (int j = 0; j < params.size(); j++) { JSONObject param = params.getJSONObject(j); String attrName = param.getString("name"); boolean needHidden = checkNeedHidden(attrName); boolean containsMaskStr = param.getString("value").contains("****"); if (attrName.equals(element.getAttribute("name"))) { if(!needHidden || !containsMaskStr) { element.setAttribute("value", param.getString("value").trim()); } } } } } // 将更新后的Document对象写回XML文件 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); DOMSource source = new DOMSource(document); StringWriter writer = new StringWriter(); transformer.transform(source, new StreamResult(writer)); String updatedXML = writer.toString(); // 将updatedXML写入文件 java.nio.file.Files.write(java.nio.file.Paths.get(asrConfXmlPath), updatedXML.getBytes()); } catch (Exception e) { String errorDetails = e.toString() + CommonUtils.getStackTraceString(e.getStackTrace()); log.error("setAsrConf error: {}", errorDetails); return errorDetails; } return ""; } @Override public String getCertWssPen() { String fsConfDirectory = ccParamsService.getParamValueByCode("fs_conf_directory", ""); String fileName = fsConfDirectory + "/tls/wss.pem"; StringBuilder content = new StringBuilder(); if (!new File(fileName).exists()) { return ""; } try (BufferedReader br = new BufferedReader(new FileReader(fileName))) { String line; while ((line = br.readLine()) != null) { content.append(line).append("\n"); // 追加每一行内容,并添加换行符 } } catch (IOException e) { e.printStackTrace(); } return content.toString(); } @Override public void setCertWssPen(String certValue) { String fsConfDirectory = ccParamsService.getParamValueByCode("fs_conf_directory", ""); String fileName = fsConfDirectory + "/tls/wss.pem"; if (!new File(fsConfDirectory + "/tls").exists()) { new File(fsConfDirectory + "/tls").mkdirs(); } if (!new File(fileName).exists()) { try { new File(fileName).createNewFile(); } catch (IOException e) { e.printStackTrace(); } } try (BufferedWriter bw = new BufferedWriter(new FileWriter(fileName))) { bw.write(certValue); } catch (IOException e) { e.printStackTrace(); } } @Override public String getLicenseValue() { String fsConfDirectory = ccParamsService.getParamValueByCode("fs_conf_directory", ""); String fileName = fsConfDirectory + "/autoload_configs/license.conf"; StringBuilder content = new StringBuilder(); if (!new File(fileName).exists()) { return ""; } try (BufferedReader br = new BufferedReader(new FileReader(fileName))) { String line; while ((line = br.readLine()) != null) { content.append(line).append("\n"); // 追加每一行内容,并添加换行符 } } catch (IOException e) { e.printStackTrace(); } return content.toString(); } @Override public void setLicenseConf(String licenseValue) { String fsConfDirectory = ccParamsService.getParamValueByCode("fs_conf_directory", ""); String fileName = fsConfDirectory + "/autoload_configs/license.conf"; if (!new File(fileName).exists()) { try { new File(fileName).createNewFile(); } catch (IOException e) { e.printStackTrace(); } } try (BufferedWriter bw = new BufferedWriter(new FileWriter(fileName))) { bw.write(licenseValue); } catch (IOException e) { e.printStackTrace(); } } @Override public JSONObject getLicenseInfo(){ return JSONObject.parseObject(ccParamsService.getParamValueByCode("system_license_info", "{}")); } @Override public String getLogs(String uuid, String logFile, String logType) { log.info(logFile); // 使用ProcessBuilder来正确处理命令字符串 String ansiRegex = "\u001b\\[[;\\d]*m"; // 匹配 ANSI 转义序列的正则表达式 List commands = new ArrayList<>(); commands.add("sh"); commands.add("-c"); if (StringUtils.isBlank(uuid)) { commands.add("tail -n 20 " + logFile); } else { commands.add("cat " + logFile + " | grep '" + uuid + "'"); } log.info(StringUtils.join(commands.toArray(), " ")); String logs = ""; try { // 使用ProcessBuilder执行命令 ProcessBuilder processBuilder = new ProcessBuilder(commands); Process process = processBuilder.start(); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { if ("fs".equals(logType)) { try{ logs += JSONObject.parseObject(line).getString("log").replaceAll(ansiRegex, "") ; }catch (Exception e) { log.error(ExceptionUtil.getExceptionMessage(e)); } } else { logs += line + "\r\n"; } } // 读取命令的错误输出 BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); String errorLine; while ((errorLine = errorReader.readLine()) != null) { log.info(errorLine); } process.waitFor(); // 等待进程结束并获取退出值 } catch (IOException | InterruptedException e) { e.printStackTrace(); } return logs; } @Override public List selectProfileList() { String fsConfDirectory = ccParamsService.getParamValueByCode("fs_conf_directory", ""); List fsConfProfileList = new ArrayList<>(); String profilePath = fsConfDirectory + "/sip_profiles"; File profileDir = new File(profilePath); // 过滤出文件夹中所有的文件(非文件夹) File[] files = profileDir.listFiles(new FileFilter() { public boolean accept(File file) { return file.isFile(); } }); if (files != null) { for (File file : files) { // 检查文件是否是XML文件 if (file.getName().endsWith(".xml")) { try { FsConfProfile fsConfProfile = new FsConfProfile(); // 创建DocumentBuilderFactory对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 创建DocumentBuilder对象 DocumentBuilder builder = factory.newDocumentBuilder(); // 解析XML文件 Document document = builder.parse(file); // profile元素 Element profile = (Element)document.getElementsByTagName("profile").item(0); fsConfProfile.setProfileName(profile.getAttribute("name")); // 获取settings元素 Element settings = (Element)document.getElementsByTagName("settings").item(0); // 获取属性值 NodeList nodes = settings.getElementsByTagName("param"); for (int i = 0; i < nodes.getLength(); i++) { if (nodes.item(i) instanceof Element) { Element element = (Element) nodes.item(i); if ("sip-port".equals(element.getAttribute("name"))) { fsConfProfile.setSipPort(element.getAttribute("value")); } if ("sip-ip".equals(element.getAttribute("name"))) { fsConfProfile.setSipId(element.getAttribute("value")); } } } fsConfProfileList.add(fsConfProfile); } catch (Exception e) { e.printStackTrace(); } } } } return fsConfProfileList; } @Override public String setProfileConf(String profileName, String profileType, JSONArray params) { String fsConfDirectory = ccParamsService.getParamValueByCode("fs_conf_directory", ""); try { // 创建DocumentBuilderFactory对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 创建DocumentBuilder对象 DocumentBuilder builder = factory.newDocumentBuilder(); // 解析XML文件获取Document对象 String profilefXmlPath = fsConfDirectory + "/sip_profiles/" + profileName + ".xml"; File profilefXmlFile = new File(profilefXmlPath); if (!profilefXmlFile.exists()) { // 如果xml文件不存在(新增profile),则先从模板文件里拷贝一份,并创建对应的文件夹 try { // 使用Files.copy方法拷贝文件 Files.copy(Paths.get(fsConfDirectory + "/template/" + profileType + ".xml"), Paths.get(profilefXmlPath), StandardCopyOption.REPLACE_EXISTING); log.info("文件拷贝成功!"); new File(fsConfDirectory + "/sip_profiles/" + profileName).mkdirs(); log.info("创建文件夹成功!"); } catch (IOException e) { e.printStackTrace(); log.info("文件拷贝失败!"); } } Document document = builder.parse(profilefXmlFile); // profile元素 Element profile = (Element)document.getElementsByTagName("profile").item(0); profile.setAttribute("name", profileName); // 获取X-PRE-PROCESS元素,修改data Element gatways = (Element)document.getElementsByTagName("X-PRE-PROCESS").item(0); if(gatways == null){ return "profile 模板文件错误,无法读取网关配置节点!"; } gatways.setAttribute("data", profileName + "/*.xml"); // 获取settings元素 Element settings = (Element)document.getElementsByTagName("settings").item(0); // 更新属性值 NodeList nodes = settings.getElementsByTagName("param"); for (int j = 0; j < params.size(); j++) { JSONObject param = params.getJSONObject(j); String attrName = param.getString("name"); String attrValue = param.getString("value"); // 忽略参数名或者参数值为空的参数 if (StringUtils.isBlank(attrName) || StringUtils.isBlank(attrValue)) { continue; } Boolean newParams = true; // 是否是新增参数 for (int i = 0; i < nodes.getLength(); i++) { if (nodes.item(i) instanceof Element) { Element element = (Element) nodes.item(i); if (attrName.equals(element.getAttribute("name"))) { newParams = false; element.setAttribute("value", param.getString("value").trim()); } } } if (newParams) { log.info("新增属性:{}", JSONObject.toJSONString(param)); Element element = document.createElement("param"); element.setAttribute("name", param.getString("name").trim()); element.setAttribute("value", param.getString("value").trim()); settings.appendChild(element); } } // 将更新后的Document对象写回XML文件 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); DOMSource source = new DOMSource(document); StringWriter writer = new StringWriter(); transformer.transform(source, new StreamResult(writer)); String updatedXML = writer.toString(); // 将updatedXML写入文件 java.nio.file.Files.write(java.nio.file.Paths.get(profilefXmlPath), updatedXML.getBytes()); } catch (Exception e) { return String.format("修改profile失败, %s \n %s", e.toString(), CommonUtils.getStackTraceString(e.getStackTrace())); } return ""; } @Override public JSONObject getProfileConf(String profileName, String profileType) { String fsConfDirectory = ccParamsService.getParamValueByCode("fs_conf_directory", ""); String profilefXmlPath = ""; if (StringUtils.isBlank(profileName)) { // 新增 profilefXmlPath = fsConfDirectory + "/template/" + profileType + ".xml"; } else { // 更新/查看 profilefXmlPath = fsConfDirectory + "/sip_profiles/" + profileName + ".xml"; } JSONObject confAllVars = new JSONObject(); try { // 创建DocumentBuilderFactory对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 创建DocumentBuilder对象 DocumentBuilder builder = factory.newDocumentBuilder(); // 解析XML文件获取Document对象 Document document = builder.parse(new File(profilefXmlPath)); // 获取settings元素 Element settings = (Element)document.getElementsByTagName("settings").item(0); // 获取属性值 NodeList nodes = settings.getElementsByTagName("param"); for (int i = 0; i < nodes.getLength(); i++) { if (nodes.item(i) instanceof Element) { Element element = (Element) nodes.item(i); confAllVars.put(element.getAttribute("name"), element.getAttribute("value")); } } } catch (Exception e) { e.printStackTrace(); } return confAllVars; } @Override public void setGwRegisterConf(String orginProfileName, String profileName, String gwName, JSONObject params) { String fsConfDirectory = ccParamsService.getParamValueByCode("fs_conf_directory", ""); setGwConf(fsConfDirectory + "/template/MRWG1.xml", orginProfileName, profileName, gwName, params); } @Override public void setGwUnRegisterConf(String orginProfileName, String profileName, String gwName, JSONObject params) { String fsConfDirectory = ccParamsService.getParamValueByCode("fs_conf_directory", ""); setGwConf(fsConfDirectory + "/template/MRWG0.xml", orginProfileName, profileName, gwName, params); } @Override public String getFingerprintValue() { String cmd = ccParamsService.getParamValueByCode("system_hw_fingerprint_cmd", ""); try { String fingerprintValue = ShellUtil.exec(cmd); return fingerprintValue; } catch (Exception e) { log.error(ExceptionUtil.getExceptionMessage(e)); return e.getMessage(); } } private void setGwConf(String gwTemplate, String orginProfileName, String profileName, String gwName, JSONObject params) { String fsConfDirectory = ccParamsService.getParamValueByCode("fs_conf_directory", ""); try { // 创建DocumentBuilderFactory对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 创建DocumentBuilder对象 DocumentBuilder builder = factory.newDocumentBuilder(); // 如果修改了profile,则删除原文件 if (StringUtils.isNotEmpty(orginProfileName) && !orginProfileName.equals(profileName)) { String orignGatewayXmlPath = fsConfDirectory + "/sip_profiles/" + orginProfileName + "/" + gwName + ".xml"; try { Files.delete(Paths.get(orignGatewayXmlPath)); // 删除文件后要kill掉网关 EslMessage eslMessage1 = EslConnectionUtil.sendSyncApiCommand("sofia", "profile " + orginProfileName + " killgw " + gwName); if (null != eslMessage1) { log.info(StringUtils.joinWith("/r/n", eslMessage1.getBodyLines().toArray())); } log.info("文件删除成功!"); } catch (Exception e) { log.error("删除文件失败:{}", orignGatewayXmlPath); log.error(ExceptionUtil.getExceptionMessage(e)); } } // 如果目录不存在则自动创建 File profileDir = new File(fsConfDirectory + "/sip_profiles/" + profileName); if (!profileDir.exists()) { profileDir.mkdirs(); } // 解析XML文件获取Document对象 String gatewayXmlPath = fsConfDirectory + "/sip_profiles/" + profileName + "/" + gwName + ".xml"; File profilefXmlFile = new File(gatewayXmlPath); // 每次都从模板文件里拷贝一份,并覆盖参数值,确保修改是否注册模式时属性正确 try { // 使用Files.copy方法拷贝文件 Files.copy(Paths.get(gwTemplate), Paths.get(gatewayXmlPath), StandardCopyOption.REPLACE_EXISTING); log.info("文件拷贝成功!"); } catch (IOException e) { e.printStackTrace(); log.info("文件拷贝失败!"); } Document document = builder.parse(profilefXmlFile); // gateway元素 Element gateway = (Element)document.getElementsByTagName("gateway").item(0); gateway.setAttribute("name", gwName); // 更新属性值 NodeList nodes = document.getElementsByTagName("param"); for (String attrName: params.keySet()) { String attrValue = params.getString(attrName); // 忽略参数名或者参数值为空的参数 if (StringUtils.isBlank(attrName) || StringUtils.isBlank(attrValue)) { continue; } Boolean newParams = true; // 是否是新增参数 for (int i = 0; i < nodes.getLength(); i++) { if (nodes.item(i) instanceof Element) { Element element = (Element) nodes.item(i); if (attrName.equals(element.getAttribute("name"))) { newParams = false; element.setAttribute("value", attrValue.trim()); } } } if (newParams) { log.info("新增属性:{}", attrName); Element element = document.createElement("param"); element.setAttribute("name", attrName); element.setAttribute("value", attrValue.trim()); gateway.appendChild(element); } } // 将更新后的Document对象写回XML文件 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); DOMSource source = new DOMSource(document); StringWriter writer = new StringWriter(); transformer.transform(source, new StreamResult(writer)); String updatedXML = writer.toString(); // 将updatedXML写入文件 java.nio.file.Files.write(java.nio.file.Paths.get(gatewayXmlPath), updatedXML.getBytes()); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { String certValue = "123"; String fileName = "D:\\liliqiang\\ruoyi\\test\\wss.pem"; try (BufferedWriter bw = new BufferedWriter(new FileWriter(fileName))) { bw.write(certValue); } catch (IOException e) { e.printStackTrace(); } } }