Remove the AssetInventory server from core. It has fallen behind both

upstream and the reference implementation to the point where it is no
longer usable. It has no known users, and sinnce it doesn't work anymore,
it is safe to assume that no one has used it in a long time.
arthursv
Melanie 2009-08-20 21:45:49 +01:00
parent 297393f349
commit b23160a871
24 changed files with 0 additions and 5829 deletions

View File

@ -1,98 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.IO;
using System.Reflection;
using OpenSim.Framework;
using log4net;
using Nini.Config;
namespace OpenSim.Grid.AssetInventoryServer
{
public static class AssetInventoryConfig
{
public const string CONFIG_FILE = "AssetInventoryServer.ini";
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public static IConfigSource LoadConfig()
{
IConfigSource configSource = new IniConfigSource();
configSource.AddConfig("Startup");
return LoadConfig(configSource);
}
public static IConfigSource LoadConfig(IConfigSource source)
{
string iniFileName = source.Configs["Startup"].GetString("inifile", CONFIG_FILE);
string iniFilePath = Path.Combine(Util.configDir(), iniFileName);
source.Merge(DefaultConfig());
if (!File.Exists(iniFilePath))
{
m_log.FatalFormat("[CONFIG]: File {0} not found, could not load any configuration.", iniFilePath);
m_log.FatalFormat("[CONFIG]: Did you copy the AssetInventoryServer.ini.example file to AssetInventoryServer.ini?");
Environment.Exit(1);
}
source.Merge(new IniConfigSource(iniFilePath));
return source;
}
private static IConfigSource DefaultConfig()
{
IConfigSource result = new IniConfigSource();
{
IConfig config = result.AddConfig("Config");
config.Set("listen_port", 8003);
config.Set("assetset_location", String.Format(".{0}assets{0}AssetSets.xml", Path.DirectorySeparatorChar));
}
{
IConfig config = result.AddConfig("Plugins");
config.Set("asset_storage_provider", "OpenSimAssetStorage");
config.Set("inventory_storage_provider", "OpenSimInventoryStorage");
config.Set("authentication_provider", "NullAuthentication");
config.Set("authorization_provider", "AuthorizeAll");
config.Set("metrics_provider", "NullMetrics");
config.Set("frontends", "ReferenceFrontend,OpenSimAssetFrontend,OpenSimInventoryFrontend,BrowseFrontend");
}
{
IConfig config = result.AddConfig("OpenSim");
config.Set("asset_database_provider", "OpenSim.Data.MySQL.dll");
config.Set("inventory_database_provider", "OpenSim.Data.MySQL.dll");
config.Set("asset_database_connect", String.Empty);
config.Set("inventory_database_connect", String.Empty);
}
return result;
}
}
}

View File

@ -1,216 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using OpenSim.Framework;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Framework.Console;
using OpenSim.Framework.AssetLoader.Filesystem;
using Nini.Config;
using log4net;
namespace OpenSim.Grid.AssetInventoryServer
{
public class AssetInventoryServer : BaseOpenSimServer
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public IConfigSource ConfigFile;
public IAssetStorageProvider StorageProvider;
public IInventoryStorageProvider InventoryProvider;
public IAuthenticationProvider AuthenticationProvider;
public IAuthorizationProvider AuthorizationProvider;
public IMetricsProvider MetricsProvider;
private List<IAssetInventoryServerPlugin> m_frontends = new List<IAssetInventoryServerPlugin>();
private List<IAssetInventoryServerPlugin> m_backends = new List<IAssetInventoryServerPlugin>();
public AssetInventoryServer(IConfigSource config)
{
ConfigFile = config;
m_console = new LocalConsole("AssetInventory");
MainConsole.Instance = m_console;
}
public bool Start()
{
Startup();
m_log.Info("[ASSETINVENTORY]: Starting AssetInventory Server");
try
{
ConfigFile = AssetInventoryConfig.LoadConfig(ConfigFile);
}
catch (Exception)
{
m_log.Error("[ASSETINVENTORY]: Failed to load the config.");
return false;
}
StorageProvider = LoadAssetInventoryServerPlugin("/OpenSim/AssetInventoryServer/AssetStorageProvider",
"asset_storage_provider", false) as IAssetStorageProvider;
m_backends.Add(StorageProvider);
InventoryProvider = LoadAssetInventoryServerPlugin("/OpenSim/AssetInventoryServer/InventoryStorageProvider",
"inventory_storage_provider", false) as IInventoryStorageProvider;
m_backends.Add(InventoryProvider);
MetricsProvider = LoadAssetInventoryServerPlugin("/OpenSim/AssetInventoryServer/MetricsProvider",
"metrics_provider", false) as IMetricsProvider;
m_backends.Add(MetricsProvider);
try
{
InitHttpServer((uint) ConfigFile.Configs["Config"].GetInt("listen_port"));
}
catch (Exception ex)
{
m_log.Error("[ASSETINVENTORY]: Initializing the HTTP server failed, shutting down: " + ex.Message);
Shutdown();
return false;
}
LoadDefaultAssets();
AuthenticationProvider = LoadAssetInventoryServerPlugin("/OpenSim/AssetInventoryServer/AuthenticationProvider",
"authentication_provider", false) as IAuthenticationProvider;
m_backends.Add(AuthenticationProvider);
AuthorizationProvider = LoadAssetInventoryServerPlugin("/OpenSim/AssetInventoryServer/AuthorizationProvider",
"authorization_provider", false) as IAuthorizationProvider;
m_backends.Add(AuthorizationProvider);
m_frontends.AddRange(LoadAssetInventoryServerPlugins("/OpenSim/AssetInventoryServer/Frontend", "frontends"));
// Inform the user if we don't have any frontends at this point.
if (m_frontends.Count == 0)
m_log.Info("[ASSETINVENTORY]: Starting with no frontends loaded, which isn't extremely useful. Did you set the 'frontends' configuration parameter?");
return true;
}
public void Work()
{
m_console.Output("Enter help for a list of commands");
while (true)
{
m_console.Prompt();
}
}
public override void ShutdownSpecific()
{
foreach (IAssetInventoryServerPlugin plugin in m_frontends)
{
m_log.Debug("[ASSETINVENTORY]: Disposing plugin " + plugin.Name);
try { plugin.Dispose(); }
catch (Exception ex)
{ m_log.ErrorFormat("[ASSETINVENTORY]: Failure shutting down plugin {0}: {1}", plugin.Name, ex.Message); }
}
foreach (IAssetInventoryServerPlugin plugin in m_backends)
{
m_log.Debug("[ASSETINVENTORY]: Disposing plugin " + plugin.Name);
try { plugin.Dispose(); }
catch (Exception ex)
{ m_log.ErrorFormat("[ASSETINVENTORY]: Failure shutting down plugin {0}: {1}", plugin.Name, ex.Message); }
}
if (HttpServer != null)
HttpServer.Stop();
}
void InitHttpServer(uint port)
{
m_httpServer = new BaseHttpServer(port);
m_httpServer.Start();
m_log.Info("[ASSETINVENTORY]: AssetInventory server is listening on port " + port);
}
private IAssetInventoryServerPlugin LoadAssetInventoryServerPlugin(string addinPath, string configParam, bool optional)
{
IAssetInventoryServerPlugin result = null;
List<IAssetInventoryServerPlugin> plugins = LoadAssetInventoryServerPlugins(addinPath, configParam);
if (plugins.Count == 1)
{
result = plugins[0];
}
else if (plugins.Count > 1)
{
m_log.ErrorFormat("[ASSETINVENTORY]: Only 1 plugin expected for extension point '{0}', {1} plugins loaded. Check the '{2}' parameter in the config file.",
addinPath, plugins.Count, configParam);
Shutdown();
Environment.Exit(0);
}
else if (!optional)
{
m_log.ErrorFormat("[ASSETINVENTORY]: The extension point '{0}' is not optional. Check the '{1}' parameter in the config file.", addinPath, configParam);
Shutdown();
Environment.Exit(0);
}
return result;
}
private List<IAssetInventoryServerPlugin> LoadAssetInventoryServerPlugins(string addinPath, string configParam)
{
PluginLoader<IAssetInventoryServerPlugin> loader = new PluginLoader<IAssetInventoryServerPlugin>(new AssetInventoryServerPluginInitialiser(this));
loader.Add(addinPath, new PluginIdFilter(ConfigFile.Configs["Plugins"].GetString(configParam)));
try
{
loader.Load();
}
catch (PluginNotInitialisedException e)
{
m_log.ErrorFormat("[ASSETINVENTORY]: Error initialising plugin '{0}' for extension point '{1}'.", e.Message, addinPath);
Shutdown();
Environment.Exit(0);
}
return loader.Plugins;
}
private void LoadDefaultAssets()
{
AssetLoaderFileSystem assetLoader = new AssetLoaderFileSystem();
assetLoader.ForEachDefaultXmlAsset(ConfigFile.Configs["Config"].GetString("assetset_location"), StoreAsset);
}
private void StoreAsset(AssetBase asset)
{
StorageProvider.TryCreateAsset(asset);
}
}
}

View File

@ -1,143 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using OpenMetaverse;
using OpenSim.Framework;
namespace OpenSim.Grid.AssetInventoryServer
{
/// <summary>
/// Response from a call to a backend provider
/// </summary>
public enum BackendResponse
{
/// <summary>The call succeeded</summary>
Success,
/// <summary>The resource requested was not found</summary>
NotFound,
/// <summary>A server failure prevented the call from
/// completing</summary>
Failure
}
public class AssetInventoryServerPluginInitialiser : PluginInitialiserBase
{
private AssetInventoryServer server;
public AssetInventoryServerPluginInitialiser(AssetInventoryServer server)
{
this.server = server;
}
public override void Initialise(IPlugin plugin)
{
IAssetInventoryServerPlugin p = plugin as IAssetInventoryServerPlugin;
p.Initialise (server);
}
}
#region Interfaces
public interface IAssetInventoryServerPlugin : IPlugin
{
void Initialise(AssetInventoryServer server);
}
public interface IAssetStorageProvider : IAssetInventoryServerPlugin
{
BackendResponse TryFetchMetadata(UUID assetID, out AssetMetadata metadata);
BackendResponse TryFetchData(UUID assetID, out byte[] assetData);
BackendResponse TryFetchDataMetadata(UUID assetID, out AssetBase asset);
BackendResponse TryCreateAsset(AssetBase asset);
BackendResponse TryCreateAsset(AssetBase asset, out UUID assetID);
int ForEach(Action<AssetMetadata> action, int start, int count);
}
public interface IInventoryStorageProvider : IAssetInventoryServerPlugin
{
BackendResponse TryFetchItem(Uri owner, UUID itemID, out InventoryItemBase item);
BackendResponse TryFetchFolder(Uri owner, UUID folderID, out InventoryFolderWithChildren folder);
BackendResponse TryFetchFolderContents(Uri owner, UUID folderID, out InventoryCollection contents);
BackendResponse TryFetchFolderList(Uri owner, out List<InventoryFolderWithChildren> folders);
BackendResponse TryFetchInventory(Uri owner, out InventoryCollection inventory);
BackendResponse TryFetchActiveGestures(Uri owner, out List<InventoryItemBase> gestures);
BackendResponse TryCreateItem(Uri owner, InventoryItemBase item);
BackendResponse TryCreateFolder(Uri owner, InventoryFolderWithChildren folder);
BackendResponse TryCreateInventory(Uri owner, InventoryFolderWithChildren rootFolder);
BackendResponse TryDeleteItem(Uri owner, UUID itemID);
BackendResponse TryDeleteFolder(Uri owner, UUID folderID);
BackendResponse TryPurgeFolder(Uri owner, UUID folderID);
}
public interface IAuthenticationProvider : IAssetInventoryServerPlugin
{
void AddIdentifier(UUID authToken, Uri identifier);
bool RemoveIdentifier(UUID authToken);
bool TryGetIdentifier(UUID authToken, out Uri identifier);
}
public interface IAuthorizationProvider : IAssetInventoryServerPlugin
{
bool IsMetadataAuthorized(UUID authToken, UUID assetID);
/// <summary>
/// Authorizes access to the data for an asset. Access to asset data
/// also implies access to the metadata for that asset
/// </summary>
/// <param name="authToken">Authentication token to check for access</param>
/// <param name="assetID">ID of the requested asset</param>
/// <returns>True if access is granted, otherwise false</returns>
bool IsDataAuthorized(UUID authToken, UUID assetID);
bool IsCreateAuthorized(UUID authToken);
bool IsInventoryReadAuthorized(UUID authToken, Uri owner);
bool IsInventoryWriteAuthorized(UUID authToken, Uri owner);
}
public interface IMetricsProvider : IAssetInventoryServerPlugin
{
void LogAssetMetadataFetch(string extension, BackendResponse response, UUID assetID, DateTime time);
void LogAssetDataFetch(string extension, BackendResponse response, UUID assetID, int dataSize, DateTime time);
void LogAssetCreate(string extension, BackendResponse response, UUID assetID, int dataSize, DateTime time);
void LogInventoryFetch(string extension, BackendResponse response, Uri owner, UUID objID, bool folder, DateTime time);
void LogInventoryFetchFolderContents(string extension, BackendResponse response, Uri owner, UUID folderID, DateTime time);
void LogInventoryFetchFolderList(string extension, BackendResponse response, Uri owner, DateTime time);
void LogInventoryFetchInventory(string extension, BackendResponse response, Uri owner, DateTime time);
void LogInventoryFetchActiveGestures(string extension, BackendResponse response, Uri owner, DateTime time);
void LogInventoryCreate(string extension, BackendResponse response, Uri owner, bool folder, DateTime time);
void LogInventoryCreateInventory(string extension, BackendResponse response, DateTime time);
void LogInventoryDelete(string extension, BackendResponse response, Uri owner, UUID objID, bool folder, DateTime time);
void LogInventoryPurgeFolder(string extension, BackendResponse response, Uri owner, UUID folderID, DateTime time);
}
#endregion Interfaces
}

View File

@ -1,139 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using OpenMetaverse;
using OpenSim.Framework;
namespace OpenSim.Grid.AssetInventoryServer
{
//public class InventoryBase
//{
//}
//public class InventoryFolder : InventoryBase
//{
// public string Name;
// public UUID Owner;
// public UUID ParentID;
// public UUID ID;
// public short Type;
// public ushort Version;
// [NonSerialized]
// public Dictionary<UUID, InventoryBase> Children = new Dictionary<UUID, InventoryBase>();
// public InventoryFolder()
// {
// }
// public InventoryFolder(string name, UUID ownerID, UUID parentID, short assetType)
// {
// ID = UUID.Random();
// Name = name;
// Owner = ownerID;
// ParentID = parentID;
// Type = assetType;
// Version = 1;
// }
// public override string ToString()
// {
// return String.Format("{0} ({1})", Name, ID);
// }
//}
//public class InventoryItem : InventoryBase
//{
// public UUID ID;
// public int InvType;
// public UUID Folder;
// public UUID Owner;
// public UUID Creator;
// public string Name;
// public string Description;
// public uint NextPermissions;
// public uint CurrentPermissions;
// public uint BasePermissions;
// public uint EveryOnePermissions;
// public uint GroupPermissions;
// public int AssetType;
// public UUID AssetID;
// public UUID GroupID;
// public bool GroupOwned;
// public int SalePrice;
// public byte SaleType;
// public uint Flags;
// public int CreationDate;
// public override string ToString()
// {
// return String.Format("{0} ({1})", Name, ID);
// }
//}
public class InventoryFolderWithChildren : InventoryFolderBase
{
public InventoryFolderWithChildren()
{
}
public InventoryFolderWithChildren(InventoryFolderBase folder)
{
// from InventoryNodeBase
Name = folder.Name;
ID = folder.ID;
Owner = folder.Owner;
// from InventoryFolderBase
ParentID = folder.ParentID;
Type = folder.Type;
Version = folder.Version;
}
public InventoryFolderWithChildren(string name, UUID ownerID, UUID parentID, short assetType)
{
ID = UUID.Random();
Name = name;
Owner = ownerID;
ParentID = parentID;
Type = assetType;
Version = 1;
}
[NonSerialized]
public Dictionary<UUID, InventoryNodeBase> Children = new Dictionary<UUID, InventoryNodeBase>();
}
public class InventoryCollection
{
public Dictionary<UUID, InventoryFolderWithChildren> Folders;
public Dictionary<UUID, InventoryItemBase> Items;
public UUID UserID;
}
}

