我们在部署消息中间件的时候,可能需要对配置文件进行一些修改,正常情况下我们会直接到config路径下手动修改,但是这种做法并不适用于一键安装部署服务。所以我们需要实现一个接口供运营人员方便操作、修改配置信息。我实现了两个版本的修改配置文件的接口(Java和C#),这里先分享C#版的实现代码。
1. 配置修改XML(ActiveMQ的通信端口和服务器控制台端口)
public class ReadAndWriteXML
{
#region 属性
/// <summary>
/// 存放xml内容的文件夹下的文件名
/// </summary>
private string JettyXML = "jetty.xml";
private string ActiveMQXML = "activemq.xml";
#endregion
#region 写入xml
/// <summary>
///
/// </summary>
/// <param name="file">文件名</param>
/// <param name="key"></param>
/// <param name="value"></param>
public int WriteDoc(string path, string file, string value)
{
string SavePath = Path.Combine(path, "config");
//判断是否存在文件夹
var DirectoryPath = Path.GetDirectoryName(SavePath); //获取文件夹所在的路径
if (!Directory.Exists(SavePath))
{
return 3; //文件夹不存在返回3
}
XmlDocument doc = new XmlDocument();
try
{
if (File.Exists(Path.Combine(SavePath, file)))
{
//如果文件存在 加载XML
doc.Load(Path.Combine(SavePath, file));
//分支判断是jetty还是activemq
if (file.Equals(JettyXML))
{
XmlNode xmlnode = doc.SelectSingleNode(@"//bean[@id='jettyPort']");
xmlnode.LastChild.Attributes["value"].Value = value;
}
if (file.Equals("ActiveMQXML"))
{
XmlNode xmlnode = doc.SelectSingleNode("/beans/broker/transportConnectors/transportConnector[@name='openwire']");
xmlnode.Attributes["uri"].Value = "tcp://0.0.0.0:" + value + "?maximumConnections=1000&wireFormat.maxFrameSize=104857600";
}
doc.Save(file);
}
return 0;
}
catch (Exception e)
{
return 10;
}
}
}
2. 配置修改properties文件(ActiveMQ的管理员信息)
/// <summary>
///ReadProperties 的摘要说明
/// </summary>
public class ReadProperties : System.Collections.Hashtable
{
private ArrayList list = new ArrayList();
public ArrayList List
{
get { return list; }
set { list = value; }
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="fileName">要读写的properties文件名</param>
public ReadProperties(string path)
{
string filepath = Path.Combine(path, "config/users.properties");
Load(filepath);
}
/// <summary>
/// 重写父类的方法,key值相当于用户ID,Value值相当于Password
/// </summary>
/// <param name="key">键</param>
/// <param name="value">值</param>
public override void Add(object key, object value)
{
base.Add(key, value);
list.Add(key);
}
public override ICollection Keys
{
get
{
return list;
}
}
/// <summary>
/// 加载文件
/// </summary>
/// <param name="filePath">文件路径</param>
public void Load(string filePath)
{
char[] convertBuf = new char[1024];
int limit;
int keyLen;
int valueStart;
char c;
string bufLine = string.Empty;
bool hasSep;
bool precedingBackslash;
using (StreamReader sr = new StreamReader(filePath))
{
while (sr.Peek() >= 0)
{
bufLine = sr.ReadLine();
limit = bufLine.Length;
keyLen = 0;
valueStart = limit;
hasSep = false;
precedingBackslash = false;
if (bufLine.StartsWith("#"))
keyLen = bufLine.Length;
while (keyLen < limit)
{
c = bufLine[keyLen];
if ((c == '=' || c == ':') & !precedingBackslash)
{
valueStart = keyLen + 1;
hasSep = true;
break;
}
else if ((c == ' ' || c == '\t' || c == '\f') & !precedingBackslash)
{
valueStart = keyLen + 1;
break;
}
if (c == '\\')
{
precedingBackslash = !precedingBackslash;
}
else
{
precedingBackslash = false;
}
keyLen++;
}
while (valueStart < limit)
{
c = bufLine[valueStart];
if (c != ' ' && c != '\t' && c != '\f')
{
if (!hasSep && (c == '=' || c == ':'))
{
hasSep = true;
}
else
{
break;
}
}
valueStart++;
}
string key = bufLine.Substring(0, keyLen);
string values = bufLine.Substring(valueStart, limit - valueStart);
if (key == "")
key += "#";
while (key.StartsWith("#") & this.Contains(key))
{
key += "#";
}
this.Add(key, values);
}
}
}
/// <summary>
/// 保存文件
/// </summary>
/// <param name="filePath">要保存的文件的路径</param>
public void save(string filePath)
{
if (File.Exists(filePath))
{
File.Delete(filePath);
}
FileStream fileStream = File.Create(filePath);
StreamWriter sw = new StreamWriter(fileStream);
foreach (object item in list)
{
String key = (String)item;
String val = (String)this[key];
if (key.StartsWith("#"))
{
if (val == "")
{
sw.WriteLine(key);
}
else
{
sw.WriteLine(val);
}
}
else
{
sw.WriteLine(key + "=" + val);
}
}
sw.Close();
fileStream.Close();
}
}
调用的时候我们先调用构造方法实例化,然后调用Add方法即可。