OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
ServicesServerBase.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors, http://opensimulator.org/
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using System;
29 using System.Collections.Generic;
30 using System.IO;
31 using System.Reflection;
32 using System.Threading;
33 using System.Text;
34 using System.Xml;
35 using OpenSim.Framework;
36 using OpenSim.Framework.Console;
37 using OpenSim.Framework.Monitoring;
38 using OpenSim.Framework.Servers;
39 using log4net;
40 using log4net.Config;
41 using log4net.Appender;
42 using log4net.Core;
43 using log4net.Repository;
44 using Nini.Config;
45 
46 namespace OpenSim.Server.Base
47 {
49  {
50  // Logger
51  //
52  private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53 
54  // Command line args
55  //
56  protected string[] m_Arguments;
57 
58  public string ConfigDirectory
59  {
60  get;
61  private set;
62  }
63 
64  // Run flag
65  //
66  private bool m_Running = true;
67 
68  // Handle all the automagical stuff
69  //
70  public ServicesServerBase(string prompt, string[] args) : base()
71  {
72  // Save raw arguments
73  m_Arguments = args;
74 
75  // Read command line
76  ArgvConfigSource argvConfig = new ArgvConfigSource(args);
77 
78  argvConfig.AddSwitch("Startup", "console", "c");
79  argvConfig.AddSwitch("Startup", "logfile", "l");
80  argvConfig.AddSwitch("Startup", "inifile", "i");
81  argvConfig.AddSwitch("Startup", "prompt", "p");
82  argvConfig.AddSwitch("Startup", "logconfig", "g");
83 
84  // Automagically create the ini file name
85  string fileName = "";
86  if (Assembly.GetEntryAssembly() != null)
87  fileName = Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().Location);
88  string iniFile = fileName + ".ini";
89  string logConfig = null;
90 
91  IConfig startupConfig = argvConfig.Configs["Startup"];
92  if (startupConfig != null)
93  {
94  // Check if a file name was given on the command line
95  iniFile = startupConfig.GetString("inifile", iniFile);
96 
97  // Check if a prompt was given on the command line
98  prompt = startupConfig.GetString("prompt", prompt);
99 
100  // Check for a Log4Net config file on the command line
101  logConfig =startupConfig.GetString("logconfig", logConfig);
102  }
103 
104  // Find out of the file name is a URI and remote load it if possible.
105  // Load it as a local file otherwise.
106  Uri configUri;
107 
108  try
109  {
110  if (Uri.TryCreate(iniFile, UriKind.Absolute, out configUri) &&
111  configUri.Scheme == Uri.UriSchemeHttp)
112  {
113  XmlReader r = XmlReader.Create(iniFile);
114  Config = new XmlConfigSource(r);
115  }
116  else
117  {
118  Config = new IniConfigSource(iniFile);
119  }
120  }
121  catch (Exception e)
122  {
123  System.Console.WriteLine("Error reading from config source. {0}", e.Message);
124  Environment.Exit(1);
125  }
126 
127  // Merge OpSys env vars
128  m_log.Info("[CONFIG]: Loading environment variables for Config");
129  Util.MergeEnvironmentToConfig(Config);
130 
131  // Merge the configuration from the command line into the loaded file
132  Config.Merge(argvConfig);
133 
134  Config.ReplaceKeyValues();
135 
136  // Refresh the startupConfig post merge
137  if (Config.Configs["Startup"] != null)
138  {
139  startupConfig = Config.Configs["Startup"];
140  }
141 
142  ConfigDirectory = startupConfig.GetString("ConfigDirectory", ".");
143 
144  prompt = startupConfig.GetString("Prompt", prompt);
145 
146  // Allow derived classes to load config before the console is opened.
147  ReadConfig();
148 
149  // Create main console
150  string consoleType = "local";
151  if (startupConfig != null)
152  consoleType = startupConfig.GetString("console", consoleType);
153 
154  if (consoleType == "basic")
155  {
156  MainConsole.Instance = new CommandConsole(prompt);
157  }
158  else if (consoleType == "rest")
159  {
160  MainConsole.Instance = new RemoteConsole(prompt);
161  ((RemoteConsole)MainConsole.Instance).ReadConfig(Config);
162  }
163  else if (consoleType == "mock")
164  {
165  MainConsole.Instance = new MockConsole();
166  }
167  else if (consoleType == "local")
168  {
169  MainConsole.Instance = new LocalConsole(prompt, startupConfig);
170  }
171 
172  m_console = MainConsole.Instance;
173 
174  if (logConfig != null)
175  {
176  FileInfo cfg = new FileInfo(logConfig);
177  XmlConfigurator.Configure(cfg);
178  }
179  else
180  {
181  XmlConfigurator.Configure();
182  }
183 
184  LogEnvironmentInformation();
185  RegisterCommonAppenders(startupConfig);
186 
187  if (startupConfig.GetString("PIDFile", String.Empty) != String.Empty)
188  {
189  CreatePIDFile(startupConfig.GetString("PIDFile"));
190  }
191 
192  RegisterCommonCommands();
193  RegisterCommonComponents(Config);
194 
195  // Allow derived classes to perform initialization that
196  // needs to be done after the console has opened
197  Initialise();
198  }
199 
200  public bool Running
201  {
202  get { return m_Running; }
203  }
204 
205  public virtual int Run()
206  {
207  Watchdog.Enabled = true;
208  MemoryWatchdog.Enabled = true;
209 
210  while (m_Running)
211  {
212  try
213  {
214  MainConsole.Instance.Prompt();
215  }
216  catch (Exception e)
217  {
218  m_log.ErrorFormat("Command error: {0}", e);
219  }
220  }
221 
222  RemovePIDFile();
223 
224  return 0;
225  }
226 
227  protected override void ShutdownSpecific()
228  {
229  m_Running = false;
230  m_log.Info("[CONSOLE] Quitting");
231 
232  base.ShutdownSpecific();
233  }
234 
235  protected virtual void ReadConfig()
236  {
237  }
238 
239  protected virtual void Initialise()
240  {
241  }
242  }
243 }
static ICommandConsole Instance
Definition: MainConsole.cs:35
This is a Fake console that's used when setting up the Scene in Unit Tests Don't use this except for ...
Definition: MockConsole.cs:41
override void ShutdownSpecific()
Should be overriden and referenced by descendents if they need to perform extra shutdown processing ...
A console that uses cursor control and color
Definition: LocalConsole.cs:44
A console that processes commands internally
ServicesServerBase(string prompt, string[] args)