View File

@ -1,62 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using Nini.Config;
using log4net.Config;
using log4net;
using System.Reflection;
namespace OpenSim.Grid.AssetInventoryServer
{
class MainEntry
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
static void Main(string[] args)
{
XmlConfigurator.Configure();
ArgvConfigSource configSource = new ArgvConfigSource(args);
configSource.AddSwitch("Startup", "inifile");
AssetInventoryServer server = new AssetInventoryServer(configSource);
if (server.Start())
{
Console.CancelKeyPress +=
delegate(object sender, ConsoleCancelEventArgs e)
{
m_log.Info("AssetInventory server is shutting down...");
server.Shutdown();
Environment.Exit(0);
};
server.Work();
}
}
}
}

View File

@ -1,105 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Reflection;
using OpenMetaverse;
using OpenSim.Framework;
using log4net;
namespace OpenSim.Grid.AssetInventoryServer.Plugins
{
public class AuthorizeAllPlugin : IAuthorizationProvider
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
//private AssetInventoryServer m_server;
public AuthorizeAllPlugin()
{
}
#region IPlugin implementation
public void Initialise(AssetInventoryServer server)
{
//m_server = server;
m_log.Info("[AUTHORIZEALL]: Authorize All loaded.");
}
/// <summary>
/// <para>Initialises asset interface</para>
/// </summary>
public void Initialise()
{
m_log.InfoFormat("[AUTHORIZEALL]: {0} cannot be default-initialized!", Name);
throw new PluginNotInitialisedException(Name);
}
public void Dispose()
{
}
public string Version
{
// TODO: this should be something meaningful and not hardcoded?
get { return "0.1"; }
}
public string Name
{
get { return "AuthorizeAll"; }
}
#endregion IPlugin implementation
public bool IsMetadataAuthorized(UUID authToken, UUID assetID)
{
return true;
}
public bool IsDataAuthorized(UUID authToken, UUID assetID)
{
return true;
}
public bool IsCreateAuthorized(UUID authToken)
{
return true;
}
public bool IsInventoryReadAuthorized(UUID authToken, Uri owner)
{
return true;
}
public bool IsInventoryWriteAuthorized(UUID authToken, Uri owner)
{
return true;
}
}
}

View File

@ -1,173 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.IO;
using System.Reflection;
using System.Collections.Specialized;
using System.Net;
using System.Text;
using System.Web;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using log4net;
namespace OpenSim.Grid.AssetInventoryServer.Plugins
{
public class BrowseFrontendPlugin : IAssetInventoryServerPlugin
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private AssetInventoryServer m_server;
public BrowseFrontendPlugin()
{
}
#region IPlugin implementation
public void Initialise(AssetInventoryServer server)
{
m_server = server;
// Request for / or /?...
m_server.HttpServer.AddStreamHandler(new BrowseRequestHandler(server));
m_log.Info("[BROWSEFRONTEND]: Browser Frontend loaded.");
}
/// <summary>
/// <para>Initialises asset interface</para>
/// </summary>
public void Initialise()
{
m_log.InfoFormat("[BROWSEFRONTEND]: {0} cannot be default-initialized!", Name);
throw new PluginNotInitialisedException(Name);
}
public void Dispose()
{
}
public string Version
{
// TODO: this should be something meaningful and not hardcoded?
get { return "0.1"; }
}
public string Name
{
get { return "BrowseFrontend"; }
}
#endregion IPlugin implementation
public class BrowseRequestHandler : BaseStreamHandler
{
AssetInventoryServer m_server;
//public BrowseRequestHandler(AssetInventoryServer server) : base("GET", "(^/$|(^/\?.*)")
public BrowseRequestHandler(AssetInventoryServer server) : base("GET", "/")
{
m_server = server;
}
public override string ContentType
{
get { return "text/html"; }
}
#region IStreamedRequestHandler implementation
public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
const int ASSETS_PER_PAGE = 25;
const string HEADER = "<html><head><title>Asset Server</title></head><body>";
const string TABLE_HEADER =
"<table><tr><th>Name</th><th>Description</th><th>Type</th><th>ID</th><th>Temporary</th><th>SHA-1</th></tr>";
const string TABLE_FOOTER = "</table>";
const string FOOTER = "</body></html>";
UUID authToken = Utils.GetAuthToken(httpRequest);
StringBuilder html = new StringBuilder();
int start = 0;
uint page = 0;
if (!String.IsNullOrEmpty(httpRequest.Url.Query))
{
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
if (!String.IsNullOrEmpty(query["page"]) && UInt32.TryParse(query["page"], out page))
start = (int)page * ASSETS_PER_PAGE;
}
html.AppendLine(HEADER);
html.AppendLine("<p>");
if (page > 0)
html.AppendFormat("<a href=\"{0}?page={1}\">&lt; Previous Page</a> | ", httpRequest.RawUrl, page - 1);
html.AppendFormat("<a href=\"{0}?page={1}\">Next Page &gt;</a>", httpRequest.RawUrl, page + 1);
html.AppendLine("</p>");
html.AppendLine(TABLE_HEADER);
m_server.StorageProvider.ForEach(
delegate(AssetMetadata data)
{
if (m_server.AuthorizationProvider.IsMetadataAuthorized(authToken, data.FullID))
{
html.AppendLine(String.Format(
"<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td><td>{5}</td></tr>",
data.Name, data.Description, data.ContentType, data.ID, data.Temporary,
BitConverter.ToString(data.SHA1).Replace("-", String.Empty)));
}
else
{
html.AppendLine(String.Format(
"<tr><td>[Protected Asset]</td><td>&nbsp;</td><td>&nbsp;</td><td>{0}</td><td>{1}</td><td>&nbsp;</td></tr>",
data.ID, data.Temporary));
}
}, start, ASSETS_PER_PAGE
);
html.AppendLine(TABLE_FOOTER);
html.AppendLine(FOOTER);
byte[] responseData = System.Text.Encoding.UTF8.GetBytes(html.ToString());
httpResponse.StatusCode = (int) HttpStatusCode.OK;
//httpResponse.Body.Write(responseData, 0, responseData.Length);
//httpResponse.Body.Flush();
return responseData;
}
#endregion IStreamedRequestHandler implementation
}
}
}

View File

@ -1,211 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Net;
using System.IO;
using System.IO.Compression;
using System.Xml;
using System.Reflection;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Serialization;
using OpenSim.Framework.Serialization.External;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using log4net;
namespace OpenSim.Grid.AssetInventoryServer.Plugins
{
public class InventoryArchivePlugin : IAssetInventoryServerPlugin
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private AssetInventoryServer m_server;
public InventoryArchivePlugin()
{
}
#region IPlugin implementation
public void Initialise(AssetInventoryServer server)
{
m_server = server;
m_server.HttpServer.AddStreamHandler(new GetInventoryArchive(server));
m_log.Info("[INVENTORYARCHIVE]: Inventory Archive loaded.");
}
/// <summary>
/// <para>Initialises asset interface</para>
/// </summary>
public void Initialise()
{
m_log.InfoFormat("[INVENTORYARCHIVE]: {0} cannot be default-initialized!", Name);
throw new PluginNotInitialisedException(Name);
}
public void Dispose()
{
}
public string Version
{
// TODO: this should be something meaningful and not hardcoded?
get { return "0.1"; }
}
public string Name
{
get { return "InventoryArchive"; }
}
#endregion IPlugin implementation
public class GetInventoryArchive : BaseStreamHandler
{
AssetInventoryServer m_server;
//public GetInventoryArchive(AssetInventoryServer server) : base("GET", @"^/inventoryarchive/")
public GetInventoryArchive(AssetInventoryServer server) : base("GET", "/inventoryarchive")
{
m_server = server;
}
public override string ContentType
{
get { return "application/x-compressed"; }
}
public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
byte[] buffer = new byte[] {};
UUID ownerID;
// Split the URL up to get the asset ID out
string[] rawUrl = httpRequest.Url.PathAndQuery.Split('/');
if (rawUrl.Length >= 3 && rawUrl[2].Length >= 36 && UUID.TryParse(rawUrl[2].Substring(0, 36), out ownerID))
{
Uri owner = Utils.GetOpenSimUri(ownerID);
InventoryCollection inventory;
BackendResponse storageResponse = m_server.InventoryProvider.TryFetchInventory(owner, out inventory);
if (storageResponse == BackendResponse.Success)
{
m_log.DebugFormat("[INVENTORYARCHIVE]: Archiving inventory for user UUID {0}", ownerID);
buffer = ArchiveInventoryCollection(inventory);
httpResponse.StatusCode = (int) HttpStatusCode.OK;
}
else
{
httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError;
}
}
else
{
m_log.Warn("[INVENTORYARCHIVE]: Unrecognized inventory archive request: " + httpRequest.Url.PathAndQuery);
}
return buffer;
}
}
private static byte[] ArchiveInventoryCollection(InventoryCollection inventory)
{
byte[] buffer = new byte[] {};
// Fill in each folder's Children dictionary.
InventoryFolderWithChildren rootFolder = BuildInventoryHierarchy(ref inventory);
// TODO: It's probably a bad idea to tar to memory for large
// inventories.
MemoryStream ms = new MemoryStream();
GZipStream gzs = new GZipStream(ms, CompressionMode.Compress, true);
TarArchiveWriter archive = new TarArchiveWriter(gzs);
WriteInventoryFolderToArchive(archive, rootFolder, ArchiveConstants.INVENTORY_PATH);
archive.Close();
ms.Seek(0, SeekOrigin.Begin);
buffer = ms.GetBuffer();
Array.Resize<byte>(ref buffer, (int) ms.Length);
ms.Close();
return buffer;
}
private static InventoryFolderWithChildren BuildInventoryHierarchy(ref InventoryCollection inventory)
{
m_log.DebugFormat("[INVENTORYARCHIVE]: Building inventory hierarchy");
InventoryFolderWithChildren rootFolder = null;
foreach (InventoryFolderWithChildren parentFolder in inventory.Folders.Values)
{
// Grab the root folder, it has no parents.
if (UUID.Zero == parentFolder.ParentID) rootFolder = parentFolder;
foreach (InventoryFolderWithChildren folder in inventory.Folders.Values)
if (parentFolder.ID == folder.ParentID)
parentFolder.Children.Add(folder.ID, folder);
foreach (InventoryItemBase item in inventory.Items.Values)
if (parentFolder.ID == item.Folder)
parentFolder.Children.Add(item.ID, item);
}
return rootFolder;
}
private static void WriteInventoryFolderToArchive(
TarArchiveWriter archive, InventoryFolderWithChildren folder, string path)
{
path += string.Format("{0}{1}{2}/", folder.Name, ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR, folder.ID);
archive.WriteDir(path);
foreach (InventoryNodeBase inventoryNode in folder.Children.Values)
{
if (inventoryNode is InventoryFolderWithChildren)
{
WriteInventoryFolderToArchive(archive, (InventoryFolderWithChildren) inventoryNode, path);
}
else if (inventoryNode is InventoryItemBase)
{
WriteInventoryItemToArchive(archive, (InventoryItemBase) inventoryNode, path);
}
}
}
private static void WriteInventoryItemToArchive(TarArchiveWriter archive, InventoryItemBase item, string path)
{
string filename = string.Format("{0}{1}_{2}.xml", path, item.Name, item.ID);
string serialization = UserInventoryItemSerializer.Serialize(item);
archive.WriteFile(filename, serialization);
//m_assetGatherer.GatherAssetUuids(item.AssetID, (AssetType) item.AssetType, assetUuids);
}
}
}

View File

@ -1,95 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Reflection;
using OpenMetaverse;
using OpenSim.Framework;
using log4net;
namespace OpenSim.Grid.AssetInventoryServer.Plugins
{
public class NullAuthenticationPlugin : IAuthenticationProvider
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
//private AssetInventoryServer m_server;
public NullAuthenticationPlugin()
{
}
#region IPlugin implementation
public void Initialise(AssetInventoryServer server)
{
//m_server = server;
m_log.Info("[NULLAUTHENTICATION]: Null Authentication loaded.");
}
/// <summary>
/// <para>Initialises asset interface</para>
/// </summary>
public void Initialise()
{
m_log.InfoFormat("[NULLAUTHENTICATION]: {0} cannot be default-initialized!", Name);
throw new PluginNotInitialisedException(Name);
}
public void Dispose()
{
}
public string Version
{
// TODO: this should be something meaningful and not hardcoded?
get { return "0.1"; }
}
public string Name
{
get { return "NullAuthentication"; }
}
#endregion IPlugin implementation
public void AddIdentifier(UUID authToken, Uri identifier)
{
}
public bool RemoveIdentifier(UUID authToken)
{
return true;
}
public bool TryGetIdentifier(UUID authToken, out Uri identifier)
{
identifier = null;
return true;
}
}
}

View File

@ -1,151 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Reflection;
using OpenMetaverse;
using log4net;
namespace OpenSim.Grid.AssetInventoryServer.Plugins
{
public class NullMetricsPlugin : IMetricsProvider
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
//private AssetInventoryServer m_server;
public NullMetricsPlugin()
{
}
#region IMetricsProvider implementation
public void LogAssetMetadataFetch(string extension, BackendResponse response, UUID assetID, DateTime time)
{
m_log.DebugFormat("[{0}]: AssetMetadataFetch(): AssetID: {1}, Response: {2}", extension, assetID, response);
}
public void LogAssetDataFetch(string extension, BackendResponse response, UUID assetID, int dataSize, DateTime time)
{
m_log.DebugFormat("[{0}]: AssetDataFetch(): AssetID: {1}, DataSize: {2}, Response: {3}", extension, assetID,
dataSize, response);
}
public void LogAssetCreate(string extension, BackendResponse response, UUID assetID, int dataSize, DateTime time)
{
m_log.DebugFormat("[{0}]: AssetCreate(): AssetID: {1}, DataSize: {2}, Response: {3}", extension, assetID,
dataSize, response);
}
public void LogInventoryFetch(string extension, BackendResponse response, Uri owner, UUID objID, bool folder, DateTime time)
{
m_log.DebugFormat("[{0}]: InventoryFetch(): ObjID: {1}, Folder: {2}, OwnerID: {3}, Response: {4}", extension,
objID, folder, owner, response);
}
public void LogInventoryFetchFolderContents(string extension, BackendResponse response, Uri owner, UUID folderID, DateTime time)
{
m_log.DebugFormat("[{0}]: InventoryFetchFolderContents(): FolderID: {1}, OwnerID: {2}, Response: {3}", extension,
folderID, owner, response);
}
public void LogInventoryFetchFolderList(string extension, BackendResponse response, Uri owner, DateTime time)
{
m_log.DebugFormat("[{0}]: InventoryFetchFolderList(): OwnerID: {1}, Response: {2}", extension,
owner, response);
}
public void LogInventoryFetchInventory(string extension, BackendResponse response, Uri owner, DateTime time)
{
m_log.DebugFormat("[{0}]: InventoryFetchInventory(): OwnerID: {1}, Response: {2}", extension,
owner, response);
}
public void LogInventoryFetchActiveGestures(string extension, BackendResponse response, Uri owner, DateTime time)
{
m_log.DebugFormat("[{0}]: InventoryFetchActiveGestures(): OwnerID: {1}, Response: {2}", extension,
owner, response);
}
public void LogInventoryCreate(string extension, BackendResponse response, Uri owner, bool folder, DateTime time)
{
m_log.DebugFormat("[{0}]: InventoryCreate(): OwnerID: {1}, Response: {2}", extension,
owner, response);
}
public void LogInventoryCreateInventory(string extension, BackendResponse response, DateTime time)
{
m_log.DebugFormat("[{0}]: InventoryCreateInventory(): Response: {1}", extension,
response);
}
public void LogInventoryDelete(string extension, BackendResponse response, Uri owner, UUID objID, bool folder, DateTime time)
{
m_log.DebugFormat("[{0}]: InventoryDelete(): OwnerID: {1}, Folder: {2}, Response: {3}", extension,
owner, folder, response);
}
public void LogInventoryPurgeFolder(string extension, BackendResponse response, Uri owner, UUID folderID, DateTime time)
{
m_log.DebugFormat("[{0}]: InventoryPurgeFolder(): OwnerID: {1}, FolderID: {2}, Response: {3}", extension,
owner, folderID, response);
}
#endregion IMetricsProvider implementation
#region IPlugin implementation
public void Initialise(AssetInventoryServer server)
{
//m_server = server;
}
/// <summary>
/// <para>Initialises metrics interface</para>
/// </summary>
public void Initialise()
{
m_log.Info("[NULLMETRICS]: Null metrics loaded.");
}
public void Dispose()
{
}
public string Version
{
// TODO: this should be something meaningful and not hardcoded?
get { return "0.1"; }
}
public string Name
{
get { return "NullMetrics"; }
}
#endregion IPlugin implementation
}
}

