aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Server/Base/ServerUtils.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Server/Base/ServerUtils.cs')
-rw-r--r--OpenSim/Server/Base/ServerUtils.cs226
1 files changed, 214 insertions, 12 deletions
diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs
index 42c82cf..210a314 100644
--- a/OpenSim/Server/Base/ServerUtils.cs
+++ b/OpenSim/Server/Base/ServerUtils.cs
@@ -33,11 +33,163 @@ using System.Xml.Serialization;
33using System.Text; 33using System.Text;
34using System.Collections.Generic; 34using System.Collections.Generic;
35using log4net; 35using log4net;
36using Nini.Config;
36using OpenSim.Framework; 37using OpenSim.Framework;
37using OpenMetaverse; 38using OpenMetaverse;
39using Mono.Addins;
40using OpenSim.Framework.Servers.HttpServer;
41using OpenSim.Framework.Servers;
38 42
43
44[assembly:AddinRoot("Robust", "0.1")]
39namespace OpenSim.Server.Base 45namespace OpenSim.Server.Base
40{ 46{
47 [TypeExtensionPoint(Path="/Robust/Connector", Name="RobustConnector")]
48 public interface IRobustConnector
49 {
50 string ConfigName
51 {
52 get;
53 }
54
55 bool Enabled
56 {
57 get;
58 }
59
60 string PluginPath
61 {
62 get;
63 set;
64 }
65
66 uint Configure(IConfigSource config);
67 void Initialize(IHttpServer server);
68 void Unload();
69 }
70
71 public class PluginLoader
72 {
73 static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
74
75 public AddinRegistry Registry
76 {
77 get;
78 private set;
79 }
80
81 public IConfigSource Config
82 {
83 get;
84 private set;
85 }
86
87 public PluginLoader(IConfigSource config, string registryPath)
88 {
89 Config = config;
90
91 Registry = new AddinRegistry(registryPath, ".");
92 suppress_console_output_(true);
93 AddinManager.Initialize(registryPath);
94 suppress_console_output_(false);
95 AddinManager.Registry.Update();
96 CommandManager commandmanager = new CommandManager(Registry);
97 AddinManager.AddExtensionNodeHandler("/Robust/Connector", OnExtensionChanged);
98 }
99
100 private static TextWriter prev_console_;
101 // Temporarily masking the errors reported on start
102 // This is caused by a non-managed dll in the ./bin dir
103 // when the registry is initialized. The dll belongs to
104 // libomv, which has a hard-coded path to "." for pinvoke
105 // to load the openjpeg dll
106 //
107 // Will look for a way to fix, but for now this keeps the
108 // confusion to a minimum. this was copied from our region
109 // plugin loader, we have been doing this in there for a long time.
110 //
111 public void suppress_console_output_(bool save)
112 {
113 if (save)
114 {
115 prev_console_ = System.Console.Out;
116 System.Console.SetOut(new StreamWriter(Stream.Null));
117 }
118 else
119 {
120 if (prev_console_ != null)
121 System.Console.SetOut(prev_console_);
122 }
123 }
124
125 private void OnExtensionChanged(object s, ExtensionNodeEventArgs args)
126 {
127 IRobustConnector connector = (IRobustConnector)args.ExtensionObject;
128 Addin a = Registry.GetAddin(args.ExtensionNode.Addin.Id);
129
130 if(a == null)
131 {
132 Registry.Rebuild(null);
133 a = Registry.GetAddin(args.ExtensionNode.Addin.Id);
134 }
135
136 switch(args.Change)
137 {
138 case ExtensionChange.Add:
139 if (a.AddinFile.Contains(Registry.DefaultAddinsFolder))
140 {
141 m_log.InfoFormat("[SERVER UTILS]: Adding {0} from registry", a.Name);
142 connector.PluginPath = System.IO.Path.Combine(Registry.DefaultAddinsFolder,a.Name.Replace(',', '.')); }
143 else
144 {
145 m_log.InfoFormat("[SERVER UTILS]: Adding {0} from ./bin", a.Name);
146 connector.PluginPath = a.AddinFile;
147 }
148 LoadPlugin(connector);
149 break;
150 case ExtensionChange.Remove:
151 m_log.InfoFormat("[SERVER UTILS]: Removing {0}", a.Name);
152 UnloadPlugin(connector);
153 break;
154 }
155 }
156
157 private void LoadPlugin(IRobustConnector connector)
158 {
159 IHttpServer server = null;
160 uint port = connector.Configure(Config);
161
162 if(connector.Enabled)
163 {
164 server = GetServer(connector, port);
165 connector.Initialize(server);
166 }
167 else
168 {
169 m_log.InfoFormat("[SERVER UTILS]: {0} Disabled.", connector.ConfigName);
170 }
171 }
172
173 private void UnloadPlugin(IRobustConnector connector)
174 {
175 m_log.InfoFormat("[SERVER UTILS]: Unloading {0}", connector.ConfigName);
176
177 connector.Unload();
178 }
179
180 private IHttpServer GetServer(IRobustConnector connector, uint port)
181 {
182 IHttpServer server;
183
184 if(port != 0)
185 server = MainServer.GetHttpServer(port);
186 else
187 server = MainServer.Instance;
188
189 return server;
190 }
191 }
192
41 public static class ServerUtils 193 public static class ServerUtils
42 { 194 {
43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 195 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -63,20 +215,30 @@ namespace OpenSim.Server.Base
63 /// <param name="dllName"></param> 215 /// <param name="dllName"></param>
64 /// <param name="args">The arguments which control which constructor is invoked on the plugin</param> 216 /// <param name="args">The arguments which control which constructor is invoked on the plugin</param>
65 /// <returns></returns> 217 /// <returns></returns>
66 public static T LoadPlugin<T>(string dllName, Object[] args) where T:class 218 public static T LoadPlugin<T> (string dllName, Object[] args) where T:class
67 { 219 {
68 // This is good to debug configuration problems 220 // This is good to debug configuration problems
69 //if (dllName == string.Empty) 221 //if (dllName == string.Empty)
70 // Util.PrintCallStack(); 222 // Util.PrintCallStack();
71 223
72 string[] parts = dllName.Split(new char[] {':'});
73
74 dllName = parts[0];
75
76 string className = String.Empty; 224 string className = String.Empty;
77 225
78 if (parts.Length > 1) 226 // The path for a dynamic plugin will contain ":" on Windows
79 className = parts[1]; 227 string[] parts = dllName.Split (new char[] {':'});
228
229 if (parts [0].Length > 1)
230 {
231 dllName = parts [0];
232 if (parts.Length > 1)
233 className = parts[1];
234 }
235 else
236 {
237 // This is Windows - we must replace the ":" in the path
238 dllName = String.Format ("{0}:{1}", parts [0], parts [1]);
239 if (parts.Length > 2)
240 className = parts[2];
241 }
80 242
81 return LoadPlugin<T>(dllName, className, args); 243 return LoadPlugin<T>(dllName, className, args);
82 } 244 }
@@ -118,8 +280,11 @@ namespace OpenSim.Server.Base
118 { 280 {
119 if (!(e is System.MissingMethodException)) 281 if (!(e is System.MissingMethodException))
120 { 282 {
121 m_log.ErrorFormat("Error loading plugin {0} from {1}. Exception: {2}", 283 m_log.ErrorFormat("[SERVER UTILS]: Error loading plugin {0} from {1}. Exception: {2}, {3}",
122 interfaceName, dllName, e.InnerException == null ? e.Message : e.InnerException.Message); 284 interfaceName,
285 dllName,
286 e.InnerException == null ? e.Message : e.InnerException.Message,
287 e.StackTrace);
123 } 288 }
124 return null; 289 return null;
125 } 290 }
@@ -133,14 +298,14 @@ namespace OpenSim.Server.Base
133 } 298 }
134 catch (ReflectionTypeLoadException rtle) 299 catch (ReflectionTypeLoadException rtle)
135 { 300 {
136 m_log.Error(string.Format("Error loading plugin from {0}:\n{1}", dllName, 301 m_log.Error(string.Format("[SERVER UTILS]: Error loading plugin from {0}:\n{1}", dllName,
137 String.Join("\n", Array.ConvertAll(rtle.LoaderExceptions, e => e.ToString()))), 302 String.Join("\n", Array.ConvertAll(rtle.LoaderExceptions, e => e.ToString()))),
138 rtle); 303 rtle);
139 return null; 304 return null;
140 } 305 }
141 catch (Exception e) 306 catch (Exception e)
142 { 307 {
143 m_log.Error(string.Format("Error loading plugin from {0}", dllName), e); 308 m_log.Error(string.Format("[SERVER UTILS]: Error loading plugin from {0}", dllName), e);
144 return null; 309 return null;
145 } 310 }
146 } 311 }
@@ -333,5 +498,42 @@ namespace OpenSim.Server.Base
333 498
334 return ret; 499 return ret;
335 } 500 }
501
502 public static IConfig GetConfig(string configFile, string configName)
503 {
504 IConfig config;
505
506 if (File.Exists(configFile))
507 {
508 IConfigSource configsource = new IniConfigSource(configFile);
509 config = configsource.Configs[configName];
510 }
511 else
512 config = null;
513
514 return config;
515 }
516
517 public static IConfigSource LoadInitialConfig(string url)
518 {
519 IConfigSource source = new XmlConfigSource();
520 m_log.InfoFormat("[SERVER UTILS]: {0} is a http:// URI, fetching ...", url);
521
522 // The ini file path is a http URI
523 // Try to read it
524 try
525 {
526 XmlReader r = XmlReader.Create(url);
527 IConfigSource cs = new XmlConfigSource(r);
528 source.Merge(cs);
529 }
530 catch (Exception e)
531 {
532 m_log.FatalFormat("[SERVER UTILS]: Exception reading config from URI {0}\n" + e.ToString(), url);
533 Environment.Exit(1);
534 }
535
536 return source;
537 }
336 } 538 }
337} 539}