View File

@ -1,198 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Reflection;
using System.Net;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using log4net;
namespace OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim
{
public class OpenSimAssetFrontendPlugin : IAssetInventoryServerPlugin
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private AssetInventoryServer m_server;
public OpenSimAssetFrontendPlugin()
{
}
#region IPlugin implementation
public void Initialise(AssetInventoryServer server)
{
m_server = server;
// Asset request
m_server.HttpServer.AddStreamHandler(new AssetRequestHandler(server));
// Asset creation
m_server.HttpServer.AddStreamHandler(new AssetPostHandler(server));
m_log.Info("[OPENSIMASSETFRONTEND]: OpenSim Asset Frontend loaded.");
}
/// <summary>
/// <para>Initialises asset interface</para>
/// </summary>
public void Initialise()
{
m_log.InfoFormat("[OPENSIMASSETFRONTEND]: {0} cannot be default-initialized!", Name);
throw new PluginNotInitialisedException(Name);
}
public void Dispose()
{
}
public string Version
{
// TODO: this should be something meaningful and not hardcoded?
get { return "0.1"; }
}
public string Name
{
get { return "OpenSimAssetFrontend"; }
}
#endregion IPlugin implementation
public class AssetRequestHandler : BaseStreamHandler
{
AssetInventoryServer m_server;
//public AssetRequestHandler(AssetInventoryServer server) : base("GET", "^/assets")
public AssetRequestHandler(AssetInventoryServer server) : base("GET", "/assets")
{
m_server = server;
}
public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
byte[] buffer = new byte[] {};
UUID assetID;
// Split the URL up to get the asset ID out
string[] rawUrl = httpRequest.Url.PathAndQuery.Split('/');
if (rawUrl.Length >= 3 && rawUrl[2].Length >= 36 && UUID.TryParse(rawUrl[2].Substring(0, 36), out assetID))
{
BackendResponse dataResponse;
AssetBase asset = new AssetBase();
if ((dataResponse = m_server.StorageProvider.TryFetchDataMetadata(assetID, out asset)) == BackendResponse.Success)
{
if (rawUrl.Length >= 4 && rawUrl[3] == "data")
{
httpResponse.StatusCode = (int)HttpStatusCode.OK;
httpResponse.ContentType = Utils.SLAssetTypeToContentType(asset.Type);
buffer=asset.Data;
}
else
{
XmlSerializer xs = new XmlSerializer(typeof(AssetBase));
MemoryStream ms = new MemoryStream();
XmlTextWriter xw = new XmlTextWriter(ms, Encoding.UTF8);
xs.Serialize(xw, asset);
xw.Flush();
ms.Seek(0, SeekOrigin.Begin);
buffer = ms.GetBuffer();
Array.Resize<byte>(ref buffer, (int)ms.Length);
ms.Close();
httpResponse.StatusCode = (int)HttpStatusCode.OK;
}
}
else
{
m_log.WarnFormat("[OPENSIMASSETFRONTEND]: Failed to fetch asset data or metadata for {0}: {1}", assetID, dataResponse);
httpResponse.StatusCode = (int) HttpStatusCode.NotFound;
}
}
else
{
m_log.Warn("[OPENSIMASSETFRONTEND]: Unrecognized OpenSim asset request: " + httpRequest.Url.PathAndQuery);
}
return buffer;
}
}
public class AssetPostHandler : BaseStreamHandler
{
AssetInventoryServer m_server;
//public AssetPostHandler(AssetInventoryServer server) : base("POST", "/^assets")
public AssetPostHandler(AssetInventoryServer server) : base("POST", "/assets")
{
m_server = server;
}
public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
AssetBase asset = null;
try
{
asset = (AssetBase) new XmlSerializer(typeof (AssetBase)).Deserialize(httpRequest.InputStream);
}
catch (Exception ex)
{
m_log.Warn("[OPENSIMASSETFRONTEND]: Failed to parse POST data (expecting AssetBase): " + ex.Message);
httpResponse.StatusCode = (int) HttpStatusCode.BadRequest;
}
if (asset != null && asset.Data != null && asset.Data.Length > 0)
{
BackendResponse storageResponse = m_server.StorageProvider.TryCreateAsset(asset);
if (storageResponse == BackendResponse.Success)
httpResponse.StatusCode = (int) HttpStatusCode.Created;
else if (storageResponse == BackendResponse.NotFound)
httpResponse.StatusCode = (int) HttpStatusCode.NotFound;
else
httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError;
}
else
{
m_log.Warn("[OPENSIMASSETFRONTEND]: AssetPostHandler called with no asset data");
httpResponse.StatusCode = (int) HttpStatusCode.BadRequest;
}
return new byte[] {};
}
}
}
}

View File

@ -1,189 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Reflection;
using System.Data;
using System.Collections.Generic;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Data;
using Nini.Config;
using log4net;
namespace OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim
{
public class OpenSimAssetStoragePlugin : IAssetStorageProvider
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
const string EXTENSION_NAME = "OpenSimAssetStorage"; // Used in metrics reporting
private AssetInventoryServer m_server;
private IAssetDataPlugin m_assetProvider;
private IConfig m_openSimConfig;
public OpenSimAssetStoragePlugin()
{
}
#region IAssetStorageProvider implementation
public BackendResponse TryFetchMetadata(UUID assetID, out AssetMetadata metadata)
{
metadata = null;
BackendResponse ret;
AssetBase asset = m_assetProvider.GetAsset(assetID);
if (asset == null) ret = BackendResponse.NotFound;
else
{
metadata = asset.Metadata;
ret = BackendResponse.Success;
}
m_server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now);
return ret;
}
public BackendResponse TryFetchData(UUID assetID, out byte[] assetData)
{
assetData = null;
BackendResponse ret;
AssetBase asset = m_assetProvider.GetAsset(assetID);
if (asset == null) ret = BackendResponse.NotFound;
else
{
assetData = asset.Data;
ret = BackendResponse.Success;
}
m_server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (assetData != null ? assetData.Length : 0), DateTime.Now);
return ret;
}
public BackendResponse TryFetchDataMetadata(UUID assetID, out AssetBase asset)
{
asset = m_assetProvider.GetAsset(assetID);
if (asset == null) return BackendResponse.NotFound;
return BackendResponse.Success;
}
public BackendResponse TryCreateAsset(AssetBase asset, out UUID assetID)
{
assetID = asset.FullID = UUID.Random();
return TryCreateAsset(asset);
}
public BackendResponse TryCreateAsset(AssetBase asset)
{
BackendResponse ret;
m_assetProvider.StoreAsset(asset);
ret = BackendResponse.Success;
m_server.MetricsProvider.LogAssetCreate(EXTENSION_NAME, ret, asset.FullID, asset.Data.Length, DateTime.Now);
return ret;
}
public int ForEach(Action<AssetMetadata> action, int start, int count)
{
int rowCount = 0;
foreach (AssetMetadata metadata in m_assetProvider.FetchAssetMetadataSet(start, count))
{
// We set the ContentType here because Utils is only in
// AssetInventoryServer. This should be moved to the DB
// backends when the equivalent of SLAssetTypeToContentType is
// in OpenSim.Framework or similar.
metadata.ContentType = Utils.SLAssetTypeToContentType(metadata.Type);
action(metadata);
++rowCount;
}
return rowCount;
}
#endregion IAssetStorageProvider implementation
#region IPlugin implementation
public void Initialise(AssetInventoryServer server)
{
m_server = server;
m_openSimConfig = server.ConfigFile.Configs["OpenSim"];
try
{
m_assetProvider = DataPluginFactory.LoadDataPlugin<IAssetDataPlugin>(m_openSimConfig.GetString("asset_database_provider"),
m_openSimConfig.GetString("asset_database_connect"));
if (m_assetProvider == null)
{
m_log.Error("[OPENSIMASSETSTORAGE]: Failed to load a database plugin, server halting.");
Environment.Exit(-1);
}
else
m_log.InfoFormat("[OPENSIMASSETSTORAGE]: Loaded storage backend: {0}", Version);
}
catch (Exception e)
{
m_log.WarnFormat("[OPENSIMASSETSTORAGE]: Failure loading data plugin: {0}", e.ToString());
throw new PluginNotInitialisedException(Name);
}
}
/// <summary>
/// <para>Initialises asset interface</para>
/// </summary>
public void Initialise()
{
m_log.InfoFormat("[OPENSIMASSETSTORAGE]: {0} cannot be default-initialized!", Name);
throw new PluginNotInitialisedException(Name);
}
public void Dispose()
{
}
public string Version
{
get { return m_assetProvider.Version; }
}
public string Name
{
get { return "OpenSimAssetStorage"; }
}
#endregion IPlugin implementation
}
}

View File

@ -1,867 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Net;
using System.Reflection;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using log4net;
namespace OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim
{
public class OpenSimInventoryFrontendPlugin : IAssetInventoryServerPlugin
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private AssetInventoryServer m_server;
private Utils.InventoryCollectionSerializer collectionSerializer = new Utils.InventoryCollectionSerializer();
public OpenSimInventoryFrontendPlugin()
{
}
#region IPlugin implementation
public void Initialise(AssetInventoryServer server)
{
m_server = server;
m_server.HttpServer.AddStreamHandler(new GetInventoryHandler(server, collectionSerializer));
m_server.HttpServer.AddStreamHandler(new CreateInventoryHandler(server));
m_server.HttpServer.AddStreamHandler(new NewFolderHandler(server));
m_server.HttpServer.AddStreamHandler(new UpdateFolderHandler(server));
m_server.HttpServer.AddStreamHandler(new MoveFolderHandler(server));
m_server.HttpServer.AddStreamHandler(new PurgeFolderHandler(server));
m_server.HttpServer.AddStreamHandler(new NewItemHandler(server));
m_server.HttpServer.AddStreamHandler(new DeleteItemHandler(server));
m_server.HttpServer.AddStreamHandler(new RootFoldersHandler(server));
m_server.HttpServer.AddStreamHandler(new ActiveGesturesHandler(server));
m_log.Info("[OPENSIMINVENTORYFRONTEND]: OpenSim Inventory Frontend loaded.");
}
/// <summary>
/// <para>Initialises asset interface</para>
/// </summary>
public void Initialise()
{
m_log.InfoFormat("[OPENSIMINVENTORYFRONTEND]: {0} cannot be default-initialized!", Name);
throw new PluginNotInitialisedException(Name);
}
public void Dispose()
{
}
public string Version
{
// TODO: this should be something meaningful and not hardcoded?
get { return "0.1"; }
}
public string Name
{
get { return "OpenSimInventoryFrontend"; }
}
#endregion IPlugin implementation
public class GetInventoryHandler : BaseStreamHandler
{
AssetInventoryServer m_server;
Utils.InventoryCollectionSerializer m_collectionSerializer;
//public GetInventoryHandler(AssetInventoryServer server, Utils.InventoryCollectionSerializer collectionSerializer) : base("POST", @"^/GetInventory/")
public GetInventoryHandler(AssetInventoryServer server, Utils.InventoryCollectionSerializer collectionSerializer) : base("POST", "/GetInventory")
{
m_server = server;
m_collectionSerializer = collectionSerializer;
}
public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
byte[] buffer = new byte[] {};
UUID sessionID, agentID;
UUID ownerID = DeserializeUUID(httpRequest.InputStream, out agentID, out sessionID);
if (ownerID != UUID.Zero)
{
m_log.Warn("[OPENSIMINVENTORYFRONTEND]: GetInventory is not scalable on some inventory backends, avoid calling it wherever possible");
Uri owner = Utils.GetOpenSimUri(ownerID);
InventoryCollection inventory;
BackendResponse storageResponse = m_server.InventoryProvider.TryFetchInventory(owner, out inventory);
if (storageResponse == BackendResponse.Success)
{
//collectionSerializer.Serialize(httpResponse.Body, inventory);
//httpResponse.Body.Flush();
MemoryStream ms = new MemoryStream();
m_collectionSerializer.Serialize(ms, inventory);
ms.Seek(0, SeekOrigin.Begin);
buffer = ms.GetBuffer();
Array.Resize<byte>(ref buffer, (int) ms.Length);
ms.Close();
httpResponse.StatusCode = (int) HttpStatusCode.OK;
}
else if (storageResponse == BackendResponse.NotFound)
{
// Return an empty inventory set to mimic OpenSim.Grid.InventoryServer.exe
inventory = new InventoryCollection();
inventory.UserID = ownerID;
inventory.Folders = new Dictionary<UUID, InventoryFolderWithChildren>();
inventory.Items = new Dictionary<UUID, InventoryItemBase>();
//collectionSerializer.Serialize(httpResponse.Body, inventory);
//httpResponse.Body.Flush();
MemoryStream ms = new MemoryStream();
m_collectionSerializer.Serialize(ms, inventory);
ms.Seek(0, SeekOrigin.Begin);
buffer = ms.GetBuffer();
Array.Resize<byte>(ref buffer, (int) ms.Length);
ms.Close();
httpResponse.StatusCode = (int) HttpStatusCode.OK;
}
else
{
httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError;
}
}
else
{
httpResponse.StatusCode = (int) HttpStatusCode.BadRequest;
}
return buffer;
}
}
public class CreateInventoryHandler : BaseStreamHandler
{
AssetInventoryServer m_server;
//public CreateInventoryHandler(AssetInventoryServer server) : base("POST", @"^/CreateInventory/")
public CreateInventoryHandler(AssetInventoryServer server) : base("POST", "/CreateInventory")
{
m_server = server;
}
public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
UUID ownerID = DeserializeUUID(httpRequest.InputStream);
if (ownerID != UUID.Zero)
{
Uri owner = Utils.GetOpenSimUri(ownerID);
m_log.DebugFormat("[OPENSIMINVENTORYFRONTEND]: Created URI {0} for inventory creation", owner);
InventoryFolderWithChildren rootFolder = new InventoryFolderWithChildren("My Inventory", ownerID, UUID.Zero, (short)AssetType.Folder);
BackendResponse storageResponse = m_server.InventoryProvider.TryCreateInventory(owner, rootFolder);
if (storageResponse == BackendResponse.Success)
{
// TODO: The CreateFolder calls need to be executed in SimpleStorage.
//CreateFolder("Animations", ownerID, rootFolder.ID, AssetType.Animation);
//CreateFolder("Body Parts", ownerID, rootFolder.ID, AssetType.Bodypart);
//CreateFolder("Calling Cards", ownerID, rootFolder.ID, AssetType.CallingCard);
//CreateFolder("Clothing", ownerID, rootFolder.ID, AssetType.Clothing);
//CreateFolder("Gestures", ownerID, rootFolder.ID, AssetType.Gesture);
//CreateFolder("Landmarks", ownerID, rootFolder.ID, AssetType.Landmark);
//CreateFolder("Lost and Found", ownerID, rootFolder.ID, AssetType.LostAndFoundFolder);
//CreateFolder("Notecards", ownerID, rootFolder.ID, AssetType.Notecard);
//CreateFolder("Objects", ownerID, rootFolder.ID, AssetType.Object);
//CreateFolder("Photo Album", ownerID, rootFolder.ID, AssetType.SnapshotFolder);
//CreateFolder("Scripts", ownerID, rootFolder.ID, AssetType.LSLText);
//CreateFolder("Sounds", ownerID, rootFolder.ID, AssetType.Sound);
//CreateFolder("Textures", ownerID, rootFolder.ID, AssetType.Texture);
//CreateFolder("Trash", ownerID, rootFolder.ID, AssetType.TrashFolder);
return SerializeBool(true);
}
}
return SerializeBool(false);
}
}
public class NewFolderHandler : BaseStreamHandler
{
AssetInventoryServer m_server;
//public NewFolderHandler(AssetInventoryServer server) : base("POST", @"^/NewFolder/")
public NewFolderHandler(AssetInventoryServer server) : base("POST", "/NewFolder")
{
m_server = server;
}
public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
UUID agentID, sessionID;
InventoryFolderWithChildren folder = DeserializeFolder(httpRequest.InputStream, out agentID, out sessionID);
if (folder != null)
{
Uri owner = Utils.GetOpenSimUri(folder.Owner);
// Some calls that are moving or updating a folder instead
// of creating a new one will pass in an InventoryFolder
// without the name set and type set to 0. If this is the
// case we need to look up the name first and preserver
// it's type.
if (String.IsNullOrEmpty(folder.Name))
{
InventoryFolderWithChildren oldFolder;
if (m_server.InventoryProvider.TryFetchFolder(owner, folder.ID, out oldFolder) == BackendResponse.Success)
{
folder.Name = oldFolder.Name;
folder.Type = oldFolder.Type;
}
}
BackendResponse storageResponse = m_server.InventoryProvider.TryCreateFolder(owner, folder);
if (storageResponse == BackendResponse.Success)
{
return SerializeBool(true);
}
}
return SerializeBool(false);
}
}
public class UpdateFolderHandler : BaseStreamHandler
{
AssetInventoryServer m_server;
//public UpdateFolderHandler(AssetInventoryServer server) : base("POST", @"^/UpdateFolder/")
public UpdateFolderHandler(AssetInventoryServer server) : base("POST", "/UpdateFolder")
{
m_server = server;
}
public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
return new NewFolderHandler(m_server).Handle(path, request, httpRequest, httpResponse);
}
}
public class MoveFolderHandler : BaseStreamHandler
{
AssetInventoryServer m_server;
//public MoveFolderHandler(AssetInventoryServer server) : base("POST", @"^/MoveFolder/")
public MoveFolderHandler(AssetInventoryServer server) : base("POST", "/MoveFolder")
{
m_server = server;
}
public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
return new NewFolderHandler(m_server).Handle(path, request, httpRequest, httpResponse);
}
}
public class PurgeFolderHandler : BaseStreamHandler
{
AssetInventoryServer m_server;
//public PurgeFolderHandler(AssetInventoryServer server) : base("POST", @"^/PurgeFolder/")
public PurgeFolderHandler(AssetInventoryServer server) : base("POST", "/PurgeFolder")
{
m_server = server;
}
public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
UUID agentID, sessionID;
InventoryFolderWithChildren folder = DeserializeFolder(httpRequest.InputStream, out agentID, out sessionID);
if (folder != null)
{
Uri owner = Utils.GetOpenSimUri(folder.Owner);
BackendResponse storageResponse = m_server.InventoryProvider.TryPurgeFolder(owner, folder.ID);
if (storageResponse == BackendResponse.Success)
{
return SerializeBool(true);
}
}
return SerializeBool(false);
}
}
public class NewItemHandler : BaseStreamHandler
{
AssetInventoryServer m_server;
//public NewItemHandler(AssetInventoryServer server) : base("POST", @"^/NewItem/")
public NewItemHandler(AssetInventoryServer server) : base("POST", "/NewItem")
{
m_server = server;
}
public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
UUID agentID, sessionID;
InventoryItemBase item = DeserializeItem(httpRequest.InputStream, out agentID, out sessionID);
if (item != null)
{
Uri owner = Utils.GetOpenSimUri(agentID);
BackendResponse storageResponse = m_server.InventoryProvider.TryCreateItem(owner, item);
if (storageResponse == BackendResponse.Success)
{
return SerializeBool(true);
}
}
return SerializeBool(false);
}
}
public class DeleteItemHandler : BaseStreamHandler
{
AssetInventoryServer m_server;
//public DeleteItemHandler(AssetInventoryServer server) : base("POST", @"^/DeleteItem/")
public DeleteItemHandler(AssetInventoryServer server) : base("POST", "/DeleteItem")
{
m_server = server;
}
public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
UUID agentID, sessionID;
InventoryItemBase item = DeserializeItem(httpRequest.InputStream, out agentID, out sessionID);
if (item != null)
{
Uri owner = Utils.GetOpenSimUri(item.Owner);
BackendResponse storageResponse = m_server.InventoryProvider.TryDeleteItem(owner, item.ID);
if (storageResponse == BackendResponse.Success)
{
return SerializeBool(true);
}
}
return SerializeBool(false);
}
}
public class RootFoldersHandler : BaseStreamHandler
{
AssetInventoryServer m_server;
//public RootFoldersHandler(AssetInventoryServer server) : base("POST", @"^/RootFolders/")
public RootFoldersHandler(AssetInventoryServer server) : base("POST", "/RootFolders")
{
m_server = server;
}
public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
byte[] buffer = new byte[] {};
UUID ownerID = DeserializeUUID(httpRequest.InputStream);
if (ownerID != UUID.Zero)
{
Uri owner = Utils.GetOpenSimUri(ownerID);
List<InventoryFolderWithChildren> skeleton;
BackendResponse storageResponse = m_server.InventoryProvider.TryFetchFolderList(owner, out skeleton);
if (storageResponse == BackendResponse.Success)
{
MemoryStream ms = new MemoryStream();
SerializeFolderList(ms, skeleton);
ms.Seek(0, SeekOrigin.Begin);
buffer = ms.GetBuffer();
Array.Resize<byte>(ref buffer, (int) ms.Length);
ms.Close();
httpResponse.StatusCode = (int) HttpStatusCode.OK;
}
else if (storageResponse == BackendResponse.NotFound)
{
// Return an empty set of inventory so the requester knows that
// an inventory needs to be created for this agent
MemoryStream ms = new MemoryStream();
SerializeFolderList(ms, new List<InventoryFolderWithChildren>(0));
ms.Seek(0, SeekOrigin.Begin);
buffer = ms.GetBuffer();
Array.Resize<byte>(ref buffer, (int) ms.Length);
ms.Close();
httpResponse.StatusCode = (int) HttpStatusCode.OK;
}
else
{
httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError;
}
}
else
{
httpResponse.StatusCode = (int) HttpStatusCode.BadRequest;
}
return buffer;
}
}
public class ActiveGesturesHandler : BaseStreamHandler
{
AssetInventoryServer m_server;
//public ActiveGesturesHandler(AssetInventoryServer server) : base("POST", @"^/ActiveGestures/")
public ActiveGesturesHandler(AssetInventoryServer server) : base("POST", "/ActiveGestures")
{
m_server = server;
}
public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
byte[] buffer = new byte[] {};
UUID ownerID = DeserializeUUID(httpRequest.InputStream);
if (ownerID != UUID.Zero)
{
Uri owner = Utils.GetOpenSimUri(ownerID);
List<InventoryItemBase> gestures;
BackendResponse storageResponse = m_server.InventoryProvider.TryFetchActiveGestures(owner, out gestures);
if (storageResponse == BackendResponse.Success)
{
MemoryStream ms = new MemoryStream();
SerializeItemList(ms, gestures);
ms.Seek(0, SeekOrigin.Begin);
buffer = ms.GetBuffer();
Array.Resize<byte>(ref buffer, (int) ms.Length);
ms.Close();
httpResponse.StatusCode = (int) HttpStatusCode.OK;
}
else if (storageResponse == BackendResponse.NotFound)
{
// Return an empty set of gestures to match OpenSim.Grid.InventoryServer.exe behavior
MemoryStream ms = new MemoryStream();
SerializeItemList(ms, new List<InventoryItemBase>(0));
ms.Seek(0, SeekOrigin.Begin);
buffer = ms.GetBuffer();
Array.Resize<byte>(ref buffer, (int) ms.Length);
ms.Close();
httpResponse.StatusCode = (int) HttpStatusCode.OK;
}
else
{
httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError;
}
}
else
{
httpResponse.StatusCode = (int) HttpStatusCode.BadRequest;
}
return buffer;
}
}
//BackendResponse CreateFolder(string name, UUID ownerID, UUID parentID, AssetType assetType)
//{
// InventoryFolder folder = new InventoryFolder(name, ownerID, parentID, (short)assetType);
// Uri owner = Utils.GetOpenSimUri(ownerID);
// return m_server.InventoryProvider.TryCreateFolder(owner, folder);
//}
private static UUID DeserializeUUID(Stream stream)
{
UUID id = UUID.Zero;
try
{
using (XmlReader reader = XmlReader.Create(stream))
{
reader.MoveToContent();
UUID.TryParse(reader.ReadElementContentAsString("guid", String.Empty), out id);
}
}
catch (Exception ex)
{
m_log.Warn("[OPENSIMINVENTORYFRONTEND]: Failed to parse POST data (expecting guid): " + ex.Message);
}
return id;
}
private static UUID DeserializeUUID(Stream stream, out UUID agentID, out UUID sessionID)
{
UUID id;
try
{
using (XmlReader reader = XmlReader.Create(stream))
{
reader.MoveToContent();
reader.ReadStartElement("RestSessionObjectOfGuid");
UUID.TryParse(reader.ReadElementContentAsString("SessionID", String.Empty), out sessionID);
UUID.TryParse(reader.ReadElementContentAsString("AvatarID", String.Empty), out agentID);
UUID.TryParse(reader.ReadElementContentAsString("Body", String.Empty), out id);
reader.ReadEndElement();
}
}
catch (Exception ex)
{
m_log.Warn("[OPENSIMINVENTORYFRONTEND]: Failed to parse GetInventory POST data: " + ex.Message);
agentID = UUID.Zero;
sessionID = UUID.Zero;
return UUID.Zero;
}
return id;
}
private static InventoryFolderWithChildren DeserializeFolder(Stream stream, out UUID agentID, out UUID sessionID)
{
InventoryFolderWithChildren folder = new InventoryFolderWithChildren();
try
{
using (XmlReader reader = XmlReader.Create(stream))
{
reader.MoveToContent();
reader.ReadStartElement("RestSessionObjectOfInventoryFolderBase");
UUID.TryParse(reader.ReadElementContentAsString("SessionID", String.Empty), out sessionID);
UUID.TryParse(reader.ReadElementContentAsString("AvatarID", String.Empty), out agentID);
reader.ReadStartElement("Body");
if (reader.Name == "Name")
folder.Name = reader.ReadElementContentAsString("Name", String.Empty);
else
folder.Name = String.Empty;
UUID dummyUUID;
ReadUUID(reader, "ID", out dummyUUID);
folder.ID = dummyUUID;
ReadUUID(reader, "Owner", out dummyUUID);
folder.Owner = dummyUUID;
ReadUUID(reader, "ParentID", out dummyUUID);
folder.ParentID = dummyUUID;
short dummyType;
Int16.TryParse(reader.ReadElementContentAsString("Type", String.Empty), out dummyType);
folder.Type = dummyType;
ushort dummyVersion;
UInt16.TryParse(reader.ReadElementContentAsString("Version", String.Empty), out dummyVersion);
folder.Version = dummyVersion;
reader.ReadEndElement();
reader.ReadEndElement();
}
}
catch (Exception ex)
{
m_log.Warn("[OPENSIMINVENTORYFRONTEND]: Failed to parse POST data (expecting InventoryFolderBase): " + ex.Message);
agentID = UUID.Zero;
sessionID = UUID.Zero;
return null;
}
return folder;
}
private static InventoryItemBase DeserializeItem(Stream stream, out UUID agentID, out UUID sessionID)
{
InventoryItemBase item = new InventoryItemBase();
try
{
using (XmlReader reader = XmlReader.Create(stream))
{
reader.MoveToContent();
reader.ReadStartElement("RestSessionObjectOfInventoryItemBase");
UUID.TryParse(reader.ReadElementContentAsString("SessionID", String.Empty), out sessionID);
UUID.TryParse(reader.ReadElementContentAsString("AvatarID", String.Empty), out agentID);
reader.ReadStartElement("Body");
item.Name = reader.ReadElementContentAsString("Name", String.Empty);
UUID dummyUUID;
ReadUUID(reader, "ID", out dummyUUID);
item.ID = dummyUUID;
ReadUUID(reader, "Owner", out dummyUUID);
item.Owner = dummyUUID;
int dummyInt;
Int32.TryParse(reader.ReadElementContentAsString("InvType", String.Empty), out dummyInt);
item.InvType = dummyInt;
ReadUUID(reader, "Folder", out dummyUUID);
item.Folder = dummyUUID;
item.CreatorId = reader.ReadElementContentAsString("CreatorId", String.Empty);
item.Description = reader.ReadElementContentAsString("Description", String.Empty);
uint dummyUInt;
UInt32.TryParse(reader.ReadElementContentAsString("NextPermissions", String.Empty), out dummyUInt);
item.NextPermissions = dummyUInt;
UInt32.TryParse(reader.ReadElementContentAsString("CurrentPermissions", String.Empty), out dummyUInt);
item.CurrentPermissions = dummyUInt;
UInt32.TryParse(reader.ReadElementContentAsString("BasePermissions", String.Empty), out dummyUInt);
item.BasePermissions = dummyUInt;
UInt32.TryParse(reader.ReadElementContentAsString("EveryOnePermissions", String.Empty), out dummyUInt);
item.EveryOnePermissions = dummyUInt;
UInt32.TryParse(reader.ReadElementContentAsString("GroupPermissions", String.Empty), out dummyUInt);
item.GroupPermissions = dummyUInt;
Int32.TryParse(reader.ReadElementContentAsString("AssetType", String.Empty), out dummyInt);
item.AssetType = dummyInt;
ReadUUID(reader, "AssetID", out dummyUUID);
item.AssetID = dummyUUID;
ReadUUID(reader, "GroupID", out dummyUUID);
item.GroupID = dummyUUID;
bool dummyBool;
Boolean.TryParse(reader.ReadElementContentAsString("GroupOwned", String.Empty), out dummyBool);
item.GroupOwned = dummyBool;
Int32.TryParse(reader.ReadElementContentAsString("SalePrice", String.Empty), out dummyInt);
item.SalePrice = dummyInt;
byte dummyByte;
Byte.TryParse(reader.ReadElementContentAsString("SaleType", String.Empty), out dummyByte);
item.SaleType = dummyByte;
UInt32.TryParse(reader.ReadElementContentAsString("Flags", String.Empty), out dummyUInt);
item.Flags = dummyUInt;
Int32.TryParse(reader.ReadElementContentAsString("CreationDate", String.Empty), out dummyInt);
item.CreationDate = dummyInt;
reader.ReadEndElement();
reader.ReadEndElement();
}
}
catch (Exception ex)
{
m_log.Warn("[OPENSIMINVENTORYFRONTEND]: Failed to parse POST data (expecting InventoryItemBase): " + ex.Message);
agentID = UUID.Zero;
sessionID = UUID.Zero;
return null;
}
return item;
}
private static byte[] SerializeBool(bool value)
{
byte[] buffer;
MemoryStream ms = new MemoryStream();
using (XmlWriter writer = XmlWriter.Create(ms))
{
writer.WriteStartDocument();
writer.WriteStartElement("boolean");
writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema");
writer.WriteString(value.ToString().ToLower());
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Flush();
}
ms.Seek(0, SeekOrigin.Begin);
buffer = ms.GetBuffer();
Array.Resize<byte>(ref buffer, (int) ms.Length);
ms.Close();
return buffer;
}
private static void SerializeFolderList(Stream stream, List<InventoryFolderWithChildren> folders)
{
using (XmlWriter writer = XmlWriter.Create(stream))
{
writer.WriteStartDocument();
writer.WriteStartElement("ArrayOfInventoryFolderBase");
writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema");
if (folders != null)
{
foreach (InventoryFolderWithChildren folder in folders)
{
writer.WriteStartElement("InventoryFolderBase");
writer.WriteElementString("Name", folder.Name);
WriteUUID(writer, "Owner", folder.Owner);
WriteUUID(writer, "ParentID", folder.ParentID);
WriteUUID(writer, "ID", folder.ID);
writer.WriteElementString("Type", XmlConvert.ToString(folder.Type));
writer.WriteElementString("Version", XmlConvert.ToString(folder.Version));
writer.WriteEndElement();
}
}
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Flush();
}
stream.Flush();
}
private static void SerializeItemList(Stream stream, List<InventoryItemBase> items)
{
using (XmlWriter writer = XmlWriter.Create(stream))
{
writer.WriteStartDocument();
writer.WriteStartElement("ArrayOfInventoryItemBase");
writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema");
if (items != null)
{
foreach (InventoryItemBase item in items)
{
writer.WriteStartElement("InventoryItemBase");
WriteUUID(writer, "ID", item.ID);
writer.WriteElementString("InvType", XmlConvert.ToString(item.InvType));
WriteUUID(writer, "Folder", item.Folder);
WriteUUID(writer, "Owner", item.Owner);
writer.WriteElementString("Creator", item.CreatorId);
writer.WriteElementString("Name", item.Name);
writer.WriteElementString("Description", item.Description);
writer.WriteElementString("NextPermissions", XmlConvert.ToString(item.NextPermissions));
writer.WriteElementString("CurrentPermissions", XmlConvert.ToString(item.CurrentPermissions));
writer.WriteElementString("BasePermissions", XmlConvert.ToString(item.BasePermissions));
writer.WriteElementString("EveryOnePermissions", XmlConvert.ToString(item.EveryOnePermissions));
writer.WriteElementString("GroupPermissions", XmlConvert.ToString(item.GroupPermissions));
writer.WriteElementString("AssetType", XmlConvert.ToString(item.AssetType));
WriteUUID(writer, "AssetID", item.AssetID);
WriteUUID(writer, "GroupID", item.GroupID);
writer.WriteElementString("GroupOwned", XmlConvert.ToString(item.GroupOwned));
writer.WriteElementString("SalePrice", XmlConvert.ToString(item.SalePrice));
writer.WriteElementString("SaleType", XmlConvert.ToString(item.SaleType));
writer.WriteElementString("Flags", XmlConvert.ToString(item.Flags));
writer.WriteElementString("CreationDate", XmlConvert.ToString(item.CreationDate));
writer.WriteEndElement();
}
}
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Flush();
}
stream.Flush();
}
private static void WriteUUID(XmlWriter writer, string name, UUID id)
{
writer.WriteStartElement(name);
writer.WriteElementString("Guid", XmlConvert.ToString(id.Guid));
writer.WriteEndElement();
}
private static void ReadUUID(XmlReader reader, string name, out UUID id)
{
reader.ReadStartElement(name);
UUID.TryParse(reader.ReadElementContentAsString("Guid", String.Empty), out id);
reader.ReadEndElement();
}
}
#region OpenSim AssetType
/// <summary>
/// The different types of grid assets
/// </summary>
public enum AssetType : sbyte
{
/// <summary>Unknown asset type</summary>
Unknown = -1,
/// <summary>Texture asset, stores in JPEG2000 J2C stream format</summary>
Texture = 0,
/// <summary>Sound asset</summary>
Sound = 1,
/// <summary>Calling card for another avatar</summary>
CallingCard = 2,
/// <summary>Link to a location in world</summary>
Landmark = 3,
// <summary>Legacy script asset, you should never see one of these</summary>
//[Obsolete]
//Script = 4,
/// <summary>Collection of textures and parameters that can be
/// worn by an avatar</summary>
Clothing = 5,
/// <summary>Primitive that can contain textures, sounds,
/// scripts and more</summary>
Object = 6,
/// <summary>Notecard asset</summary>
Notecard = 7,
/// <summary>Holds a collection of inventory items</summary>
Folder = 8,
/// <summary>Root inventory folder</summary>
RootFolder = 9,
/// <summary>Linden scripting language script</summary>
LSLText = 10,
/// <summary>LSO bytecode for a script</summary>
LSLBytecode = 11,
/// <summary>Uncompressed TGA texture</summary>
TextureTGA = 12,
/// <summary>Collection of textures and shape parameters that can
/// be worn</summary>
Bodypart = 13,
/// <summary>Trash folder</summary>
TrashFolder = 14,
/// <summary>Snapshot folder</summary>
SnapshotFolder = 15,
/// <summary>Lost and found folder</summary>
LostAndFoundFolder = 16,
/// <summary>Uncompressed sound</summary>
SoundWAV = 17,
/// <summary>Uncompressed TGA non-square image, not to be used as a
/// texture</summary>
ImageTGA = 18,
/// <summary>Compressed JPEG non-square image, not to be used as a
/// texture</summary>
ImageJPEG = 19,
/// <summary>Animation</summary>
Animation = 20,
/// <summary>Sequence of animations, sounds, chat, and pauses</summary>
Gesture = 21,
/// <summary>Simstate file</summary>
Simstate = 22,
}
#endregion OpenSim AssetType
}

View File

@ -1,56 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Communications;
using OpenSim.Data;
namespace OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim
{
public class OpenSimInventoryService : InventoryServiceBase
{
public InventoryFolderWithChildren GetInventoryFolder(UUID folderID)
{
InventoryFolderBase baseFolder = null;
InventoryFolderWithChildren folder = null;
foreach (IInventoryDataPlugin plugin in m_plugins)
{
baseFolder = plugin.getInventoryFolder(folderID);
}
if (null != baseFolder)
{
folder = new InventoryFolderWithChildren(baseFolder);
folder.Children = null; // This call only returns data for the folder itself, no children data
}
return folder;
}
}
}

View File

@ -1,547 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Data;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Data;
using Nini.Config;
using log4net;
namespace OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim
{
public class OpenSimInventoryStoragePlugin : IInventoryStorageProvider
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
const string EXTENSION_NAME = "OpenSimInventoryStorage"; // Used in metrics reporting
private AssetInventoryServer m_server;
private IConfig m_openSimConfig;
private OpenSimInventoryService m_inventoryService;
public OpenSimInventoryStoragePlugin()
{
}
#region IInventoryStorageProvider implementation
public BackendResponse TryFetchItem(Uri owner, UUID itemID, out InventoryItemBase item)
{
item = null;
//BackendResponse ret;
//using (MySqlConnection dbConnection = new MySqlConnection(m_openSimConfig.GetString("inventory_database_connect")))
//{
// IDataReader reader;
// try
// {
// dbConnection.Open();
// IDbCommand command = dbConnection.CreateCommand();
// command.CommandText = String.Format("SELECT assetID,assetType,inventoryName,inventoryDescription,inventoryNextPermissions," +
// "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," +
// "creationDate,groupID,groupOwned,flags,avatarID,parentFolderID,inventoryGroupPermissions FROM inventoryitems WHERE inventoryID='{0}'",
// itemID.ToString());
// reader = command.ExecuteReader();
// if (reader.Read())
// {
// item = new InventoryItemBase();
// item.ID = itemID;
// item.AssetID = UUID.Parse(reader.GetString(0));
// item.AssetType = reader.GetInt32(1);
// item.Name = reader.GetString(2);
// item.Description = reader.GetString(3);
// item.NextPermissions = (uint)reader.GetInt32(4);
// item.CurrentPermissions = (uint)reader.GetInt32(5);
// item.InvType = reader.GetInt32(6);
// item.Creator = UUID.Parse(reader.GetString(7));
// item.BasePermissions = (uint)reader.GetInt32(8);
// item.EveryOnePermissions = (uint)reader.GetInt32(9);
// item.SalePrice = reader.GetInt32(10);
// item.SaleType = reader.GetByte(11);
// item.CreationDate = reader.GetInt32(12);
// item.GroupID = UUID.Parse(reader.GetString(13));
// item.GroupOwned = reader.GetBoolean(14);
// item.Flags = (uint)reader.GetInt32(15);
// item.Owner = UUID.Parse(reader.GetString(16));
// item.Folder = UUID.Parse(reader.GetString(17));
// item.GroupPermissions = (uint)reader.GetInt32(18);
// ret = BackendResponse.Success;
// }
// else
// {
// ret = BackendResponse.NotFound;
// }
// }
// catch (MySqlException ex)
// {
// m_log.Error("[OPENSIMINVENTORYSTORAGE]: Connection to MySQL backend failed: " + ex.Message);
// ret = BackendResponse.Failure;
// }
//}
//m_server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now);
//return ret;
m_log.Warn("[OPENSIMINVENTORYSTORAGE]: Called TryFetchItem which is not implemented.");
return BackendResponse.Success;
}
public BackendResponse TryFetchFolder(Uri owner, UUID folderID, out InventoryFolderWithChildren folder)
{
BackendResponse ret;
// TODO: implement some logic for "folder not found"
folder = m_inventoryService.GetInventoryFolder(folderID);
ret = BackendResponse.Success;
m_server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now);
return ret;
}
public BackendResponse TryFetchFolderContents(Uri owner, UUID folderID, out InventoryCollection contents)
{
contents = null;
//BackendResponse ret;
//using (MySqlConnection dbConnection = new MySqlConnection(m_openSimConfig.GetString("inventory_database_connect")))
//{
// IDataReader reader;
// try
// {
// dbConnection.Open();
// contents = new InventoryCollection();
// #region Folder retrieval
// IDbCommand command = dbConnection.CreateCommand();
// command.CommandText = String.Format("SELECT folderName,type,version,agentID,folderID FROM inventoryfolders WHERE parentFolderID='{0}'",
// folderID.ToString());
// reader = command.ExecuteReader();
// contents.Folders = new Dictionary<UUID, InventoryFolderWithChildren>();
// while (reader.Read())
// {
// InventoryFolderWithChildren folder = new InventoryFolderWithChildren();
// folder.ParentID = folderID;
// folder.Children = null; // This call doesn't do recursion
// folder.Name = reader.GetString(0);
// folder.Type = reader.GetInt16(1);
// folder.Version = (ushort)reader.GetInt16(2);
// folder.Owner = UUID.Parse(reader.GetString(3));
// folder.ID = UUID.Parse(reader.GetString(4));
// contents.Folders.Add(folder.ID, folder);
// contents.UserID = folder.Owner;
// }
// reader.Close();
// #endregion Folder retrieval
// #region Item retrieval
// command = dbConnection.CreateCommand();
// command.CommandText = String.Format("SELECT assetID,assetType,inventoryName,inventoryDescription,inventoryNextPermissions," +
// "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," +
// "creationDate,groupID,groupOwned,flags,avatarID,inventoryID,inventoryGroupPermissions FROM inventoryitems WHERE parentFolderID='{0}'",
// folderID.ToString());
// reader = command.ExecuteReader();
// contents.Items = new Dictionary<UUID, InventoryItemBase>();
// while (reader.Read())
// {
// InventoryItemBase item = new InventoryItemBase();
// item.Folder = folderID;
// item.AssetID = UUID.Parse(reader.GetString(0));
// item.AssetType = reader.GetInt32(1);
// item.Name = reader.GetString(2);
// item.Description = reader.GetString(3);
// item.NextPermissions = (uint)reader.GetInt32(4);
// item.CurrentPermissions = (uint)reader.GetInt32(5);
// item.InvType = reader.GetInt32(6);
// item.Creator = UUID.Parse(reader.GetString(7));
// item.BasePermissions = (uint)reader.GetInt32(8);
// item.EveryOnePermissions = (uint)reader.GetInt32(9);
// item.SalePrice = reader.GetInt32(10);
// item.SaleType = reader.GetByte(11);
// item.CreationDate = reader.GetInt32(12);
// item.GroupID = UUID.Parse(reader.GetString(13));
// item.GroupOwned = reader.GetBoolean(14);
// item.Flags = (uint)reader.GetInt32(15);
// item.Owner = UUID.Parse(reader.GetString(16));
// item.ID = UUID.Parse(reader.GetString(17));
// item.GroupPermissions = (uint)reader.GetInt32(18);
// contents.Items.Add(item.ID, item);
// contents.UserID = item.Owner;
// }
// #endregion Item retrieval
// ret = BackendResponse.Success;
// }
// catch (MySqlException ex)
// {
// m_log.Error("[OPENSIMINVENTORYSTORAGE]: Connection to MySQL backend failed: " + ex.Message);
// ret = BackendResponse.Failure;
// }
//}
//m_server.MetricsProvider.LogInventoryFetchFolderContents(EXTENSION_NAME, ret, owner, folderID, DateTime.Now);
//return ret;
m_log.Warn("[OPENSIMINVENTORYSTORAGE]: Called TryFetchFolderContents which is not implemented.");
return BackendResponse.Success;
}
public BackendResponse TryFetchFolderList(Uri owner, out List<InventoryFolderWithChildren> folders)
{
folders = new List<InventoryFolderWithChildren>();
BackendResponse ret;
UUID ownerID;
if (Utils.TryGetOpenSimUUID(owner, out ownerID))
{
List<InventoryFolderBase> baseFolders = m_inventoryService.GetInventorySkeleton(ownerID);
foreach (InventoryFolderBase baseFolder in baseFolders)
{
InventoryFolderWithChildren folder = new InventoryFolderWithChildren(baseFolder);
//folder.Children = null; // This call does not create a folder hierarchy
folders.Add(folder);
}
ret = BackendResponse.Success;
}
else
{
folders = null;
ret = BackendResponse.NotFound;
}
m_server.MetricsProvider.LogInventoryFetchFolderList(EXTENSION_NAME, ret, owner, DateTime.Now);
return ret;
}
public BackendResponse TryFetchInventory(Uri owner, out InventoryCollection inventory)
{
inventory = null;
BackendResponse ret;
List<InventoryFolderWithChildren> folders;
ret = TryFetchFolderList(owner, out folders);
if (ret == BackendResponse.Success)
{
// Add the retrieved folders to the inventory collection
inventory = new InventoryCollection();
inventory.Folders = new Dictionary<UUID, InventoryFolderWithChildren>(folders.Count);
foreach (InventoryFolderWithChildren folder in folders)
inventory.Folders[folder.ID] = folder;
// Fetch inventory items
UUID ownerID;
if (Utils.TryGetOpenSimUUID(owner, out ownerID))
{
inventory.UserID = ownerID;
inventory.Items = new Dictionary<UUID, InventoryItemBase>();
foreach (InventoryFolderWithChildren folder in folders)
{
foreach (InventoryItemBase item in m_inventoryService.RequestFolderItems(folder.ID))
{
inventory.Items.Add(item.ID, item);
}
}
ret = BackendResponse.Success;
}
else
{
ret = BackendResponse.NotFound;
}
}
m_server.MetricsProvider.LogInventoryFetchInventory(EXTENSION_NAME, ret, owner, DateTime.Now);
return ret;
}
public BackendResponse TryFetchActiveGestures(Uri owner, out List<InventoryItemBase> gestures)
{
gestures = null;
BackendResponse ret;
UUID ownerID;
if (Utils.TryGetOpenSimUUID(owner, out ownerID))
{
gestures = m_inventoryService.GetActiveGestures(ownerID);
ret = BackendResponse.Success;
}
else
{
ret = BackendResponse.NotFound;
}
m_server.MetricsProvider.LogInventoryFetchActiveGestures(EXTENSION_NAME, ret, owner, DateTime.Now);
return ret;
}
public BackendResponse TryCreateItem(Uri owner, InventoryItemBase item)
{
BackendResponse ret;
if (m_inventoryService.AddItem(item))
{
ret = BackendResponse.Success;
}
else
{
ret = BackendResponse.Failure;
}
m_server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, false, DateTime.Now);
return ret;
}
public BackendResponse TryCreateFolder(Uri owner, InventoryFolderWithChildren folder)
{
BackendResponse ret;
if (m_inventoryService.AddFolder(folder))
{
ret = BackendResponse.Success;
}
else
{
ret = BackendResponse.Failure;
}
m_server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, true, DateTime.Now);
return ret;
}
public BackendResponse TryCreateInventory(Uri owner, InventoryFolderWithChildren rootFolder)
{
BackendResponse ret;
UUID ownerID;
if (Utils.TryGetOpenSimUUID(owner, out ownerID))
{
if (m_inventoryService.CreateNewUserInventory(ownerID))
{
ret = BackendResponse.Success;
}
else
{
ret = BackendResponse.Failure;
}
}
else
{
ret = BackendResponse.Failure;
}
return ret;
}
public BackendResponse TryDeleteItem(Uri owner, UUID itemID)
{
BackendResponse ret;
if (m_inventoryService.DeleteItem(m_inventoryService.GetInventoryItem(itemID)))
{
ret = BackendResponse.Success;
}
else
{
ret = BackendResponse.Failure;
}
m_server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now);
return ret;
}
public BackendResponse TryDeleteFolder(Uri owner, UUID folderID)
{
//BackendResponse ret;
//UUID ownerID;
//if (Utils.TryGetOpenSimUUID(owner, out ownerID))
//{
// using (MySqlConnection dbConnection = new MySqlConnection(m_openSimConfig.GetString("inventory_database_connect")))
// {
// try
// {
// dbConnection.Open();
// MySqlCommand command = new MySqlCommand(
// "DELETE FROM inventoryfolders WHERE folderID=?folderID AND agentID=?agentID", dbConnection);
// command.Parameters.AddWithValue("?folderID", folderID.ToString());
// command.Parameters.AddWithValue("?agentID", ownerID.ToString());
// int rowsAffected = command.ExecuteNonQuery();
// if (rowsAffected == 1)
// {
// ret = BackendResponse.Success;
// }
// else
// {
// m_log.ErrorFormat("[OPENSIMINVENTORYSTORAGE]: MySQL DELETE query affected {0} rows", rowsAffected);
// ret = BackendResponse.NotFound;
// }
// }
// catch (MySqlException ex)
// {
// m_log.Error("[OPENSIMINVENTORYSTORAGE]: Connection to MySQL backend failed: " + ex.Message);
// ret = BackendResponse.Failure;
// }
// }
//}
//else
//{
// ret = BackendResponse.NotFound;
//}
//m_server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now);
//return ret;
m_log.Warn("[OPENSIMINVENTORYSTORAGE]: Called TryDeleteFolder which is not implemented.");
return BackendResponse.Success;
}
public BackendResponse TryPurgeFolder(Uri owner, UUID folderID)
{
BackendResponse ret;
if (m_inventoryService.PurgeFolder(m_inventoryService.GetInventoryFolder(folderID)))
{
ret = BackendResponse.Success;
}
else
{
ret = BackendResponse.Failure;
}
m_server.MetricsProvider.LogInventoryPurgeFolder(EXTENSION_NAME, ret, owner, folderID, DateTime.Now);
return ret;
}
public int ForEach(Action<AssetMetadata> action, int start, int count)
{
int rowCount = 0;
//using (MySqlConnection dbConnection = new MySqlConnection(m_openSimConfig.GetString("inventory_database_connect")))
//{
// MySqlDataReader reader;
// try
// {
// dbConnection.Open();
// MySqlCommand command = dbConnection.CreateCommand();
// command.CommandText = String.Format("SELECT name,description,assetType,temporary,data,id FROM assets LIMIT {0}, {1}",
// start, count);
// reader = command.ExecuteReader();
// }
// catch (MySqlException ex)
// {
// m_log.Error("[OPENSIMINVENTORYSTORAGE]: Connection to MySQL backend failed: " + ex.Message);
// return 0;
// }
// while (reader.Read())
// {
// Metadata metadata = new Metadata();
// metadata.CreationDate = OpenMetaverse.Utils.Epoch;
// metadata.Description = reader.GetString(1);
// metadata.ID = UUID.Parse(reader.GetString(5));
// metadata.Name = reader.GetString(0);
// metadata.SHA1 = OpenMetaverse.Utils.SHA1((byte[])reader.GetValue(4));
// metadata.Temporary = reader.GetBoolean(3);
// metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2));
// action(metadata);
// ++rowCount;
// }
// reader.Close();
//}
return rowCount;
}
#endregion IInventoryStorageProvider implementation
#region IPlugin implementation
public void Initialise(AssetInventoryServer server)
{
m_server = server;
m_openSimConfig = server.ConfigFile.Configs["OpenSim"];
m_inventoryService = new OpenSimInventoryService();
m_inventoryService.AddPlugin(m_openSimConfig.GetString("inventory_database_provider"),
m_openSimConfig.GetString("inventory_database_connect"));
}
public void Stop()
{
}
public void Initialise()
{
m_log.InfoFormat("[OPENSIMINVENTORYSTORAGE]: {0} cannot be default-initialized!", Name);
throw new PluginNotInitialisedException(Name);
}
public void Dispose()
{
}
public string Version
{
// TODO: this should be something meaningful and not hardcoded?
get { return "0.1"; }
}
public string Name
{
get { return "OpenSimInventoryStorage"; }
}
#endregion IPlugin implementation
}
}

View File

@ -1,27 +0,0 @@
<Addin id="OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim" version="0.1">
<Runtime>
<Import assembly="OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim.dll" />
<Import assembly="OpenSim.Data.dll" />
</Runtime>
<Dependencies>
<Addin id="OpenSim.Grid.AssetInventoryServer" version="0.1" />
</Dependencies>
<ExtensionPoint path = "/OpenSim/AssetData">
<ExtensionNode name="Plugin" type="OpenSim.Framework.PluginExtensionNode" objectType="OpenSim.Data.IAssetDataPlugin" />
</ExtensionPoint>
<Extension path="/OpenSim/AssetInventoryServer/AssetStorageProvider">
<Plugin id="OpenSimAssetStorage" provider="OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim.OpenSimAssetStoragePlugin" />
</Extension>
<Extension path="/OpenSim/AssetInventoryServer/InventoryStorageProvider">
<Plugin id="OpenSimInventoryStorage" provider="OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim.OpenSimInventoryStoragePlugin" />
</Extension>
<Extension path="/OpenSim/AssetInventoryServer/Frontend">
<Plugin id="OpenSimAssetFrontend" provider="OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim.OpenSimAssetFrontendPlugin" />
</Extension>
<Extension path="/OpenSim/AssetInventoryServer/Frontend">
<Plugin id="OpenSimInventoryFrontend" provider="OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim.OpenSimInventoryFrontendPlugin" />
</Extension>
</Addin>

View File

@ -1,369 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.IO;
using System.Reflection;
using System.Net;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using log4net;
namespace OpenSim.Grid.AssetInventoryServer.Plugins
{
public class ReferenceFrontendPlugin : IAssetInventoryServerPlugin
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
AssetInventoryServer m_server;
public ReferenceFrontendPlugin()
{
}
#region IPlugin implementation
public void Initialise(AssetInventoryServer server)
{
m_server = server;
// Asset metadata request
//m_server.HttpServer.AddStreamHandler(new MetadataRequestHandler(server));
// Asset data request
m_server.HttpServer.AddStreamHandler(new DataRequestHandler(server));
// Asset creation
//m_server.HttpServer.AddStreamHandler(new CreateRequestHandler(server));
m_log.Info("[REFERENCEFRONTEND]: Reference Frontend loaded.");
}
/// <summary>
/// <para>Initialises asset interface</para>
/// </summary>
public void Initialise()
{
m_log.InfoFormat("[REFERENCEFRONTEND]: {0} cannot be default-initialized!", Name);
throw new PluginNotInitialisedException(Name);
}
public void Dispose()
{
}
public string Version
{
// TODO: this should be something meaningful and not hardcoded?
get { return "0.1"; }
}
public string Name
{
get { return "ReferenceFrontend"; }
}
#endregion IPlugin implementation
//public class MetadataRequestHandler : IStreamedRequestHandler
//{
// AssetInventoryServer m_server;
// string m_contentType;
// string m_httpMethod;
// string m_path;
// public MetadataRequestHandler(AssetInventoryServer server)
// {
// m_server = server;
// m_contentType = null;
// m_httpMethod = "GET";
// m_path = @"^/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/metadata";
// }
// #region IStreamedRequestHandler implementation
// public string ContentType
// {
// get { return m_contentType; }
// }
// public string HttpMethod
// {
// get { return m_httpMethod; }
// }
// public string Path
// {
// get { return m_path; }
// }
// public byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
// {
// byte[] serializedData = null;
// UUID assetID;
// // Split the URL up into an AssetID and a method
// string[] rawUrl = httpRequest.Url.PathAndQuery.Split('/');
// if (rawUrl.Length >= 3 && UUID.TryParse(rawUrl[1], out assetID))
// {
// UUID authToken = Utils.GetAuthToken(httpRequest);
// if (m_server.AuthorizationProvider.IsMetadataAuthorized(authToken, assetID))
// {
// AssetMetadata metadata;
// BackendResponse storageResponse = m_server.StorageProvider.TryFetchMetadata(assetID, out metadata);
// if (storageResponse == BackendResponse.Success)
// {
// // If the asset data location wasn't specified in the metadata, specify it
// // manually here by pointing back to this asset server
// if (!metadata.Methods.ContainsKey("data"))
// {
// metadata.Methods["data"] = new Uri(String.Format("{0}://{1}/{2}/data",
// httpRequest.Url.Scheme, httpRequest.Url.Authority, assetID));
// }
// serializedData = metadata.SerializeToBytes();
// httpResponse.StatusCode = (int) HttpStatusCode.OK;
// httpResponse.ContentType = "application/json";
// httpResponse.ContentLength = serializedData.Length;
// httpResponse.Body.Write(serializedData, 0, serializedData.Length);
// }
// else if (storageResponse == BackendResponse.NotFound)
// {
// m_log.Warn("[REFERENCEFRONTEND]: Could not find metadata for asset " + assetID.ToString());
// httpResponse.StatusCode = (int) HttpStatusCode.NotFound;
// }
// else
// {
// httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError;
// }
// }
// else
// {
// httpResponse.StatusCode = (int) HttpStatusCode.Forbidden;
// }
// return serializedData;
// }
// httpResponse.StatusCode = (int) HttpStatusCode.NotFound;
// return serializedData;
// }
// #endregion IStreamedRequestHandler implementation
//}
public class DataRequestHandler : IStreamedRequestHandler
{
AssetInventoryServer m_server;
string m_contentType;
string m_httpMethod;
string m_path;
public DataRequestHandler(AssetInventoryServer server)
{
m_server = server;
m_contentType = null;
m_httpMethod = "GET";
m_path = @"^/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/data";
}
#region IStreamedRequestHandler implementation
public string ContentType
{
get { return m_contentType; }
}
public string HttpMethod
{
get { return m_httpMethod; }
}
public string Path
{
get { return m_path; }
}
public byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
byte[] assetData = null;
UUID assetID;
// Split the URL up into an AssetID and a method
string[] rawUrl = httpRequest.Url.PathAndQuery.Split('/');
if (rawUrl.Length >= 3 && UUID.TryParse(rawUrl[1], out assetID))
{
UUID authToken = Utils.GetAuthToken(httpRequest);
if (m_server.AuthorizationProvider.IsDataAuthorized(authToken, assetID))
{
BackendResponse storageResponse = m_server.StorageProvider.TryFetchData(assetID, out assetData);
if (storageResponse == BackendResponse.Success)
{
httpResponse.StatusCode = (int) HttpStatusCode.OK;
httpResponse.ContentType = "application/octet-stream";
httpResponse.AddHeader("Content-Disposition", "attachment; filename=" + assetID.ToString());
httpResponse.ContentLength = assetData.Length;
httpResponse.Body.Write(assetData, 0, assetData.Length);
}
else if (storageResponse == BackendResponse.NotFound)
{
httpResponse.StatusCode = (int) HttpStatusCode.NotFound;
}
else
{
httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError;
}
}
else
{
httpResponse.StatusCode = (int) HttpStatusCode.Forbidden;
}
return assetData;
}
httpResponse.StatusCode = (int) HttpStatusCode.BadRequest;
return assetData;
}
#endregion IStreamedRequestHandler implementation
}
//public class CreateRequestHandler : IStreamedRequestHandler
//{
// AssetInventoryServer m_server;
// string m_contentType;
// string m_httpMethod;
// string m_path;
// public CreateRequestHandler(AssetInventoryServer server)
// {
// m_server = server;
// m_contentType = null;
// m_httpMethod = "POST";
// m_path = "^/createasset";
// }
// #region IStreamedRequestHandler implementation
// public string ContentType
// {
// get { return m_contentType; }
// }
// public string HttpMethod
// {
// get { return m_httpMethod; }
// }
// public string Path
// {
// get { return m_path; }
// }
// public byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
// {
// byte[] responseData = null;
// UUID authToken = Utils.GetAuthToken(httpRequest);
// if (m_server.AuthorizationProvider.IsCreateAuthorized(authToken))
// {
// try
// {
// OSD osdata = OSDParser.DeserializeJson(new StreamReader(httpRequest.InputStream).ReadToEnd());
// if (osdata.Type == OSDType.Map)
// {
// OSDMap map = (OSDMap)osdata;
// Metadata metadata = new Metadata();
// metadata.Deserialize(map);
// byte[] assetData = map["data"].AsBinary();
// if (assetData != null && assetData.Length > 0)
// {
// BackendResponse storageResponse;
// if (metadata.ID != UUID.Zero)
// storageResponse = m_server.StorageProvider.TryCreateAsset(metadata, assetData);
// else
// storageResponse = m_server.StorageProvider.TryCreateAsset(metadata, assetData, out metadata.ID);
// if (storageResponse == BackendResponse.Success)
// {
// httpResponse.StatusCode = (int) HttpStatusCode.Created;
// OSDMap responseMap = new OSDMap(1);
// responseMap["id"] = OSD.FromUUID(metadata.ID);
// LitJson.JsonData jsonData = OSDParser.SerializeJson(responseMap);
// responseData = System.Text.Encoding.UTF8.GetBytes(jsonData.ToJson());
// httpResponse.Body.Write(responseData, 0, responseData.Length);
// httpResponse.Body.Flush();
// }
// else if (storageResponse == BackendResponse.NotFound)
// {
// httpResponse.StatusCode = (int) HttpStatusCode.NotFound;
// }
// else
// {
// httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError;
// }
// }
// else
// {
// httpResponse.StatusCode = (int) HttpStatusCode.BadRequest;
// }
// }
// else
// {
// httpResponse.StatusCode = (int) HttpStatusCode.BadRequest;
// }
// }
// catch (Exception ex)
// {
// httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError;
// httpResponse.StatusDescription = ex.Message;
// }
// }
// else
// {
// httpResponse.StatusCode = (int) HttpStatusCode.Forbidden;
// }
// return responseData;
// }
// #endregion IStreamedRequestHandler implementation
//}
}
}

View File

@ -1,28 +0,0 @@
<Addin id="OpenSim.Grid.AssetInventoryServer.Plugins" version="0.1">
<Runtime>
<Import assembly="OpenSim.Grid.AssetInventoryServer.Plugins.dll" />
</Runtime>
<Dependencies>
<Addin id="OpenSim.Grid.AssetInventoryServer" version="0.1" />
</Dependencies>
<Extension path="/OpenSim/AssetInventoryServer/MetricsProvider">
<Plugin id="NullMetrics" provider="OpenSim.Grid.AssetInventoryServer.Plugins.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.NullMetricsPlugin" />
</Extension>
<Extension path="/OpenSim/AssetInventoryServer/Frontend">
<Plugin id="BrowseFrontend" provider="OpenSim.Grid.AssetInventoryServer.Plugins.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.BrowseFrontendPlugin" />
</Extension>
<Extension path="/OpenSim/AssetInventoryServer/Frontend">
<Plugin id="ReferenceFrontend" provider="OpenSim.Grid.AssetInventoryServer.Plugins.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.ReferenceFrontendPlugin" />
</Extension>
<Extension path="/OpenSim/AssetInventoryServer/AuthenticationProvider">
<Plugin id="NullAuthentication" provider="OpenSim.Grid.AssetInventoryServer.Plugins.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.NullAuthenticationPlugin" />
</Extension>
<Extension path="/OpenSim/AssetInventoryServer/AuthorizationProvider">
<Plugin id="AuthorizeAll" provider="OpenSim.Grid.AssetInventoryServer.Plugins.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.AuthorizeAllPlugin" />
</Extension>
<Extension path="/OpenSim/AssetInventoryServer/Frontend">
<Plugin id="InventoryArchive" provider="OpenSim.Grid.AssetInventoryServer.Plugins.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.InventoryArchivePlugin" />
</Extension>
</Addin>

View File

@ -1,16 +0,0 @@
<Addin id="OpenSim.Grid.AssetInventoryServer.Plugins.Simple" version="0.1">
<Runtime>
<Import assembly="OpenSim.Grid.AssetInventoryServer.Plugins.Simple.dll" />
</Runtime>
<Dependencies>
<Addin id="OpenSim.Grid.AssetInventoryServer" version="0.1" />
</Dependencies>
<Extension path="/OpenSim/AssetInventoryServer/AssetStorageProvider">
<Plugin id="SimpleAssetStorage" provider="OpenSim.Grid.AssetInventoryServer.Plugins.Simple.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.Simple.SimpleAssetStoragePlugin" />
</Extension>
<Extension path="/OpenSim/AssetInventoryServer/InventoryStorageProvider">
<Plugin id="SimpleInventoryStorage" provider="OpenSim.Grid.AssetInventoryServer.Plugins.Simple.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.Simple.SimpleInventoryStoragePlugin" />
</Extension>
</Addin>

View File

@ -1,290 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Reflection;
using System.Collections.Generic;
using System.IO;
using OpenMetaverse;
using OpenSim.Framework;
using log4net;
namespace OpenSim.Grid.AssetInventoryServer.Plugins.Simple
{
public class SimpleAssetStoragePlugin : IAssetStorageProvider
{
const string EXTENSION_NAME = "SimpleAssetStorage"; // Used in metrics reporting
const string DEFAULT_DATA_DIR = "SimpleAssets";
const string TEMP_DATA_DIR = "SimpleAssetsTemp";
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
AssetInventoryServer server;
Dictionary<UUID, AssetMetadata> metadataStorage;
Dictionary<UUID, string> filenames;
public SimpleAssetStoragePlugin()
{
}
#region Required Interfaces
public BackendResponse TryFetchMetadata(UUID assetID, out AssetMetadata metadata)
{
metadata = null;
BackendResponse ret;
if (metadataStorage.TryGetValue(assetID, out metadata))
ret = BackendResponse.Success;
else
ret = BackendResponse.NotFound;
server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now);
return ret;
}
public BackendResponse TryFetchData(UUID assetID, out byte[] assetData)
{
assetData = null;
string filename;
BackendResponse ret;
if (filenames.TryGetValue(assetID, out filename))
{
try
{
assetData = File.ReadAllBytes(filename);
ret = BackendResponse.Success;
}
catch (Exception ex)
{
m_log.ErrorFormat("[SIMPLEASSETSTORAGE]: Failed reading data for asset {0} from {1}: {2}", assetID, filename, ex.Message);
ret = BackendResponse.Failure;
}
}
else
{
ret = BackendResponse.NotFound;
}
server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (assetData != null ? assetData.Length : 0), DateTime.Now);
return ret;
}
public BackendResponse TryFetchDataMetadata(UUID assetID, out AssetBase asset)
{
asset = new AssetBase();
AssetMetadata metadata = asset.Metadata;
string filename;
BackendResponse ret;
if (metadataStorage.TryGetValue(assetID, out metadata) &&
filenames.TryGetValue(assetID, out filename))
{
try
{
asset.Data = File.ReadAllBytes(filename);
ret = BackendResponse.Success;
}
catch (Exception ex)
{
m_log.ErrorFormat("[SIMPLEASSETSTORAGE]: Failed reading data for asset {0} from {1}: {2}", assetID, filename, ex.Message);
ret = BackendResponse.Failure;
}
asset.Type = (sbyte) Utils.ContentTypeToSLAssetType(metadata.ContentType);
asset.Local = false;
}
else
{
asset = null;
ret = BackendResponse.NotFound;
}
server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now);
server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (asset != null && asset.Data != null ? asset.Data.Length : 0), DateTime.Now);
return ret;
}
public BackendResponse TryCreateAsset(AssetBase asset, out UUID assetID)
{
assetID = asset.FullID = UUID.Random();
return TryCreateAsset(asset);
}
public BackendResponse TryCreateAsset(AssetBase asset)
{
BackendResponse ret;
AssetMetadata metadata = asset.Metadata;
string path;
string filename = String.Format("{0}.{1}", asset.FullID, Utils.ContentTypeToExtension(metadata.ContentType));
if (asset.Temporary)
path = Path.Combine(TEMP_DATA_DIR, filename);
else
path = Path.Combine(DEFAULT_DATA_DIR, filename);
try
{
File.WriteAllBytes(path, asset.Data);
lock (filenames) filenames[asset.FullID] = path;
// Set the creation date to right now
metadata.CreationDate = DateTime.Now;
lock (metadataStorage)
metadataStorage[asset.FullID] = metadata;
ret = BackendResponse.Success;
}
catch (Exception ex)
{
m_log.ErrorFormat("[SIMPLEASSETSTORAGE]: Failed writing data for asset {0} to {1}: {2}", asset.FullID, filename, ex.Message);
ret = BackendResponse.Failure;
}
server.MetricsProvider.LogAssetCreate(EXTENSION_NAME, ret, asset.FullID, asset.Data.Length, DateTime.Now);
return ret;
}
public int ForEach(Action<AssetMetadata> action, int start, int count)
{
int rowCount = 0;
//lock (metadataStorage)
//{
// foreach (Metadata metadata in metadataStorage.Values)
// {
// action(metadata);
// ++rowCount;
// }
//}
return rowCount;
}
#endregion Required Interfaces
#region IPlugin implementation
public void Initialise(AssetInventoryServer server)
{
this.server = server;
metadataStorage = new Dictionary<UUID, AssetMetadata>();
filenames = new Dictionary<UUID, string>();
LoadFiles(DEFAULT_DATA_DIR, false);
LoadFiles(TEMP_DATA_DIR, true);
m_log.InfoFormat("[SIMPLEASSETSTORAGE]: Initialized the store index with metadata for {0} assets",
metadataStorage.Count);
}
/// <summary>
/// <para>Initialises asset interface</para>
/// </summary>
public void Initialise()
{
m_log.InfoFormat("[SIMPLEASSETSTORAGE]: {0} cannot be default-initialized!", Name);
throw new PluginNotInitialisedException(Name);
}
public void Dispose()
{
WipeTemporary();
}
public string Version
{
// TODO: this should be something meaningful and not hardcoded?
get { return "0.1"; }
}
public string Name
{
get { return "SimpleAssetStorage"; }
}
#endregion IPlugin implementation
public void WipeTemporary()
{
if (Directory.Exists(TEMP_DATA_DIR))
{
try { Directory.Delete(TEMP_DATA_DIR); }
catch (Exception ex) { m_log.Error("[SIMPLEASSETSTORAGE]: " + ex.Message); }
}
}
void LoadFiles(string folder, bool temporary)
{
// Try to create the directory if it doesn't already exist
if (!Directory.Exists(folder))
{
try { Directory.CreateDirectory(folder); }
catch (Exception ex)
{
m_log.Warn("[SIMPLEASSETSTORAGE]: " + ex.Message);
return;
}
}
lock (metadataStorage)
{
try
{
string[] assets = Directory.GetFiles(folder);
for (int i = 0; i < assets.Length; i++)
{
string filename = assets[i];
byte[] data = File.ReadAllBytes(filename);
AssetMetadata metadata = new AssetMetadata();
metadata.CreationDate = File.GetCreationTime(filename);
metadata.Description = String.Empty;
metadata.FullID = SimpleUtils.ParseUUIDFromFilename(filename);
metadata.Name = SimpleUtils.ParseNameFromFilename(filename);
metadata.SHA1 = OpenMetaverse.Utils.SHA1(data);
metadata.Temporary = false;
metadata.ContentType = Utils.ExtensionToContentType(Path.GetExtension(filename).TrimStart('.'));
// Store the loaded data
metadataStorage[metadata.FullID] = metadata;
filenames[metadata.FullID] = filename;
}
}
catch (Exception ex)
{
m_log.Warn("[SIMPLEASSETSTORAGE]: " + ex.Message);
}
}
}
}
}

View File

@ -1,625 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Reflection;
using System.Collections.Generic;
using System.IO;
using System.Text;
using OpenMetaverse;
using OpenSim.Framework;
using log4net;
namespace OpenSim.Grid.AssetInventoryServer.Plugins.Simple
{
public class SimpleInventoryStoragePlugin : IInventoryStorageProvider
{
const string EXTENSION_NAME = "SimpleInventoryStorage"; // Used for metrics reporting
const string DEFAULT_INVENTORY_DIR = "SimpleInventory";
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
AssetInventoryServer server;
Dictionary<Uri, InventoryCollection> inventories = new Dictionary<Uri, InventoryCollection>();
Dictionary<Uri, List<InventoryItemBase>> activeGestures = new Dictionary<Uri, List<InventoryItemBase>>();
Utils.InventoryItemSerializer itemSerializer = new Utils.InventoryItemSerializer();
Utils.InventoryFolderSerializer folderSerializer = new Utils.InventoryFolderSerializer();
public SimpleInventoryStoragePlugin()
{
}
#region Required Interfaces
public BackendResponse TryFetchItem(Uri owner, UUID itemID, out InventoryItemBase item)
{
item = null;
BackendResponse ret;
InventoryCollection collection;
if (inventories.TryGetValue(owner, out collection) && collection.Items.TryGetValue(itemID, out item))
ret = BackendResponse.Success;
else
ret = BackendResponse.NotFound;
server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now);
return ret;
}
public BackendResponse TryFetchFolder(Uri owner, UUID folderID, out InventoryFolderWithChildren folder)
{
folder = null;
BackendResponse ret;
InventoryCollection collection;
if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder))
ret = BackendResponse.Success;
else
ret = BackendResponse.NotFound;
server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now);
return ret;
}
public BackendResponse TryFetchFolderContents(Uri owner, UUID folderID, out InventoryCollection contents)
{
contents = null;
BackendResponse ret;
InventoryCollection collection;
InventoryFolderWithChildren folder;
if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder))
{
contents = new InventoryCollection();
contents.UserID = collection.UserID;
contents.Folders = new Dictionary<UUID, InventoryFolderWithChildren>();
contents.Items = new Dictionary<UUID, InventoryItemBase>();
foreach (InventoryNodeBase invBase in folder.Children.Values)
{
if (invBase is InventoryItemBase)
{
InventoryItemBase invItem = invBase as InventoryItemBase;
contents.Items.Add(invItem.ID, invItem);
}
else
{
InventoryFolderWithChildren invFolder = invBase as InventoryFolderWithChildren;
contents.Folders.Add(invFolder.ID, invFolder);
}
}
ret = BackendResponse.Success;
}
else
{
ret = BackendResponse.NotFound;
}
server.MetricsProvider.LogInventoryFetchFolderContents(EXTENSION_NAME, ret, owner, folderID, DateTime.Now);
return ret;
}
public BackendResponse TryFetchFolderList(Uri owner, out List<InventoryFolderWithChildren> folders)
{
folders = null;
BackendResponse ret;
InventoryCollection collection;
if (inventories.TryGetValue(owner, out collection))
{
folders = new List<InventoryFolderWithChildren>(collection.Folders.Values);
return BackendResponse.Success;
}
else
{
ret = BackendResponse.NotFound;
}
server.MetricsProvider.LogInventoryFetchFolderList(EXTENSION_NAME, ret, owner, DateTime.Now);
return ret;
}
public BackendResponse TryFetchInventory(Uri owner, out InventoryCollection inventory)
{
inventory = null;
BackendResponse ret;
if (inventories.TryGetValue(owner, out inventory))
ret = BackendResponse.Success;
else
ret = BackendResponse.NotFound;
server.MetricsProvider.LogInventoryFetchInventory(EXTENSION_NAME, ret, owner, DateTime.Now);
return ret;
}
public BackendResponse TryFetchActiveGestures(Uri owner, out List<InventoryItemBase> gestures)
{
gestures = null;
BackendResponse ret;
if (activeGestures.TryGetValue(owner, out gestures))
ret = BackendResponse.Success;
else
ret = BackendResponse.NotFound;
server.MetricsProvider.LogInventoryFetchActiveGestures(EXTENSION_NAME, ret, owner, DateTime.Now);
return ret;
}
public BackendResponse TryCreateItem(Uri owner, InventoryItemBase item)
{
BackendResponse ret;
InventoryCollection collection;
if (inventories.TryGetValue(owner, out collection))
{
// Delete this item first if it already exists
InventoryItemBase oldItem;
if (collection.Items.TryGetValue(item.ID, out oldItem))
TryDeleteItem(owner, item.ID);
try
{
// Create the file
SaveItem(item);
// Add the item to the collection
lock (collection) collection.Items[item.ID] = item;
// Add the item to its parent folder
InventoryFolderWithChildren parent;
if (collection.Folders.TryGetValue(item.Folder, out parent))
lock (parent.Children) parent.Children.Add(item.ID, item);
// Add active gestures to our list
if (item.InvType == (int)InventoryType.Gesture && item.Flags == 1)
{
lock (activeGestures)
activeGestures[owner].Add(item);
}
ret = BackendResponse.Success;
}
catch (Exception ex)
{
m_log.Error("[SIMPLEINVENTORYSTORAGE]: " + ex.Message);
ret = BackendResponse.Failure;
}
}
else
{
return BackendResponse.NotFound;
}
server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, false, DateTime.Now);
return ret;
}
public BackendResponse TryCreateFolder(Uri owner, InventoryFolderWithChildren folder)
{
BackendResponse ret;
InventoryCollection collection;
if (inventories.TryGetValue(owner, out collection))
{
// Delete this folder first if it already exists
InventoryFolderWithChildren oldFolder;
if (collection.Folders.TryGetValue(folder.ID, out oldFolder))
TryDeleteFolder(owner, folder.ID);
try
{
// Create the file
SaveFolder(folder);
// Add the folder to the collection
lock (collection) collection.Folders[folder.ID] = folder;
// Add the folder to its parent folder
InventoryFolderWithChildren parent;
if (collection.Folders.TryGetValue(folder.ParentID, out parent))
lock (parent.Children) parent.Children.Add(folder.ID, folder);
ret = BackendResponse.Success;
}
catch (Exception ex)
{
m_log.Error("[SIMPLEINVENTORYSTORAGE]: " + ex.Message);
ret = BackendResponse.Failure;
}
}
else
{
ret = BackendResponse.NotFound;
}
server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, true, DateTime.Now);
return ret;
}
public BackendResponse TryCreateInventory(Uri owner, InventoryFolderWithChildren rootFolder)
{
BackendResponse ret;
lock (inventories)
{
if (!inventories.ContainsKey(owner))
{
InventoryCollection collection = new InventoryCollection();
collection.UserID = rootFolder.Owner;
collection.Folders = new Dictionary<UUID, InventoryFolderWithChildren>();
collection.Folders.Add(rootFolder.ID, rootFolder);
collection.Items = new Dictionary<UUID, InventoryItemBase>();
inventories.Add(owner, collection);
ret = BackendResponse.Success;
}
else
{
ret = BackendResponse.Failure;
}
}
if (ret == BackendResponse.Success)
{
string path = Path.Combine(DEFAULT_INVENTORY_DIR, rootFolder.Owner.ToString());
try
{
// Create the directory for this agent
Directory.CreateDirectory(path);
// Create an index.txt containing the UUID and URI for this agent
string[] index = new string[] { rootFolder.Owner.ToString(), owner.ToString() };
File.WriteAllLines(Path.Combine(path, "index.txt"), index);
// Create the root folder file
SaveFolder(rootFolder);
}
catch (Exception ex)
{
m_log.Error("[SIMPLEINVENTORYSTORAGE]: " + ex.Message);
ret = BackendResponse.Failure;
}
}
server.MetricsProvider.LogInventoryCreateInventory(EXTENSION_NAME, ret, DateTime.Now);
return ret;
}
public BackendResponse TryDeleteItem(Uri owner, UUID itemID)
{
BackendResponse ret;
InventoryCollection collection;
InventoryItemBase item;
if (inventories.TryGetValue(owner, out collection) && collection.Items.TryGetValue(itemID, out item))
{
// Remove the item from its parent folder
InventoryFolderWithChildren parent;
if (collection.Folders.TryGetValue(item.Folder, out parent))
lock (parent.Children) parent.Children.Remove(itemID);
// Remove the item from the collection
lock (collection) collection.Items.Remove(itemID);
// Remove from the active gestures list if applicable
if (item.InvType == (int)InventoryType.Gesture)
{
lock (activeGestures)
{
for (int i = 0; i < activeGestures[owner].Count; i++)
{
if (activeGestures[owner][i].ID == itemID)
{
activeGestures[owner].RemoveAt(i);
break;
}
}
}
}
// Delete the file. We don't know exactly what the file name is,
// so search for it
string path = PathFromURI(owner);
string[] matches = Directory.GetFiles(path, String.Format("*{0}.item", itemID), SearchOption.TopDirectoryOnly);
foreach (string match in matches)
{
try { File.Delete(match); }
catch (Exception ex) { m_log.ErrorFormat("[SIMPLEINVENTORYSTORAGE]: Failed to delete file {0}: {1}", match, ex.Message); }
}
ret = BackendResponse.Success;
}
else
{
ret = BackendResponse.NotFound;
}
server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now);
return ret;
}
public BackendResponse TryDeleteFolder(Uri owner, UUID folderID)
{
BackendResponse ret;
InventoryCollection collection;
InventoryFolderWithChildren folder;
if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder))
{
// Remove the folder from its parent folder
InventoryFolderWithChildren parent;
if (collection.Folders.TryGetValue(folder.ParentID, out parent))
lock (parent.Children) parent.Children.Remove(folderID);
// Remove the folder from the collection
lock (collection) collection.Items.Remove(folderID);
// Delete the folder file. We don't know exactly what the file name is,
// so search for it
string path = PathFromURI(owner);
string[] matches = Directory.GetFiles(path, String.Format("*{0}.folder", folderID), SearchOption.TopDirectoryOnly);
foreach (string match in matches)
{
try { File.Delete(match); }
catch (Exception ex) { m_log.ErrorFormat("[SIMPLEINVENTORYSTORAGE]: Failed to delete folder file {0}: {1}", match, ex.Message); }
}
ret = BackendResponse.Success;
}
else
{
ret = BackendResponse.NotFound;
}
server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now);
return ret;
}
public BackendResponse TryPurgeFolder(Uri owner, UUID folderID)
{
BackendResponse ret;
InventoryCollection collection;
InventoryFolderWithChildren folder;
if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder))
{
// Delete all of the folder children
foreach (InventoryNodeBase obj in new List<InventoryNodeBase>(folder.Children.Values))
{
if (obj is InventoryItemBase)
{
TryDeleteItem(owner, (obj as InventoryItemBase).ID);
}
else
{
InventoryFolderWithChildren childFolder = obj as InventoryFolderWithChildren;
TryPurgeFolder(owner, childFolder.ID);
TryDeleteFolder(owner, childFolder.ID);
}
}
ret = BackendResponse.Success;
}
else
{
ret = BackendResponse.NotFound;
}
server.MetricsProvider.LogInventoryPurgeFolder(EXTENSION_NAME, ret, owner, folderID, DateTime.Now);
return ret;
}
#endregion Required Interfaces
void SaveItem(InventoryItemBase item)
{
string filename = String.Format("{0}-{1}.item", SanitizeFilename(item.Name), item.ID);
string path = Path.Combine(DEFAULT_INVENTORY_DIR, item.Owner.ToString());
path = Path.Combine(path, filename);
using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write))
{
itemSerializer.Serialize(stream, item);
stream.Flush();
}
}
void SaveFolder(InventoryFolderWithChildren folder)
{
string filename = String.Format("{0}-{1}.folder", SanitizeFilename(folder.Name), folder.ID);
string path = Path.Combine(DEFAULT_INVENTORY_DIR, folder.Owner.ToString());
path = Path.Combine(path, filename);
using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write))
{
folderSerializer.Serialize(stream, folder);
stream.Flush();
}
}
string SanitizeFilename(string filename)
{
string output = filename;
if (output.Length > 64)
output = output.Substring(0, 64);
foreach (char i in Path.GetInvalidFileNameChars())
output = output.Replace(i, '_');
return output;
}
static string PathFromURI(Uri uri)
{
byte[] hash = OpenMetaverse.Utils.SHA1(Encoding.UTF8.GetBytes(uri.ToString()));
StringBuilder digest = new StringBuilder(40);
// Convert the hash to a hex string
foreach (byte b in hash)
digest.AppendFormat(OpenMetaverse.Utils.EnUsCulture, "{0:x2}", b);
return Path.Combine(DEFAULT_INVENTORY_DIR, digest.ToString());
}
void LoadFiles(string folder)
{
// Try to create the directory if it doesn't already exist
if (!Directory.Exists(folder))
{
try { Directory.CreateDirectory(folder); }
catch (Exception ex)
{
m_log.Warn("[SIMPLEINVENTORYSTORAGE]: " + ex.Message);
return;
}
}
try
{
string[] agentFolders = Directory.GetDirectories(DEFAULT_INVENTORY_DIR);
for (int i = 0; i < agentFolders.Length; i++)
{
string foldername = agentFolders[i];
string indexPath = Path.Combine(foldername, "index.txt");
UUID ownerID = UUID.Zero;
Uri owner = null;
try
{
string[] index = File.ReadAllLines(indexPath);
ownerID = UUID.Parse(index[0]);
owner = new Uri(index[1]);
}
catch (Exception ex)
{
m_log.WarnFormat("[SIMPLEINVENTORYSTORAGE]: Failed loading the index file {0}: {1}", indexPath, ex.Message);
}
if (ownerID != UUID.Zero && owner != null)
{
// Initialize the active gestures list for this agent
activeGestures.Add(owner, new List<InventoryItemBase>());
InventoryCollection collection = new InventoryCollection();
collection.UserID = ownerID;
// Load all of the folders for this agent
string[] folders = Directory.GetFiles(foldername, "*.folder", SearchOption.TopDirectoryOnly);
collection.Folders = new Dictionary<UUID,InventoryFolderWithChildren>(folders.Length);
for (int j = 0; j < folders.Length; j++)
{
InventoryFolderWithChildren invFolder = (InventoryFolderWithChildren)folderSerializer.Deserialize(
new FileStream(folders[j], FileMode.Open, FileAccess.Read));
collection.Folders[invFolder.ID] = invFolder;
}
// Iterate over the folders collection, adding children to their parents
foreach (InventoryFolderWithChildren invFolder in collection.Folders.Values)
{
InventoryFolderWithChildren parent;
if (collection.Folders.TryGetValue(invFolder.ParentID, out parent))
parent.Children[invFolder.ID] = invFolder;
}
// Load all of the items for this agent
string[] files = Directory.GetFiles(foldername, "*.item", SearchOption.TopDirectoryOnly);
collection.Items = new Dictionary<UUID, InventoryItemBase>(files.Length);
for (int j = 0; j < files.Length; j++)
{
InventoryItemBase invItem = (InventoryItemBase)itemSerializer.Deserialize(
new FileStream(files[j], FileMode.Open, FileAccess.Read));
collection.Items[invItem.ID] = invItem;
// Add items to their parent folders
InventoryFolderWithChildren parent;
if (collection.Folders.TryGetValue(invItem.Folder, out parent))
parent.Children[invItem.ID] = invItem;
// Add active gestures to our list
if (invItem.InvType == (int)InventoryType.Gesture && invItem.Flags != 0)
activeGestures[owner].Add(invItem);
}
inventories.Add(owner, collection);
}
}
}
catch (Exception ex)
{
m_log.ErrorFormat("[SIMPLEINVENTORYSTORAGE]: Failed loading inventory from {0}: {1}", folder, ex.Message);
}
}
#region IPlugin implementation
public void Initialise(AssetInventoryServer server)
{
this.server = server;
LoadFiles(DEFAULT_INVENTORY_DIR);
m_log.InfoFormat("[SIMPLEINVENTORYSTORAGE]: Initialized the inventory index with data for {0} avatars",
inventories.Count);
}
/// <summary>
/// <para>Initialises asset interface</para>
/// </summary>
public void Initialise()
{
m_log.InfoFormat("[SIMPLEINVENTORYSTORAGE]: {0} cannot be default-initialized!", Name);
throw new PluginNotInitialisedException(Name);
}
public void Dispose()
{
}
public string Version
{
// TODO: this should be something meaningful and not hardcoded?
get { return "0.1"; }
}
public string Name
{
get { return "SimpleInventoryStorage"; }
}
#endregion IPlugin implementation
}
}

View File

@ -1,71 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.IO;
using OpenMetaverse;
namespace OpenSim.Grid.AssetInventoryServer.Plugins.Simple
{
public static class SimpleUtils
{
public static string ParseNameFromFilename(string filename)
{
filename = Path.GetFileName(filename);
int dot = filename.LastIndexOf('.');
int firstDash = filename.IndexOf('-');
if (dot - 37 > 0 && firstDash > 0)
return filename.Substring(0, firstDash);
else
return String.Empty;
}
public static UUID ParseUUIDFromFilename(string filename)
{
int dot = filename.LastIndexOf('.');
if (dot > 35)
{
// Grab the last 36 characters of the filename
string uuidString = filename.Substring(dot - 36, 36);
UUID uuid;
UUID.TryParse(uuidString, out uuid);
return uuid;
}
else
{
UUID uuid;
if (UUID.TryParse(Path.GetFileName(filename), out uuid))
return uuid;
else
return UUID.Zero;
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -987,128 +987,6 @@
</Files>
</Project>
<Project frameworkVersion="v3_5" name="OpenSim.Grid.AssetInventoryServer" path="OpenSim/Grid/AssetInventoryServer" type="Exe">
<Configuration name="Debug">
<Options>
<OutputPath>../../../bin/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../../bin/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../../bin/</ReferencePath>
<Reference name="System"/>
<Reference name="System.Xml"/>
<Reference name="OpenMetaverseTypes"/>
<Reference name="OpenMetaverse.StructuredData"/>
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.AssetLoader.Filesystem"/>
<Reference name="Nini.dll" />
<Reference name="log4net"/>
<Files>
<Match pattern="*.cs" recurse="false"/>
</Files>
</Project>
<Project frameworkVersion="v3_5" name="OpenSim.Grid.AssetInventoryServer.Plugins" path="OpenSim/Grid/AssetInventoryServer/Plugins" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../../../../bin/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../../../bin/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../../../bin/</ReferencePath>
<Reference name="System"/>
<Reference name="System.Xml"/>
<Reference name="System.Web"/>
<Reference name="OpenMetaverseTypes"/>
<Reference name="OpenMetaverse.StructuredData"/>
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Serialization"/>
<Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Grid.AssetInventoryServer" />
<Reference name="log4net"/>
<Files>
<Match pattern="*.cs" recurse="false" />
<Match path="Resources" pattern="*.addin.xml" buildAction="EmbeddedResource" recurse="true" />
</Files>
</Project>
<Project frameworkVersion="v3_5" name="OpenSim.Grid.AssetInventoryServer.Plugins.Simple" path="OpenSim/Grid/AssetInventoryServer/Plugins/Simple" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../../../../../bin/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../../../../bin/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../../../../bin/</ReferencePath>
<Reference name="System"/>
<Reference name="System.Xml" />
<Reference name="OpenMetaverse"/>
<Reference name="OpenMetaverseTypes"/>
<Reference name="OpenSim.Framework" />
<Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Grid.AssetInventoryServer" />
<Reference name="log4net"/>
<Files>
<Match pattern="*.cs" recurse="false" />
<Match path="Resources" pattern="*.addin.xml" buildAction="EmbeddedResource" recurse="true" />
</Files>
</Project>
<Project frameworkVersion="v3_5" name="OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim" path="OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../../../../../bin/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../../../../bin/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../../../../bin/</ReferencePath>
<Reference name="System"/>
<Reference name="System.Xml" />
<Reference name="System.Data" />
<Reference name="OpenMetaverseTypes"/>
<Reference name="OpenSim.Data" />
<Reference name="OpenSim.Framework" />
<Reference name="OpenSim.Framework.Communications" />
<Reference name="OpenSim.Grid.AssetInventoryServer" />
<Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="log4net"/>
<Reference name="Nini.dll" />
<Files>
<Match pattern="*.cs" recurse="false" />
<Match path="Resources" pattern="*.addin.xml" buildAction="EmbeddedResource" recurse="true" />
</Files>
</Project>
<Project frameworkVersion="v3_5" name="OpenSim.Grid.UserServer.Modules" path="OpenSim/Grid/UserServer.Modules" type="Library">
<Configuration name="Debug">
<Options>