From 8d304725518424131fa42dce1515137e0bb1eada Mon Sep 17 00:00:00 2001 From: Mike Mazur Date: Mon, 16 Feb 2009 02:25:25 +0000 Subject: Rename NewAssetServer AssetInventoryServer and fully qualify with OpenSim.Grid.AssetInventoryServer. --- .../MySQL/Resources/OpenSim.Data.MySQL.addin.xml | 2 +- .../AssetInventoryServer/AssetInventoryServer.cs | 263 +++++ .../Extensions/AuthorizeAll.cs | 78 ++ .../Extensions/BrowseFrontend.cs | 125 +++ .../Extensions/DBConnString.cs | 78 ++ .../Extensions/NullAuthentication.cs | 68 ++ .../AssetInventoryServer/Extensions/NullMetrics.cs | 124 +++ .../Extensions/OpenSimFrontend.cs | 215 ++++ .../Extensions/OpenSimInventoryFrontend.cs | 636 ++++++++++++ .../Extensions/OpenSimMySQLInventory.cs | 804 +++++++++++++++ .../Extensions/OpenSimMySQLStorage.cs | 311 ++++++ .../Extensions/ReferenceFrontend.cs | 239 +++++ .../Extensions/SimpleInventory.cs | 602 ++++++++++++ .../Extensions/SimpleStorage.cs | 260 +++++ .../AssetInventoryServer/Extensions/SimpleUtils.cs | 44 + OpenSim/Grid/AssetInventoryServer/Interfaces.cs | 157 +++ .../Grid/AssetInventoryServer/InventoryObjects.cs | 107 ++ OpenSim/Grid/AssetInventoryServer/Logger.cs | 62 ++ OpenSim/Grid/AssetInventoryServer/Main.cs | 62 ++ OpenSim/Grid/AssetInventoryServer/Metadata.cs | 85 ++ .../Plugins/OpenSim/OpenSimAssetStoragePlugin.cs | 352 +++++++ .../AssetInventoryServerOpenSimPlugins.addin.xml | 14 + OpenSim/Grid/AssetInventoryServer/Utils.cs | 1034 ++++++++++++++++++++ OpenSim/Grid/NewAssetServer/AssetServer.cs | 262 ----- .../Grid/NewAssetServer/Extensions/AuthorizeAll.cs | 78 -- .../NewAssetServer/Extensions/BrowseFrontend.cs | 125 --- .../Grid/NewAssetServer/Extensions/DBConnString.cs | 78 -- .../Extensions/NullAuthentication.cs | 68 -- .../Grid/NewAssetServer/Extensions/NullMetrics.cs | 124 --- .../NewAssetServer/Extensions/OpenSimFrontend.cs | 215 ---- .../Extensions/OpenSimInventoryFrontend.cs | 636 ------------ .../Extensions/OpenSimMySQLInventory.cs | 804 --------------- .../Extensions/OpenSimMySQLStorage.cs | 311 ------ .../NewAssetServer/Extensions/ReferenceFrontend.cs | 239 ----- .../NewAssetServer/Extensions/SimpleInventory.cs | 602 ------------ .../NewAssetServer/Extensions/SimpleStorage.cs | 260 ----- .../Grid/NewAssetServer/Extensions/SimpleUtils.cs | 44 - OpenSim/Grid/NewAssetServer/Interfaces.cs | 157 --- OpenSim/Grid/NewAssetServer/InventoryObjects.cs | 107 -- OpenSim/Grid/NewAssetServer/Logger.cs | 62 -- OpenSim/Grid/NewAssetServer/Main.cs | 62 -- OpenSim/Grid/NewAssetServer/Metadata.cs | 85 -- .../Plugins/OpenSim/OpenSimAssetStoragePlugin.cs | 352 ------- .../Resources/AssetServerOpenSimPlugins.addin.xml | 14 - OpenSim/Grid/NewAssetServer/Utils.cs | 1034 -------------------- bin/AssetInventoryServer.ini.example | 153 +++ bin/AssetServer.ini.example | 153 --- bin/OpenSim.Grid.AssetInventoryServer.addin.xml | 21 + bin/OpenSim.Grid.NewAssetServer.addin.xml | 21 - prebuild.xml | 10 +- 50 files changed, 5900 insertions(+), 5899 deletions(-) create mode 100644 OpenSim/Grid/AssetInventoryServer/AssetInventoryServer.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/Extensions/AuthorizeAll.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/Extensions/BrowseFrontend.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/Extensions/DBConnString.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/Extensions/NullAuthentication.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/Extensions/NullMetrics.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimFrontend.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimInventoryFrontend.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLInventory.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLStorage.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/Extensions/ReferenceFrontend.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/Extensions/SimpleInventory.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/Extensions/SimpleStorage.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/Extensions/SimpleUtils.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/Interfaces.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/InventoryObjects.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/Logger.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/Main.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/Metadata.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimAssetStoragePlugin.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/Resources/AssetInventoryServerOpenSimPlugins.addin.xml create mode 100644 OpenSim/Grid/AssetInventoryServer/Utils.cs delete mode 100644 OpenSim/Grid/NewAssetServer/AssetServer.cs delete mode 100644 OpenSim/Grid/NewAssetServer/Extensions/AuthorizeAll.cs delete mode 100644 OpenSim/Grid/NewAssetServer/Extensions/BrowseFrontend.cs delete mode 100644 OpenSim/Grid/NewAssetServer/Extensions/DBConnString.cs delete mode 100644 OpenSim/Grid/NewAssetServer/Extensions/NullAuthentication.cs delete mode 100644 OpenSim/Grid/NewAssetServer/Extensions/NullMetrics.cs delete mode 100644 OpenSim/Grid/NewAssetServer/Extensions/OpenSimFrontend.cs delete mode 100644 OpenSim/Grid/NewAssetServer/Extensions/OpenSimInventoryFrontend.cs delete mode 100644 OpenSim/Grid/NewAssetServer/Extensions/OpenSimMySQLInventory.cs delete mode 100644 OpenSim/Grid/NewAssetServer/Extensions/OpenSimMySQLStorage.cs delete mode 100644 OpenSim/Grid/NewAssetServer/Extensions/ReferenceFrontend.cs delete mode 100644 OpenSim/Grid/NewAssetServer/Extensions/SimpleInventory.cs delete mode 100644 OpenSim/Grid/NewAssetServer/Extensions/SimpleStorage.cs delete mode 100644 OpenSim/Grid/NewAssetServer/Extensions/SimpleUtils.cs delete mode 100644 OpenSim/Grid/NewAssetServer/Interfaces.cs delete mode 100644 OpenSim/Grid/NewAssetServer/InventoryObjects.cs delete mode 100644 OpenSim/Grid/NewAssetServer/Logger.cs delete mode 100644 OpenSim/Grid/NewAssetServer/Main.cs delete mode 100644 OpenSim/Grid/NewAssetServer/Metadata.cs delete mode 100644 OpenSim/Grid/NewAssetServer/Plugins/OpenSim/OpenSimAssetStoragePlugin.cs delete mode 100644 OpenSim/Grid/NewAssetServer/Plugins/OpenSim/Resources/AssetServerOpenSimPlugins.addin.xml delete mode 100644 OpenSim/Grid/NewAssetServer/Utils.cs create mode 100644 bin/AssetInventoryServer.ini.example delete mode 100644 bin/AssetServer.ini.example create mode 100644 bin/OpenSim.Grid.AssetInventoryServer.addin.xml delete mode 100644 bin/OpenSim.Grid.NewAssetServer.addin.xml diff --git a/OpenSim/Data/MySQL/Resources/OpenSim.Data.MySQL.addin.xml b/OpenSim/Data/MySQL/Resources/OpenSim.Data.MySQL.addin.xml index 9f583a2..281e3af 100644 --- a/OpenSim/Data/MySQL/Resources/OpenSim.Data.MySQL.addin.xml +++ b/OpenSim/Data/MySQL/Resources/OpenSim.Data.MySQL.addin.xml @@ -4,7 +4,7 @@ - + diff --git a/OpenSim/Grid/AssetInventoryServer/AssetInventoryServer.cs b/OpenSim/Grid/AssetInventoryServer/AssetInventoryServer.cs new file mode 100644 index 0000000..2c588f5 --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/AssetInventoryServer.cs @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2008 Intel Corporation + * All rights reserved. + * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 INTEL OR ITS + * 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.IO; +using System.Net; +using System.Reflection; +using System.Security.Cryptography.X509Certificates; +using System.ServiceProcess; +using ExtensionLoader; +using ExtensionLoader.Config; +using HttpServer; +using log4net; +using OpenSim.Framework; + +namespace OpenSim.Grid.AssetInventoryServer +{ + public class AssetInventoryServer : ServiceBase + { + public const string CONFIG_FILE = "AssetInventoryServer.ini"; + + public WebServer HttpServer; + public IniConfigSource ConfigFile; + + public IAssetStorageProvider StorageProvider; + public IInventoryProvider InventoryProvider; + public IAuthenticationProvider AuthenticationProvider; + public IAuthorizationProvider AuthorizationProvider; + public IMetricsProvider MetricsProvider; + + public AssetInventoryServer() + { + this.ServiceName = "OpenSimAssetInventoryServer"; + } + + public bool Start() + { + Logger.Log.Info("Starting Asset Server"); + List extensionList = null; + int port = 0; + X509Certificate2 serverCert = null; + + try { ConfigFile = new IniConfigSource(CONFIG_FILE); } + catch (Exception) + { + Logger.Log.Error("Failed to load the config file " + CONFIG_FILE); + return false; + } + + try + { + IConfig extensionConfig = ConfigFile.Configs["Config"]; + + // Load the port number to listen on + port = extensionConfig.GetInt("ListenPort"); + + // Load the server certificate file + string certFile = extensionConfig.GetString("SSLCertFile"); + if (!String.IsNullOrEmpty(certFile)) + serverCert = new X509Certificate2(certFile); + } + catch (Exception) + { + Logger.Log.Error("Failed to load [Config] section from " + CONFIG_FILE); + return false; + } + + try + { + // Load the extension list (and ordering) from our config file + IConfig extensionConfig = ConfigFile.Configs["Extensions"]; + extensionList = new List(extensionConfig.GetKeys()); + } + catch (Exception) + { + Logger.Log.Error("Failed to load [Extensions] section from " + CONFIG_FILE); + return false; + } + + //try + //{ + // // Create a reference list for C# extensions compiled at runtime + // List references = new List(); + // references.Add("OpenMetaverseTypes.dll"); + // references.Add("OpenMetaverse.dll"); + // references.Add("OpenMetaverse.StructuredData.dll"); + // references.Add("OpenMetaverse.Http.dll"); + // references.Add("ExtensionLoader.dll"); + // references.Add("AssetServer.exe"); + + // // Get a list of all of the members of AssetServer that are interfaces + // List assignables = ExtensionLoader.GetInterfaces(this); + + // // Load all of the extensions + // ExtensionLoader.LoadAllExtensions( + // Assembly.GetExecutingAssembly(), + // Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), + // extensionList, + // references, + // "AssetServer.*.dll", + // "AssetServer.*.cs", + // this, + // assignables); + //} + //catch (ExtensionException ex) + //{ + // Logger.Log.Error("Interface loading failed, shutting down: " + ex.Message); + // if (ex.InnerException != null) + // Logger.Log.Error(ex.InnerException.Message, ex.InnerException); + // Stop(); + // return false; + //} + + StorageProvider = LoadAssetInventoryServerPlugin() as IAssetStorageProvider; + + try + { + InitHttpServer(port, serverCert); + } + catch (Exception ex) + { + Logger.Log.Error("Initializing the HTTP server failed, shutting down: " + ex.Message); + Stop(); + return false; + } + + // Start all of the extensions + //foreach (IExtension extension in ExtensionLoader.Extensions) + //{ + // Logger.Log.Info("Starting extension " + extension.GetType().Name); + // extension.Start(this); + //} + + return true; + } + + public void Shutdown() + { + foreach (IExtension extension in ExtensionLoader.Extensions) + { + Logger.Log.Debug("Disposing extension " + extension.GetType().Name); + try { extension.Stop(); } + catch (Exception ex) + { Logger.Log.ErrorFormat("Failure shutting down extension {0}: {1}", extension.GetType().Name, ex.Message); } + } + + if (HttpServer != null) + HttpServer.Stop(); + } + + void InitHttpServer(int port, X509Certificate serverCert) + { + if (serverCert != null) + HttpServer = new WebServer(IPAddress.Any, port, serverCert, null, false); + else + HttpServer = new WebServer(IPAddress.Any, port); + + HttpServer.LogWriter = new log4netLogWriter(Logger.Log); + + HttpServer.Set404Handler( + delegate(IHttpClientContext client, IHttpRequest request, IHttpResponse response) + { + Logger.Log.Warn("Requested page was not found: " + request.Uri.PathAndQuery); + + string notFoundString = "Page Not FoundThe requested page or method was not found"; + byte[] buffer = System.Text.Encoding.UTF8.GetBytes(notFoundString); + response.Body.Write(buffer, 0, buffer.Length); + response.Status = HttpStatusCode.NotFound; + return true; + } + ); + + HttpServer.Start(); + + Logger.Log.Info("Asset server is listening on port " + port); + } + + #region ServiceBase Overrides + + protected override void OnStart(string[] args) + { + Start(); + } + protected override void OnStop() + { + Shutdown(); + } + + #endregion + + private IAssetInventoryServerPlugin LoadAssetInventoryServerPlugin() + { + PluginLoader loader = new PluginLoader(new AssetInventoryServerPluginInitialiser(this)); + + //loader.Add ("/OpenSim/AssetInventoryServer/StorageProvider", new PluginProviderFilter (provider)); + //loader.Add("/OpenSim/AssetInventoryServer/StorageProvider", new PluginCountConstraint(1)); + loader.Add("/OpenSim/AssetInventoryServer/StorageProvider"); + loader.Load(); + + return loader.Plugin; + } + } + + public class log4netLogWriter : ILogWriter + { + ILog Log; + + public log4netLogWriter(ILog log) + { + Log = log; + } + + public void Write(object source, LogPrio prio, string message) + { + switch (prio) + { + case LogPrio.Trace: + case LogPrio.Debug: + Log.DebugFormat("{0}: {1}", source, message); + break; + case LogPrio.Info: + Log.InfoFormat("{0}: {1}", source, message); + break; + case LogPrio.Warning: + Log.WarnFormat("{0}: {1}", source, message); + break; + case LogPrio.Error: + Log.ErrorFormat("{0}: {1}", source, message); + break; + case LogPrio.Fatal: + Log.FatalFormat("{0}: {1}", source, message); + break; + } + } + } +} diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/AuthorizeAll.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/AuthorizeAll.cs new file mode 100644 index 0000000..a4a2226 --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Extensions/AuthorizeAll.cs @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2008 Intel Corporation + * All rights reserved. + * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 INTEL OR ITS + * 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 ExtensionLoader; +using OpenMetaverse; + +namespace OpenSim.Grid.AssetInventoryServer.Extensions +{ + public class AuthorizeAll : IExtension, IAuthorizationProvider + { + AssetInventoryServer server; + + public AuthorizeAll() + { + } + + public void Start(AssetInventoryServer server) + { + this.server = server; + } + + public void Stop() + { + } + + 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; + } + } +} diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/BrowseFrontend.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/BrowseFrontend.cs new file mode 100644 index 0000000..ba4c4e2 --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Extensions/BrowseFrontend.cs @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2008 Intel Corporation + * All rights reserved. + * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 INTEL OR ITS + * 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.Collections.Specialized; +using System.Net; +using System.Text; +using System.Web; +using ExtensionLoader; +using OpenMetaverse; +using HttpServer; + +namespace OpenSim.Grid.AssetInventoryServer.Extensions +{ + public class BrowseFrontend : IExtension + { + AssetInventoryServer server; + + public BrowseFrontend() + { + } + + public void Start(AssetInventoryServer server) + { + this.server = server; + + // Request for / or /?... + server.HttpServer.AddHandler("get", null, @"(^/$)|(^/\?.*)", BrowseRequestHandler); + } + + public void Stop() + { + } + + bool BrowseRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) + { + const int ASSETS_PER_PAGE = 25; + const string HEADER = "Asset Server"; + const string TABLE_HEADER = + ""; + const string TABLE_FOOTER = "
NameDescriptionTypeIDTemporarySHA-1
"; + const string FOOTER = ""; + + UUID authToken = Utils.GetAuthToken(request); + + StringBuilder html = new StringBuilder(); + int start = 0; + uint page = 0; + + if (!String.IsNullOrEmpty(request.Uri.Query)) + { + NameValueCollection query = HttpUtility.ParseQueryString(request.Uri.Query); + if (!String.IsNullOrEmpty(query["page"]) && UInt32.TryParse(query["page"], out page)) + start = (int)page * ASSETS_PER_PAGE; + } + + html.AppendLine(HEADER); + + html.AppendLine("

"); + if (page > 0) + html.AppendFormat("< Previous Page | ", request.Uri.AbsolutePath, page - 1); + html.AppendFormat("Next Page >", request.Uri.AbsolutePath, page + 1); + html.AppendLine("

"); + + html.AppendLine(TABLE_HEADER); + + server.StorageProvider.ForEach( + delegate(Metadata data) + { + if (server.AuthorizationProvider.IsMetadataAuthorized(authToken, data.ID)) + { + html.AppendLine(String.Format( + "{0}{1}{2}{3}{4}{5}", + data.Name, data.Description, data.ContentType, data.ID, data.Temporary, + BitConverter.ToString(data.SHA1).Replace("-", String.Empty))); + } + else + { + html.AppendLine(String.Format( + "[Protected Asset]  {0}{1} ", + data.ID, data.Temporary)); + } + }, start, ASSETS_PER_PAGE + ); + + html.AppendLine(TABLE_FOOTER); + + html.AppendLine(FOOTER); + + byte[] responseData = System.Text.Encoding.UTF8.GetBytes(html.ToString()); + + response.Status = HttpStatusCode.OK; + response.Body.Write(responseData, 0, responseData.Length); + response.Body.Flush(); + return true; + } + } +} diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/DBConnString.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/DBConnString.cs new file mode 100644 index 0000000..58054d6 --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Extensions/DBConnString.cs @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2008 Intel Corporation + * All rights reserved. + * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 INTEL OR ITS + * 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.Xml; +using ExtensionLoader.Config; +using MySql.Data.MySqlClient; + +namespace OpenSim.Grid.AssetInventoryServer.Extensions +{ + public static class DBConnString + { + private static string connectionString; + + /// + /// Parses the MySQL connection string out of either the asset server + /// .ini or a OpenSim-style .xml file and caches the result for future + /// requests + /// + public static string GetConnectionString(IniConfigSource configFile) + { + if (connectionString == null) + { + // Try parsing from the ini file + try + { + // Load the extension list (and ordering) from our config file + IConfig extensionConfig = configFile.Configs["MySQL"]; + connectionString = extensionConfig.GetString("database_connect", null); + } + catch (Exception) { } + + if (connectionString != null) + { + // Force MySQL's broken connection pooling off + MySqlConnectionStringBuilder builder = new MySqlConnectionStringBuilder(connectionString); + builder.Pooling = false; + if (String.IsNullOrEmpty(builder.Database)) + Logger.Log.Error("No database selected in the connectionString: " + connectionString); + connectionString = builder.ToString(); + } + else + { + Logger.Log.Error("Database connection string is missing, check that the database_connect line is " + + "correct and uncommented in AssetInventoryServer.ini"); + } + } + + return connectionString; + } + } +} diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/NullAuthentication.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/NullAuthentication.cs new file mode 100644 index 0000000..796d80c --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Extensions/NullAuthentication.cs @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2008 Intel Corporation + * All rights reserved. + * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 INTEL OR ITS + * 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 ExtensionLoader; +using OpenMetaverse; + +namespace OpenSim.Grid.AssetInventoryServer.Extensions +{ + public class NullAuthentication : IExtension, IAuthenticationProvider + { + AssetInventoryServer server; + + public NullAuthentication() + { + } + + public void Start(AssetInventoryServer server) + { + this.server = server; + } + + public void Stop() + { + } + + 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; + } + } +} diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/NullMetrics.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/NullMetrics.cs new file mode 100644 index 0000000..c00203b --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Extensions/NullMetrics.cs @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2008 Intel Corporation + * All rights reserved. + * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 INTEL OR ITS + * 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 ExtensionLoader; +using OpenMetaverse; + +namespace OpenSim.Grid.AssetInventoryServer.Extensions +{ + public class NullMetrics : IExtension, IMetricsProvider + { + AssetInventoryServer server; + + public NullMetrics() + { + } + + public void Start(AssetInventoryServer server) + { + this.server = server; + } + + public void Stop() + { + } + + public void LogAssetMetadataFetch(string extension, BackendResponse response, UUID assetID, DateTime time) + { + Logger.Log.DebugFormat("[{0}] AssetMetadataFetch(): AssetID: {1}, Response: {2}", extension, assetID, response); + } + + public void LogAssetDataFetch(string extension, BackendResponse response, UUID assetID, int dataSize, DateTime time) + { + Logger.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) + { + Logger.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) + { + Logger.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) + { + Logger.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) + { + Logger.Log.DebugFormat("[{0}] InventoryFetchFolderList(): OwnerID: {1}, Response: {2}", extension, + owner, response); + } + + public void LogInventoryFetchInventory(string extension, BackendResponse response, Uri owner, DateTime time) + { + Logger.Log.DebugFormat("[{0}] InventoryFetchInventory(): OwnerID: {1}, Response: {2}", extension, + owner, response); + } + + public void LogInventoryFetchActiveGestures(string extension, BackendResponse response, Uri owner, DateTime time) + { + Logger.Log.DebugFormat("[{0}] InventoryFetchActiveGestures(): OwnerID: {1}, Response: {2}", extension, + owner, response); + } + + public void LogInventoryCreate(string extension, BackendResponse response, Uri owner, bool folder, DateTime time) + { + Logger.Log.DebugFormat("[{0}] InventoryCreate(): OwnerID: {1}, Response: {2}", extension, + owner, response); + } + + public void LogInventoryCreateInventory(string extension, BackendResponse response, DateTime time) + { + Logger.Log.DebugFormat("[{0}] InventoryCreateInventory(): Response: {1}", extension, + response); + } + + public void LogInventoryDelete(string extension, BackendResponse response, Uri owner, UUID objID, bool folder, DateTime time) + { + Logger.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) + { + Logger.Log.DebugFormat("[{0}] InventoryPurgeFolder(): OwnerID: {1}, FolderID: {2}, Response: {3}", extension, + owner, response); + } + } +} diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimFrontend.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimFrontend.cs new file mode 100644 index 0000000..4fff5e9 --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimFrontend.cs @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2008 Intel Corporation + * All rights reserved. + * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 INTEL OR ITS + * 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.Net; +using System.IO; +using System.Xml; +using ExtensionLoader; +using OpenMetaverse; +using HttpServer; + +namespace OpenSim.Grid.AssetInventoryServer.Extensions +{ + public class OpenSimFrontend : IExtension + { + AssetInventoryServer server; + + public OpenSimFrontend() + { + } + + public void Start(AssetInventoryServer server) + { + this.server = server; + + // Asset request + server.HttpServer.AddHandler("get", null, @"^/assets/", AssetRequestHandler); + + // Asset creation + server.HttpServer.AddHandler("post", null, @"^/assets/", AssetPostHandler); + } + + public void Stop() + { + } + + bool AssetRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) + { + UUID assetID; + // Split the URL up to get the asset ID out + string[] rawUrl = request.Uri.PathAndQuery.Split('/'); + + if (rawUrl.Length >= 3 && rawUrl[2].Length >= 36 && UUID.TryParse(rawUrl[2].Substring(0, 36), out assetID)) + { + Metadata metadata; + byte[] assetData; + BackendResponse dataResponse; + + if ((dataResponse = server.StorageProvider.TryFetchDataMetadata(assetID, out metadata, out assetData)) == BackendResponse.Success) + { + MemoryStream stream = new MemoryStream(); + + XmlWriterSettings settings = new XmlWriterSettings(); + settings.Indent = true; + XmlWriter writer = XmlWriter.Create(stream, settings); + + writer.WriteStartDocument(); + writer.WriteStartElement("AssetBase"); + writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance"); + writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema"); + writer.WriteStartElement("FullID"); + writer.WriteStartElement("Guid"); + writer.WriteString(assetID.ToString()); + writer.WriteEndElement(); + writer.WriteEndElement(); + writer.WriteStartElement("ID"); + writer.WriteString(assetID.ToString()); + writer.WriteEndElement(); + writer.WriteStartElement("Data"); + writer.WriteBase64(assetData, 0, assetData.Length); + writer.WriteEndElement(); + writer.WriteStartElement("Type"); + writer.WriteValue(Utils.ContentTypeToSLAssetType(metadata.ContentType)); + writer.WriteEndElement(); + writer.WriteStartElement("Name"); + writer.WriteString(metadata.Name); + writer.WriteEndElement(); + writer.WriteStartElement("Description"); + writer.WriteString(metadata.Description); + writer.WriteEndElement(); + writer.WriteStartElement("Local"); + writer.WriteValue(false); + writer.WriteEndElement(); + writer.WriteStartElement("Temporary"); + writer.WriteValue(metadata.Temporary); + writer.WriteEndElement(); + writer.WriteEndElement(); + writer.WriteEndDocument(); + + writer.Flush(); + byte[] buffer = stream.GetBuffer(); + + response.Status = HttpStatusCode.OK; + response.ContentType = "application/xml"; + response.ContentLength = stream.Length; + response.Body.Write(buffer, 0, (int)stream.Length); + response.Body.Flush(); + } + else + { + Logger.Log.WarnFormat("Failed to fetch asset data or metadata for {0}: {1}", assetID, dataResponse); + response.Status = HttpStatusCode.NotFound; + } + } + else + { + Logger.Log.Warn("Unrecognized OpenSim asset request: " + request.Uri.PathAndQuery); + } + + return true; + } + + bool AssetPostHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) + { + byte[] assetData = null; + Metadata metadata = new Metadata(); + + Logger.Log.Debug("Handling OpenSim asset upload"); + + try + { + using (XmlReader reader = XmlReader.Create(request.Body)) + { + reader.MoveToContent(); + reader.ReadStartElement("AssetBase"); + + reader.ReadStartElement("FullID"); + UUID.TryParse(reader.ReadElementContentAsString("Guid", String.Empty), out metadata.ID); + reader.ReadEndElement(); + reader.ReadStartElement("ID"); + reader.Skip(); + reader.ReadEndElement(); + + // HACK: Broken on Mono. https://bugzilla.novell.com/show_bug.cgi?id=464229 + //int readBytes = 0; + //byte[] buffer = new byte[1024]; + //MemoryStream stream = new MemoryStream(); + //BinaryWriter writer = new BinaryWriter(stream); + //while ((readBytes = reader.ReadElementContentAsBase64(buffer, 0, buffer.Length)) > 0) + // writer.Write(buffer, 0, readBytes); + //writer.Flush(); + //assetData = stream.GetBuffer(); + //Array.Resize(ref assetData, (int)stream.Length); + + assetData = Convert.FromBase64String(reader.ReadElementContentAsString()); + + int type; + Int32.TryParse(reader.ReadElementContentAsString("Type", String.Empty), out type); + metadata.ContentType = Utils.SLAssetTypeToContentType(type); + metadata.Name = reader.ReadElementContentAsString("Name", String.Empty); + metadata.Description = reader.ReadElementContentAsString("Description", String.Empty); + Boolean.TryParse(reader.ReadElementContentAsString("Local", String.Empty), out metadata.Temporary); + Boolean.TryParse(reader.ReadElementContentAsString("Temporary", String.Empty), out metadata.Temporary); + + reader.ReadEndElement(); + } + + if (assetData != null && assetData.Length > 0) + { + metadata.SHA1 = OpenMetaverse.Utils.SHA1(assetData); + metadata.CreationDate = DateTime.Now; + + BackendResponse storageResponse = server.StorageProvider.TryCreateAsset(metadata, assetData); + + if (storageResponse == BackendResponse.Success) + response.Status = HttpStatusCode.Created; + else if (storageResponse == BackendResponse.NotFound) + response.Status = HttpStatusCode.NotFound; + else + response.Status = HttpStatusCode.InternalServerError; + } + else + { + Logger.Log.Warn("AssetPostHandler called with no asset data"); + response.Status = HttpStatusCode.BadRequest; + } + } + catch (Exception ex) + { + Logger.Log.Warn("Failed to parse POST data (expecting AssetBase): " + ex.Message); + response.Status = HttpStatusCode.BadRequest; + } + + Logger.Log.Debug("Finished handling OpenSim asset upload, Status: " + response.Status.ToString()); + return true; + } + } +} diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimInventoryFrontend.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimInventoryFrontend.cs new file mode 100644 index 0000000..a0ebba5 --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimInventoryFrontend.cs @@ -0,0 +1,636 @@ +/* + * Copyright (c) 2008 Intel Corporation + * All rights reserved. + * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 INTEL OR ITS + * 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.Net; +using System.IO; +using System.Xml; +using ExtensionLoader; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using HttpServer; + +namespace OpenSim.Grid.AssetInventoryServer.Extensions +{ + public class OpenSimInventoryFrontend : IExtension + { + AssetInventoryServer server; + Utils.InventoryItemSerializer itemSerializer = new Utils.InventoryItemSerializer(); + Utils.InventoryFolderSerializer folderSerializer = new Utils.InventoryFolderSerializer(); + Utils.InventoryCollectionSerializer collectionSerializer = new Utils.InventoryCollectionSerializer(); + + public OpenSimInventoryFrontend() + { + } + + public void Start(AssetInventoryServer server) + { + this.server = server; + + server.HttpServer.AddHandler("post", null, @"^/GetInventory/", GetInventoryHandler); + server.HttpServer.AddHandler("post", null, @"^/CreateInventory/", CreateInventoryHandler); + server.HttpServer.AddHandler("post", null, @"^/NewFolder/", NewFolderHandler); + server.HttpServer.AddHandler("post", null, @"^/UpdateFolder/", UpdateFolderHandler); + server.HttpServer.AddHandler("post", null, @"^/MoveFolder/", MoveFolderHandler); + server.HttpServer.AddHandler("post", null, @"^/PurgeFolder/", PurgeFolderHandler); + server.HttpServer.AddHandler("post", null, @"^/NewItem/", NewItemHandler); + server.HttpServer.AddHandler("post", null, @"^/DeleteItem/", DeleteItemHandler); + server.HttpServer.AddHandler("post", null, @"^/RootFolders/", RootFoldersHandler); + server.HttpServer.AddHandler("post", null, @"^/ActiveGestures/", ActiveGesturesHandler); + } + + public void Stop() + { + } + + bool GetInventoryHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) + { + UUID sessionID, agentID; + UUID ownerID = DeserializeUUID(request.Body, out agentID, out sessionID); + + if (ownerID != UUID.Zero) + { + Logger.Log.Warn("GetInventory is not scalable on some inventory backends, avoid calling it wherever possible"); + + Uri owner = Utils.GetOpenSimUri(ownerID); + InventoryCollection inventory; + BackendResponse storageResponse = server.InventoryProvider.TryFetchInventory(owner, out inventory); + + if (storageResponse == BackendResponse.Success) + { + collectionSerializer.Serialize(response.Body, inventory); + response.Body.Flush(); + } + 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(); + inventory.Items = new Dictionary(); + collectionSerializer.Serialize(response.Body, inventory); + response.Body.Flush(); + } + else + { + response.Status = HttpStatusCode.InternalServerError; + } + } + else + { + response.Status = HttpStatusCode.BadRequest; + } + + return true; + } + + bool CreateInventoryHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) + { + UUID ownerID = DeserializeUUID(request.Body); + + if (ownerID != UUID.Zero) + { + Uri owner = Utils.GetOpenSimUri(ownerID); + Logger.Log.DebugFormat("Created URI {0} for inventory creation", owner); + + InventoryFolder rootFolder = new InventoryFolder("My Inventory", ownerID, UUID.Zero, (short)AssetType.Folder); + BackendResponse storageResponse = server.InventoryProvider.TryCreateInventory(owner, rootFolder); + if (storageResponse == BackendResponse.Success) + { + 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); + + SerializeBool(response.Body, true); + return true; + } + } + + SerializeBool(response.Body, false); + return true; + } + + bool NewFolderHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) + { + UUID agentID, sessionID; + InventoryFolder folder = DeserializeFolder(request.Body, 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. If this is the case we + // need to look up the name first + if (String.IsNullOrEmpty(folder.Name)) + { + InventoryFolder oldFolder; + if (server.InventoryProvider.TryFetchFolder(owner, folder.ID, out oldFolder) == BackendResponse.Success) + folder.Name = oldFolder.Name; + } + + BackendResponse storageResponse = server.InventoryProvider.TryCreateFolder(owner, folder); + + if (storageResponse == BackendResponse.Success) + { + SerializeBool(response.Body, true); + return true; + } + } + + SerializeBool(response.Body, false); + return true; + } + + bool UpdateFolderHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) + { + return NewFolderHandler(client, request, response); + } + + bool MoveFolderHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) + { + return NewFolderHandler(client, request, response); + } + + bool PurgeFolderHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) + { + UUID agentID, sessionID; + InventoryFolder folder = DeserializeFolder(request.Body, out agentID, out sessionID); + + if (folder != null) + { + Uri owner = Utils.GetOpenSimUri(folder.Owner); + BackendResponse storageResponse = server.InventoryProvider.TryPurgeFolder(owner, folder.ID); + + if (storageResponse == BackendResponse.Success) + { + SerializeBool(response.Body, true); + return true; + } + } + + SerializeBool(response.Body, false); + return true; + } + + bool NewItemHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) + { + UUID agentID, sessionID; + InventoryItem item = DeserializeItem(request.Body, out agentID, out sessionID); + + if (item != null) + { + Uri owner = Utils.GetOpenSimUri(agentID); + BackendResponse storageResponse = server.InventoryProvider.TryCreateItem(owner, item); + + if (storageResponse == BackendResponse.Success) + { + SerializeBool(response.Body, true); + return true; + } + } + + SerializeBool(response.Body, false); + return true; + } + + bool DeleteItemHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) + { + UUID agentID, sessionID; + InventoryItem item = DeserializeItem(request.Body, out agentID, out sessionID); + + if (item != null) + { + Uri owner = Utils.GetOpenSimUri(item.Owner); + BackendResponse storageResponse = server.InventoryProvider.TryDeleteItem(owner, item.ID); + + if (storageResponse == BackendResponse.Success) + { + SerializeBool(response.Body, true); + return true; + } + } + + SerializeBool(response.Body, false); + return true; + } + + bool RootFoldersHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) + { + UUID ownerID = DeserializeUUID(request.Body); + + if (ownerID != UUID.Zero) + { + Uri owner = Utils.GetOpenSimUri(ownerID); + List skeleton; + BackendResponse storageResponse = server.InventoryProvider.TryFetchFolderList(owner, out skeleton); + + if (storageResponse == BackendResponse.Success) + { + SerializeFolderList(response.Body, skeleton); + } + 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 + SerializeFolderList(response.Body, new List(0)); + } + else + { + response.Status = HttpStatusCode.InternalServerError; + } + } + else + { + response.Status = HttpStatusCode.BadRequest; + } + + return true; + } + + bool ActiveGesturesHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) + { + UUID ownerID = DeserializeUUID(request.Body); + + if (ownerID != UUID.Zero) + { + Uri owner = Utils.GetOpenSimUri(ownerID); + List gestures; + BackendResponse storageResponse = server.InventoryProvider.TryFetchActiveGestures(owner, out gestures); + + if (storageResponse == BackendResponse.Success) + { + SerializeItemList(response.Body, gestures); + } + else if (storageResponse == BackendResponse.NotFound) + { + // Return an empty set of gestures to match OpenSim.Grid.InventoryServer.exe behavior + SerializeItemList(response.Body, new List(0)); + } + else + { + response.Status = HttpStatusCode.InternalServerError; + } + } + else + { + response.Status = HttpStatusCode.BadRequest; + } + + return true; + } + + 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 server.InventoryProvider.TryCreateFolder(owner, folder); + } + + 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) + { + Logger.Log.Warn("Failed to parse POST data (expecting guid): " + ex.Message); + } + + return id; + } + + 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) + { + Logger.Log.Warn("Failed to parse GetInventory POST data: " + ex.Message); + agentID = UUID.Zero; + sessionID = UUID.Zero; + return UUID.Zero; + } + + return id; + } + + InventoryFolder DeserializeFolder(Stream stream, out UUID agentID, out UUID sessionID) + { + InventoryFolder folder = new InventoryFolder(); + + 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; + ReadUUID(reader, "Owner", out folder.Owner); + ReadUUID(reader, "ParentID", out folder.ParentID); + ReadUUID(reader, "ID", out folder.ID); + Int16.TryParse(reader.ReadElementContentAsString("Type", String.Empty), out folder.Type); + UInt16.TryParse(reader.ReadElementContentAsString("Version", String.Empty), out folder.Version); + reader.ReadEndElement(); + reader.ReadEndElement(); + } + } + catch (Exception ex) + { + Logger.Log.Warn("Failed to parse POST data (expecting InventoryFolderBase): " + ex.Message); + agentID = UUID.Zero; + sessionID = UUID.Zero; + return null; + } + + return folder; + } + + InventoryItem DeserializeItem(Stream stream, out UUID agentID, out UUID sessionID) + { + InventoryItem item = new InventoryItem(); + + 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"); + ReadUUID(reader, "ID", out item.ID); + Int32.TryParse(reader.ReadElementContentAsString("InvType", String.Empty), out item.InvType); + ReadUUID(reader, "Folder", out item.Folder); + ReadUUID(reader, "Owner", out item.Owner); + ReadUUID(reader, "Creator", out item.Creator); + item.Name = reader.ReadElementContentAsString("Name", String.Empty); + item.Description = reader.ReadElementContentAsString("Description", String.Empty); + UInt32.TryParse(reader.ReadElementContentAsString("NextPermissions", String.Empty), out item.NextPermissions); + UInt32.TryParse(reader.ReadElementContentAsString("CurrentPermissions", String.Empty), out item.CurrentPermissions); + UInt32.TryParse(reader.ReadElementContentAsString("BasePermissions", String.Empty), out item.BasePermissions); + UInt32.TryParse(reader.ReadElementContentAsString("EveryOnePermissions", String.Empty), out item.EveryOnePermissions); + UInt32.TryParse(reader.ReadElementContentAsString("GroupPermissions", String.Empty), out item.GroupPermissions); + Int32.TryParse(reader.ReadElementContentAsString("AssetType", String.Empty), out item.AssetType); + ReadUUID(reader, "AssetID", out item.AssetID); + ReadUUID(reader, "GroupID", out item.GroupID); + Boolean.TryParse(reader.ReadElementContentAsString("GroupOwned", String.Empty), out item.GroupOwned); + Int32.TryParse(reader.ReadElementContentAsString("SalePrice", String.Empty), out item.SalePrice); + Byte.TryParse(reader.ReadElementContentAsString("SaleType", String.Empty), out item.SaleType); + UInt32.TryParse(reader.ReadElementContentAsString("Flags", String.Empty), out item.Flags); + Int32.TryParse(reader.ReadElementContentAsString("CreationDate", String.Empty), out item.CreationDate); + reader.ReadEndElement(); + reader.ReadEndElement(); + } + } + catch (Exception ex) + { + Logger.Log.Warn("Failed to parse POST data (expecting InventoryItemBase): " + ex.Message); + agentID = UUID.Zero; + sessionID = UUID.Zero; + return null; + } + + return item; + } + + void SerializeBool(Stream stream, bool value) + { + using (XmlWriter writer = XmlWriter.Create(stream)) + { + 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(); + } + + stream.Flush(); + } + + void SerializeFolderList(Stream stream, List 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 (InventoryFolder 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(); + } + + void SerializeItemList(Stream stream, List 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 (InventoryItem 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); + WriteUUID(writer, "Creator", item.Creator); + 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(); + } + + void WriteUUID(XmlWriter writer, string name, UUID id) + { + writer.WriteStartElement(name); + writer.WriteElementString("Guid", XmlConvert.ToString(id.Guid)); + writer.WriteEndElement(); + } + + 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 + + /// + /// The different types of grid assets + /// + public enum AssetType : sbyte + { + /// Unknown asset type + Unknown = -1, + /// Texture asset, stores in JPEG2000 J2C stream format + Texture = 0, + /// Sound asset + Sound = 1, + /// Calling card for another avatar + CallingCard = 2, + /// Link to a location in world + Landmark = 3, + // Legacy script asset, you should never see one of these + //[Obsolete] + //Script = 4, + /// Collection of textures and parameters that can be + /// worn by an avatar + Clothing = 5, + /// Primitive that can contain textures, sounds, + /// scripts and more + Object = 6, + /// Notecard asset + Notecard = 7, + /// Holds a collection of inventory items + Folder = 8, + /// Root inventory folder + RootFolder = 9, + /// Linden scripting language script + LSLText = 10, + /// LSO bytecode for a script + LSLBytecode = 11, + /// Uncompressed TGA texture + TextureTGA = 12, + /// Collection of textures and shape parameters that can + /// be worn + Bodypart = 13, + /// Trash folder + TrashFolder = 14, + /// Snapshot folder + SnapshotFolder = 15, + /// Lost and found folder + LostAndFoundFolder = 16, + /// Uncompressed sound + SoundWAV = 17, + /// Uncompressed TGA non-square image, not to be used as a + /// texture + ImageTGA = 18, + /// Compressed JPEG non-square image, not to be used as a + /// texture + ImageJPEG = 19, + /// Animation + Animation = 20, + /// Sequence of animations, sounds, chat, and pauses + Gesture = 21, + /// Simstate file + Simstate = 22, + } + + #endregion OpenSim AssetType +} diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLInventory.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLInventory.cs new file mode 100644 index 0000000..7d6c0c2 --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLInventory.cs @@ -0,0 +1,804 @@ +/* + * Copyright (c) 2008 Intel Corporation + * All rights reserved. + * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 INTEL OR ITS + * 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.Net; +using System.Data; +using MySql.Data.MySqlClient; +using ExtensionLoader; +using ExtensionLoader.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +namespace OpenSim.Grid.AssetInventoryServer.Extensions +{ + public class OpenSimMySQLInventory : IExtension, IInventoryProvider + { + const string EXTENSION_NAME = "OpenSimMySQLInventory"; // Used in metrics reporting + + AssetInventoryServer server; + + public OpenSimMySQLInventory() + { + } + + #region Required Interfaces + + public void Start(AssetInventoryServer server) + { + this.server = server; + + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + try + { + dbConnection.Open(); + Logger.Log.Info("Connected to MySQL inventory backend: " + dbConnection.ServerVersion); + } + catch (MySqlException ex) + { + Logger.Log.Error("Connection to MySQL inventory backend failed: " + ex.Message); + } + } + } + + public void Stop() + { + } + + public BackendResponse TryFetchItem(Uri owner, UUID itemID, out InventoryItem item) + { + item = null; + BackendResponse ret; + + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + 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 InventoryItem(); + 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) + { + Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); + ret = BackendResponse.Failure; + } + } + + server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now); + return ret; + } + + public BackendResponse TryFetchFolder(Uri owner, UUID folderID, out InventoryFolder folder) + { + folder = null; + BackendResponse ret; + + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + IDataReader reader; + + try + { + dbConnection.Open(); + + IDbCommand command = dbConnection.CreateCommand(); + command.CommandText = String.Format("SELECT folderName,type,version,agentID,parentFolderID FROM inventoryfolders WHERE folderID='{0}'", + folderID.ToString()); + reader = command.ExecuteReader(); + + if (reader.Read()) + { + folder = new InventoryFolder(); + folder.Children = null; // This call only returns data for the folder itself, no children data + folder.ID = folderID; + folder.Name = reader.GetString(0); + folder.Type = reader.GetInt16(1); + folder.Version = (ushort)reader.GetInt16(2); + folder.Owner = UUID.Parse(reader.GetString(3)); + folder.ParentID = UUID.Parse(reader.GetString(4)); + + ret = BackendResponse.Success; + } + else + { + ret = BackendResponse.NotFound; + } + } + catch (MySqlException ex) + { + Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); + ret = BackendResponse.Failure; + } + } + + 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(DBConnString.GetConnectionString(server.ConfigFile))) + { + 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(); + + while (reader.Read()) + { + InventoryFolder folder = new InventoryFolder(); + 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(); + + while (reader.Read()) + { + InventoryItem item = new InventoryItem(); + 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) + { + Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); + ret = BackendResponse.Failure; + } + } + + server.MetricsProvider.LogInventoryFetchFolderContents(EXTENSION_NAME, ret, owner, folderID, DateTime.Now); + return ret; + } + + public BackendResponse TryFetchFolderList(Uri owner, out List folders) + { + folders = null; + BackendResponse ret; + UUID ownerID; + + if (Utils.TryGetOpenSimUUID(owner, out ownerID)) + { + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + IDataReader reader; + + try + { + dbConnection.Open(); + folders = new List(); + + IDbCommand command = dbConnection.CreateCommand(); + command.CommandText = String.Format("SELECT folderName,type,version,folderID,parentFolderID FROM inventoryfolders WHERE agentID='{0}'", + ownerID.ToString()); + reader = command.ExecuteReader(); + + while (reader.Read()) + { + InventoryFolder folder = new InventoryFolder(); + folder.Owner = ownerID; + folder.Children = null; // This call does not create a folder hierarchy + folder.Name = reader.GetString(0); + folder.Type = reader.GetInt16(1); + folder.Version = (ushort)reader.GetInt16(2); + folder.ID = UUID.Parse(reader.GetString(3)); + folder.ParentID = UUID.Parse(reader.GetString(4)); + + folders.Add(folder); + } + + ret = BackendResponse.Success; + } + catch (MySqlException ex) + { + Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); + ret = BackendResponse.Failure; + } + } + } + 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; + List folders; + UUID ownerID; + + ret = TryFetchFolderList(owner, out folders); + + if (ret == BackendResponse.Success) + { + // Add the retrieved folders to the inventory collection + inventory = new InventoryCollection(); + inventory.Folders = new Dictionary(folders.Count); + foreach (InventoryFolder folder in folders) + inventory.Folders[folder.ID] = folder; + + // Fetch inventory items + if (Utils.TryGetOpenSimUUID(owner, out ownerID)) + { + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + 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,inventoryID,parentFolderID,inventoryGroupPermissions FROM inventoryitems WHERE " + + "avatarID='{0}'", ownerID.ToString()); + reader = command.ExecuteReader(); + + inventory.UserID = ownerID; + inventory.Items = new Dictionary(); + + while (reader.Read()) + { + InventoryItem item = new InventoryItem(); + item.Owner = ownerID; + 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.ID = UUID.Parse(reader.GetString(16)); + item.Folder = UUID.Parse(reader.GetString(17)); + item.GroupPermissions = (uint)reader.GetInt32(18); + + inventory.Items.Add(item.ID, item); + } + + ret = BackendResponse.Success; + } + catch (MySqlException ex) + { + Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); + ret = BackendResponse.Failure; + } + } + } + else + { + ret = BackendResponse.NotFound; + } + } + + server.MetricsProvider.LogInventoryFetchInventory(EXTENSION_NAME, ret, owner, DateTime.Now); + return ret; + } + + public BackendResponse TryFetchActiveGestures(Uri owner, out List gestures) + { + gestures = null; + BackendResponse ret; + UUID ownerID; + + if (Utils.TryGetOpenSimUUID(owner, out ownerID)) + { + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + IDataReader reader; + + try + { + dbConnection.Open(); + + MySqlCommand command = new MySqlCommand("SELECT assetID,inventoryName,inventoryDescription,inventoryNextPermissions," + + "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," + + "creationDate,groupID,groupOwned,inventoryID,parentFolderID,inventoryGroupPermissions FROM inventoryitems WHERE " + + "avatarId=?uuid AND assetType=?type AND flags=1", dbConnection); + command.Parameters.AddWithValue("?uuid", ownerID.ToString()); + command.Parameters.AddWithValue("?type", (int)AssetType.Gesture); + reader = command.ExecuteReader(); + + while (reader.Read()) + { + InventoryItem item = new InventoryItem(); + item.Owner = ownerID; + item.AssetType = (int)AssetType.Gesture; + item.Flags = (uint)1; + item.AssetID = UUID.Parse(reader.GetString(0)); + item.Name = reader.GetString(1); + item.Description = reader.GetString(2); + item.NextPermissions = (uint)reader.GetInt32(3); + item.CurrentPermissions = (uint)reader.GetInt32(4); + item.InvType = reader.GetInt32(5); + item.Creator = UUID.Parse(reader.GetString(6)); + item.BasePermissions = (uint)reader.GetInt32(7); + item.EveryOnePermissions = (uint)reader.GetInt32(8); + item.SalePrice = reader.GetInt32(9); + item.SaleType = reader.GetByte(10); + item.CreationDate = reader.GetInt32(11); + item.GroupID = UUID.Parse(reader.GetString(12)); + item.GroupOwned = reader.GetBoolean(13); + item.ID = UUID.Parse(reader.GetString(14)); + item.Folder = UUID.Parse(reader.GetString(15)); + item.GroupPermissions = (uint)reader.GetInt32(16); + + gestures.Add(item); + } + + ret = BackendResponse.Success; + } + catch (MySqlException ex) + { + Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); + ret = BackendResponse.Failure; + } + } + } + else + { + ret = BackendResponse.NotFound; + } + + server.MetricsProvider.LogInventoryFetchActiveGestures(EXTENSION_NAME, ret, owner, DateTime.Now); + return ret; + } + + public BackendResponse TryCreateItem(Uri owner, InventoryItem item) + { + BackendResponse ret; + + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + try + { + dbConnection.Open(); + + MySqlCommand command = new MySqlCommand( + "REPLACE INTO inventoryitems (assetID,assetType,inventoryName,inventoryDescription,inventoryNextPermissions," + + "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," + + "creationDate,groupID,groupOwned,flags,inventoryID,avatarID,parentFolderID,inventoryGroupPermissions) VALUES " + + + "(?assetID,?assetType,?inventoryName,?inventoryDescription,?inventoryNextPermissions,?inventoryCurrentPermissions,?invType," + + "?creatorID,?inventoryBasePermissions,?inventoryEveryOnePermissions,?salePrice,?saleType,?creationDate,?groupID,?groupOwned," + + "?flags,?inventoryID,?avatarID,?parentFolderID,?inventoryGroupPermissions)", dbConnection); + + command.Parameters.AddWithValue("?assetID", item.AssetID.ToString()); + command.Parameters.AddWithValue("?assetType", item.AssetType); + command.Parameters.AddWithValue("?inventoryName", item.Name); + command.Parameters.AddWithValue("?inventoryDescription", item.Description); + command.Parameters.AddWithValue("?inventoryNextPermissions", item.NextPermissions); + command.Parameters.AddWithValue("?inventoryCurrentPermissions", item.CurrentPermissions); + command.Parameters.AddWithValue("?invType", item.InvType); + command.Parameters.AddWithValue("?creatorID", item.Creator.ToString()); + command.Parameters.AddWithValue("?inventoryBasePermissions", item.BasePermissions); + command.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.EveryOnePermissions); + command.Parameters.AddWithValue("?salePrice", item.SalePrice); + command.Parameters.AddWithValue("?saleType", item.SaleType); + command.Parameters.AddWithValue("?creationDate", item.CreationDate); + command.Parameters.AddWithValue("?groupID", item.GroupID.ToString()); + command.Parameters.AddWithValue("?groupOwned", item.GroupOwned); + command.Parameters.AddWithValue("?flags", item.Flags); + command.Parameters.AddWithValue("?inventoryID", item.ID); + command.Parameters.AddWithValue("?avatarID", item.Owner); + command.Parameters.AddWithValue("?parentFolderID", item.Folder); + command.Parameters.AddWithValue("?inventoryGroupPermissions", item.GroupPermissions); + + int rowsAffected = command.ExecuteNonQuery(); + if (rowsAffected == 1) + { + ret = BackendResponse.Success; + } + else if (rowsAffected == 2) + { + Logger.Log.Info("Replaced inventory item " + item.ID.ToString()); + ret = BackendResponse.Success; + } + else + { + Logger.Log.ErrorFormat("MySQL REPLACE query affected {0} rows", rowsAffected); + ret = BackendResponse.Failure; + } + } + catch (MySqlException ex) + { + Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); + ret = BackendResponse.Failure; + } + } + + server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, false, DateTime.Now); + return ret; + } + + public BackendResponse TryCreateFolder(Uri owner, InventoryFolder folder) + { + BackendResponse ret; + + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + try + { + dbConnection.Open(); + + MySqlCommand command = new MySqlCommand( + "REPLACE INTO inventoryfolders (folderName,type,version,folderID,agentID,parentFolderID) VALUES " + + "(?folderName,?type,?version,?folderID,?agentID,?parentFolderID)", dbConnection); + + command.Parameters.AddWithValue("?folderName", folder.Name); + command.Parameters.AddWithValue("?type", folder.Type); + command.Parameters.AddWithValue("?version", folder.Version); + command.Parameters.AddWithValue("?folderID", folder.ID); + command.Parameters.AddWithValue("?agentID", folder.Owner); + command.Parameters.AddWithValue("?parentFolderID", folder.ParentID); + + int rowsAffected = command.ExecuteNonQuery(); + if (rowsAffected == 1) + { + ret = BackendResponse.Success; + } + else if (rowsAffected == 2) + { + Logger.Log.Info("Replaced inventory folder " + folder.ID.ToString()); + ret = BackendResponse.Success; + } + else + { + Logger.Log.ErrorFormat("MySQL REPLACE query affected {0} rows", rowsAffected); + ret = BackendResponse.Failure; + } + } + catch (MySqlException ex) + { + Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); + ret = BackendResponse.Failure; + } + } + + server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, true, DateTime.Now); + return ret; + } + + public BackendResponse TryCreateInventory(Uri owner, InventoryFolder rootFolder) + { + return TryCreateFolder(owner, rootFolder); + } + + public BackendResponse TryDeleteItem(Uri owner, UUID itemID) + { + BackendResponse ret; + UUID ownerID; + + if (Utils.TryGetOpenSimUUID(owner, out ownerID)) + { + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + try + { + dbConnection.Open(); + + MySqlCommand command = new MySqlCommand( + "DELETE FROM inventoryitems WHERE inventoryID=?inventoryID AND avatarID=?avatarID", dbConnection); + + command.Parameters.AddWithValue("?inventoryID", itemID.ToString()); + command.Parameters.AddWithValue("?avatarID", ownerID.ToString()); + + int rowsAffected = command.ExecuteNonQuery(); + if (rowsAffected == 1) + { + ret = BackendResponse.Success; + } + else + { + Logger.Log.ErrorFormat("MySQL DELETE query affected {0} rows", rowsAffected); + ret = BackendResponse.NotFound; + } + } + catch (MySqlException ex) + { + Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); + ret = BackendResponse.Failure; + } + } + } + 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; + UUID ownerID; + + if (Utils.TryGetOpenSimUUID(owner, out ownerID)) + { + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + 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 + { + Logger.Log.ErrorFormat("MySQL DELETE query affected {0} rows", rowsAffected); + ret = BackendResponse.NotFound; + } + } + catch (MySqlException ex) + { + Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); + ret = BackendResponse.Failure; + } + } + } + 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; + UUID ownerID; + + if (Utils.TryGetOpenSimUUID(owner, out ownerID)) + { + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + try + { + dbConnection.Open(); + + #region Delete items + + MySqlCommand command = new MySqlCommand( + "DELETE FROM inventoryitems WHERE parentFolderID=?parentFolderID AND avatarID=?avatarID", dbConnection); + + command.Parameters.AddWithValue("?parentFolderID", folderID.ToString()); + command.Parameters.AddWithValue("?avatarID", ownerID.ToString()); + + int rowsAffected = command.ExecuteNonQuery(); + + #endregion Delete items + + #region Delete folders + + command = new MySqlCommand( + "DELETE FROM inventoryfolders WHERE parentFolderID=?parentFolderID AND agentID=?agentID", dbConnection); + + command.Parameters.AddWithValue("?parentFolderID", folderID.ToString()); + command.Parameters.AddWithValue("?agentID", ownerID.ToString()); + + rowsAffected += command.ExecuteNonQuery(); + + #endregion Delete folders + + Logger.Log.DebugFormat("Deleted {0} inventory objects from MySQL in a folder purge", rowsAffected); + + ret = BackendResponse.Success; + } + catch (MySqlException ex) + { + Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); + ret = BackendResponse.Failure; + } + } + } + else + { + ret = BackendResponse.NotFound; + } + + server.MetricsProvider.LogInventoryPurgeFolder(EXTENSION_NAME, ret, owner, folderID, DateTime.Now); + return ret; + } + + public int ForEach(Action action, int start, int count) + { + int rowCount = 0; + + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + 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) + { + Logger.Log.Error("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 Required Interfaces + } +} diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLStorage.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLStorage.cs new file mode 100644 index 0000000..36528b0 --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLStorage.cs @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2008 Intel Corporation + * All rights reserved. + * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 INTEL OR ITS + * 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.Net; +using System.Data; +using MySql.Data.MySqlClient; +using ExtensionLoader; +using ExtensionLoader.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +namespace OpenSim.Grid.AssetInventoryServer.Extensions +{ + public class OpenSimMySQLStorage : IExtension, IStorageProvider + { + const string EXTENSION_NAME = "OpenSimMySQLStorage"; // Used in metrics reporting + + AssetInventoryServer server; + + public OpenSimMySQLStorage() + { + } + + #region Required Interfaces + + public void Start(AssetInventoryServer server) + { + this.server = server; + + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + try + { + dbConnection.Open(); + Logger.Log.Info("Connected to MySQL storage backend: " + dbConnection.ServerVersion); + } + catch (MySqlException ex) + { + Logger.Log.Error("Connection to MySQL storage backend failed: " + ex.Message); + } + } + } + + public void Stop() + { + } + + public BackendResponse TryFetchMetadata(UUID assetID, out Metadata metadata) + { + metadata = null; + BackendResponse ret; + + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + IDataReader reader; + + try + { + dbConnection.Open(); + + IDbCommand command = dbConnection.CreateCommand(); + command.CommandText = String.Format("SELECT name,description,assetType,temporary FROM assets WHERE id='{0}'", assetID.ToString()); + reader = command.ExecuteReader(); + + if (reader.Read()) + { + metadata = new Metadata(); + metadata.CreationDate = OpenMetaverse.Utils.Epoch; + metadata.SHA1 = null; + metadata.ID = assetID; + metadata.Name = reader.GetString(0); + metadata.Description = reader.GetString(1); + metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2)); + metadata.Temporary = reader.GetBoolean(3); + + ret = BackendResponse.Success; + } + else + { + ret = BackendResponse.NotFound; + } + } + catch (MySqlException ex) + { + Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); + ret = BackendResponse.Failure; + } + } + + server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now); + return ret; + } + + public BackendResponse TryFetchData(UUID assetID, out byte[] assetData) + { + assetData = null; + BackendResponse ret; + + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + IDataReader reader; + + try + { + dbConnection.Open(); + + IDbCommand command = dbConnection.CreateCommand(); + command.CommandText = String.Format("SELECT data FROM assets WHERE id='{0}'", assetID.ToString()); + reader = command.ExecuteReader(); + + if (reader.Read()) + { + assetData = (byte[])reader.GetValue(0); + ret = BackendResponse.Success; + } + else + { + ret = BackendResponse.NotFound; + } + } + catch (MySqlException ex) + { + Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); + ret = BackendResponse.Failure; + } + } + + server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (assetData != null ? assetData.Length : 0), DateTime.Now); + return ret; + } + + public BackendResponse TryFetchDataMetadata(UUID assetID, out Metadata metadata, out byte[] assetData) + { + metadata = null; + assetData = null; + BackendResponse ret; + + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + IDataReader reader; + + try + { + dbConnection.Open(); + + IDbCommand command = dbConnection.CreateCommand(); + command.CommandText = String.Format("SELECT name,description,assetType,temporary,data FROM assets WHERE id='{0}'", assetID.ToString()); + reader = command.ExecuteReader(); + + if (reader.Read()) + { + metadata = new Metadata(); + metadata.CreationDate = OpenMetaverse.Utils.Epoch; + metadata.SHA1 = null; + metadata.ID = assetID; + metadata.Name = reader.GetString(0); + metadata.Description = reader.GetString(1); + metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2)); + metadata.Temporary = reader.GetBoolean(3); + + assetData = (byte[])reader.GetValue(4); + + ret = BackendResponse.Success; + } + else + { + ret = BackendResponse.NotFound; + } + } + catch (MySqlException ex) + { + Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); + ret = BackendResponse.Failure; + } + } + + server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now); + server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (assetData != null ? assetData.Length : 0), DateTime.Now); + return ret; + } + + public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData, out UUID assetID) + { + assetID = metadata.ID = UUID.Random(); + return TryCreateAsset(metadata, assetData); + } + + public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData) + { + BackendResponse ret; + + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + try + { + dbConnection.Open(); + + MySqlCommand command = new MySqlCommand( + "REPLACE INTO assets (name,description,assetType,local,temporary,data,id) VALUES " + + "(?name,?description,?assetType,?local,?temporary,?data,?id)", dbConnection); + + command.Parameters.AddWithValue("?name", metadata.Name); + command.Parameters.AddWithValue("?description", metadata.Description); + command.Parameters.AddWithValue("?assetType", Utils.ContentTypeToSLAssetType(metadata.ContentType)); + command.Parameters.AddWithValue("?local", 0); + command.Parameters.AddWithValue("?temporary", metadata.Temporary); + command.Parameters.AddWithValue("?data", assetData); + command.Parameters.AddWithValue("?id", metadata.ID.ToString()); + + int rowsAffected = command.ExecuteNonQuery(); + if (rowsAffected == 1) + { + ret = BackendResponse.Success; + } + else if (rowsAffected == 2) + { + Logger.Log.Info("Replaced asset " + metadata.ID.ToString()); + ret = BackendResponse.Success; + } + else + { + Logger.Log.ErrorFormat("MySQL REPLACE query affected {0} rows", rowsAffected); + ret = BackendResponse.Failure; + } + } + catch (MySqlException ex) + { + Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); + ret = BackendResponse.Failure; + } + } + + server.MetricsProvider.LogAssetCreate(EXTENSION_NAME, ret, metadata.ID, assetData.Length, DateTime.Now); + return ret; + } + + public int ForEach(Action action, int start, int count) + { + int rowCount = 0; + + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + 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) + { + Logger.Log.Error("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 Required Interfaces + } +} diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/ReferenceFrontend.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/ReferenceFrontend.cs new file mode 100644 index 0000000..454984e --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Extensions/ReferenceFrontend.cs @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2008 Intel Corporation + * All rights reserved. + * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 INTEL OR ITS + * 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.Net; +using System.Xml; +using ExtensionLoader; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using HttpServer; + +namespace OpenSim.Grid.AssetInventoryServer.Extensions +{ + public class ReferenceFrontend : IExtension + { + AssetInventoryServer server; + + public ReferenceFrontend() + { + } + + public void Start(AssetInventoryServer server) + { + this.server = server; + + // Asset metadata request + server.HttpServer.AddHandler("get", null, @"^/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/metadata", + MetadataRequestHandler); + + // Asset data request + server.HttpServer.AddHandler("get", null, @"^/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/data", + DataRequestHandler); + + // Asset creation + server.HttpServer.AddHandler("post", null, "^/createasset", CreateRequestHandler); + } + + public void Stop() + { + } + + bool MetadataRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) + { + UUID assetID; + // Split the URL up into an AssetID and a method + string[] rawUrl = request.Uri.PathAndQuery.Split('/'); + + if (rawUrl.Length >= 3 && UUID.TryParse(rawUrl[1], out assetID)) + { + UUID authToken = Utils.GetAuthToken(request); + + if (server.AuthorizationProvider.IsMetadataAuthorized(authToken, assetID)) + { + Metadata metadata; + BackendResponse storageResponse = 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", + request.Uri.Scheme, request.Uri.Authority, assetID)); + } + + byte[] serializedData = metadata.SerializeToBytes(); + + response.Status = HttpStatusCode.OK; + response.ContentType = "application/json"; + response.ContentLength = serializedData.Length; + response.Body.Write(serializedData, 0, serializedData.Length); + + } + else if (storageResponse == BackendResponse.NotFound) + { + Logger.Log.Warn("Could not find metadata for asset " + assetID.ToString()); + response.Status = HttpStatusCode.NotFound; + } + else + { + response.Status = HttpStatusCode.InternalServerError; + } + } + else + { + response.Status = HttpStatusCode.Forbidden; + } + + return true; + } + + response.Status = HttpStatusCode.NotFound; + return true; + } + + bool DataRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) + { + UUID assetID; + // Split the URL up into an AssetID and a method + string[] rawUrl = request.Uri.PathAndQuery.Split('/'); + + if (rawUrl.Length >= 3 && UUID.TryParse(rawUrl[1], out assetID)) + { + UUID authToken = Utils.GetAuthToken(request); + + if (server.AuthorizationProvider.IsDataAuthorized(authToken, assetID)) + { + byte[] assetData; + BackendResponse storageResponse = server.StorageProvider.TryFetchData(assetID, out assetData); + + if (storageResponse == BackendResponse.Success) + { + response.Status = HttpStatusCode.OK; + response.Status = HttpStatusCode.OK; + response.ContentType = "application/octet-stream"; + response.AddHeader("Content-Disposition", "attachment; filename=" + assetID.ToString()); + response.ContentLength = assetData.Length; + response.Body.Write(assetData, 0, assetData.Length); + } + else if (storageResponse == BackendResponse.NotFound) + { + response.Status = HttpStatusCode.NotFound; + } + else + { + response.Status = HttpStatusCode.InternalServerError; + } + } + else + { + response.Status = HttpStatusCode.Forbidden; + } + + return true; + } + + response.Status = HttpStatusCode.BadRequest; + return true; + } + + bool CreateRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) + { + UUID authToken = Utils.GetAuthToken(request); + + if (server.AuthorizationProvider.IsCreateAuthorized(authToken)) + { + try + { + OSD osdata = OSDParser.DeserializeJson(request.Body); + + 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 = server.StorageProvider.TryCreateAsset(metadata, assetData); + else + storageResponse = server.StorageProvider.TryCreateAsset(metadata, assetData, out metadata.ID); + + if (storageResponse == BackendResponse.Success) + { + response.Status = HttpStatusCode.Created; + OSDMap responseMap = new OSDMap(1); + responseMap["id"] = OSD.FromUUID(metadata.ID); + LitJson.JsonData jsonData = OSDParser.SerializeJson(responseMap); + byte[] responseData = System.Text.Encoding.UTF8.GetBytes(jsonData.ToJson()); + response.Body.Write(responseData, 0, responseData.Length); + response.Body.Flush(); + } + else if (storageResponse == BackendResponse.NotFound) + { + response.Status = HttpStatusCode.NotFound; + } + else + { + response.Status = HttpStatusCode.InternalServerError; + } + } + else + { + response.Status = HttpStatusCode.BadRequest; + } + } + else + { + response.Status = HttpStatusCode.BadRequest; + } + } + catch (Exception ex) + { + response.Status = HttpStatusCode.InternalServerError; + response.Reason = ex.Message; + } + } + else + { + response.Status = HttpStatusCode.Forbidden; + } + + return true; + } + } +} diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleInventory.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleInventory.cs new file mode 100644 index 0000000..f8acdea --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleInventory.cs @@ -0,0 +1,602 @@ +/* + * Copyright (c) 2008 Intel Corporation + * All rights reserved. + * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 INTEL OR ITS + * 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.Net; +using System.IO; +using System.Text; +using ExtensionLoader; +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +namespace OpenSim.Grid.AssetInventoryServer.Extensions +{ + public class SimpleInventory : IExtension, IInventoryProvider + { + const string EXTENSION_NAME = "SimpleInventory"; // Used for metrics reporting + const string DEFAULT_INVENTORY_DIR = "SimpleInventory"; + + AssetInventoryServer server; + Dictionary inventories = new Dictionary(); + Dictionary> activeGestures = new Dictionary>(); + Utils.InventoryItemSerializer itemSerializer = new Utils.InventoryItemSerializer(); + Utils.InventoryFolderSerializer folderSerializer = new Utils.InventoryFolderSerializer(); + + public SimpleInventory() + { + } + + #region Required Interfaces + + public void Start(AssetInventoryServer server) + { + this.server = server; + + LoadFiles(DEFAULT_INVENTORY_DIR); + + Logger.Log.InfoFormat("Initialized the inventory index with data for {0} avatars", + inventories.Count); + } + + public void Stop() + { + } + + public BackendResponse TryFetchItem(Uri owner, UUID itemID, out InventoryItem 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 InventoryFolder 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; + InventoryFolder folder; + + if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder)) + { + contents = new InventoryCollection(); + contents.UserID = collection.UserID; + contents.Folders = new Dictionary(); + contents.Items = new Dictionary(); + + foreach (InventoryBase invBase in folder.Children.Values) + { + if (invBase is InventoryItem) + { + InventoryItem invItem = invBase as InventoryItem; + contents.Items.Add(invItem.ID, invItem); + } + else + { + InventoryFolder invFolder = invBase as InventoryFolder; + 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 folders) + { + folders = null; + BackendResponse ret; + + InventoryCollection collection; + if (inventories.TryGetValue(owner, out collection)) + { + folders = new List(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 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, InventoryItem item) + { + BackendResponse ret; + + InventoryCollection collection; + if (inventories.TryGetValue(owner, out collection)) + { + // Delete this item first if it already exists + InventoryItem 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 + InventoryFolder 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) + { + Logger.Log.Error(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, InventoryFolder folder) + { + BackendResponse ret; + + InventoryCollection collection; + if (inventories.TryGetValue(owner, out collection)) + { + // Delete this folder first if it already exists + InventoryFolder 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 + InventoryFolder parent; + if (collection.Folders.TryGetValue(folder.ParentID, out parent)) + lock (parent.Children) parent.Children.Add(folder.ID, folder); + + ret = BackendResponse.Success; + } + catch (Exception ex) + { + Logger.Log.Error(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, InventoryFolder rootFolder) + { + BackendResponse ret; + + lock (inventories) + { + if (!inventories.ContainsKey(owner)) + { + InventoryCollection collection = new InventoryCollection(); + collection.UserID = rootFolder.Owner; + collection.Folders = new Dictionary(); + collection.Folders.Add(rootFolder.ID, rootFolder); + collection.Items = new Dictionary(); + + 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) + { + Logger.Log.Error(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; + InventoryItem item; + if (inventories.TryGetValue(owner, out collection) && collection.Items.TryGetValue(itemID, out item)) + { + // Remove the item from its parent folder + InventoryFolder 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) { Logger.Log.ErrorFormat("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; + InventoryFolder folder; + if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder)) + { + // Remove the folder from its parent folder + InventoryFolder 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) { Logger.Log.ErrorFormat("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; + InventoryFolder folder; + if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder)) + { + // Delete all of the folder children + foreach (InventoryBase obj in new List(folder.Children.Values)) + { + if (obj is InventoryItem) + { + TryDeleteItem(owner, (obj as InventoryItem).ID); + } + else + { + InventoryFolder childFolder = obj as InventoryFolder; + 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(InventoryItem 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(InventoryFolder 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) + { + Logger.Log.Warn(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) + { + Logger.Log.WarnFormat("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()); + + 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(folders.Length); + + for (int j = 0; j < folders.Length; j++) + { + InventoryFolder invFolder = (InventoryFolder)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 (InventoryFolder invFolder in collection.Folders.Values) + { + InventoryFolder 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(files.Length); + + for (int j = 0; j < files.Length; j++) + { + InventoryItem invItem = (InventoryItem)itemSerializer.Deserialize( + new FileStream(files[j], FileMode.Open, FileAccess.Read)); + collection.Items[invItem.ID] = invItem; + + // Add items to their parent folders + InventoryFolder 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) + { + Logger.Log.ErrorFormat("Failed loading inventory from {0}: {1}", folder, ex.Message); + } + } + } +} diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleStorage.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleStorage.cs new file mode 100644 index 0000000..c9cf138 --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleStorage.cs @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2008 Intel Corporation + * All rights reserved. + * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 INTEL OR ITS + * 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.Net; +using System.IO; +using ExtensionLoader; +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +namespace OpenSim.Grid.AssetInventoryServer.Extensions +{ + public class SimpleStorage : IExtension, IStorageProvider + { + const string EXTENSION_NAME = ""; // Used in metrics reporting + const string DEFAULT_DATA_DIR = "SimpleAssets"; + const string TEMP_DATA_DIR = "SimpleAssetsTemp"; + + AssetInventoryServer server; + Dictionary metadataStorage; + Dictionary filenames; + + public SimpleStorage() + { + } + + #region Required Interfaces + + public void Start(AssetInventoryServer server) + { + this.server = server; + metadataStorage = new Dictionary(); + filenames = new Dictionary(); + + LoadFiles(DEFAULT_DATA_DIR, false); + LoadFiles(TEMP_DATA_DIR, true); + + Logger.Log.InfoFormat("Initialized the store index with metadata for {0} assets", + metadataStorage.Count); + } + + public void Stop() + { + WipeTemporary(); + } + + public BackendResponse TryFetchMetadata(UUID assetID, out Metadata 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) + { + Logger.Log.ErrorFormat("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 Metadata metadata, out byte[] assetData) + { + metadata = null; + assetData = null; + string filename; + BackendResponse ret; + + if (metadataStorage.TryGetValue(assetID, out metadata) && + filenames.TryGetValue(assetID, out filename)) + { + try + { + assetData = File.ReadAllBytes(filename); + ret = BackendResponse.Success; + } + catch (Exception ex) + { + Logger.Log.ErrorFormat("Failed reading data for asset {0} from {1}: {2}", assetID, filename, ex.Message); + ret = BackendResponse.Failure; + } + } + else + { + ret = BackendResponse.NotFound; + } + + server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now); + server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (assetData != null ? assetData.Length : 0), DateTime.Now); + return ret; + } + + public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData, out UUID assetID) + { + assetID = metadata.ID = UUID.Random(); + return TryCreateAsset(metadata, assetData); + } + + public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData) + { + BackendResponse ret; + + string path; + string filename = String.Format("{0}.{1}", metadata.ID, Utils.ContentTypeToExtension(metadata.ContentType)); + + if (metadata.Temporary) + path = Path.Combine(TEMP_DATA_DIR, filename); + else + path = Path.Combine(DEFAULT_DATA_DIR, filename); + + try + { + File.WriteAllBytes(path, assetData); + lock (filenames) filenames[metadata.ID] = path; + + // Set the creation date to right now + metadata.CreationDate = DateTime.Now; + + lock (metadataStorage) + metadataStorage[metadata.ID] = metadata; + + ret = BackendResponse.Success; + } + catch (Exception ex) + { + Logger.Log.ErrorFormat("Failed writing data for asset {0} to {1}: {2}", metadata.ID, filename, ex.Message); + ret = BackendResponse.Failure; + } + + server.MetricsProvider.LogAssetCreate(EXTENSION_NAME, ret, metadata.ID, assetData.Length, DateTime.Now); + return ret; + } + + public int ForEach(Action action, int start, int count) + { + int rowCount = 0; + + lock (metadataStorage) + { + foreach (Metadata metadata in metadataStorage.Values) + { + action(metadata); + ++rowCount; + } + } + + return rowCount; + } + + #endregion Required Interfaces + + public void WipeTemporary() + { + if (Directory.Exists(TEMP_DATA_DIR)) + { + try { Directory.Delete(TEMP_DATA_DIR); } + catch (Exception ex) { Logger.Log.Error(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) + { + Logger.Log.Warn(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); + + Metadata metadata = new Metadata(); + metadata.CreationDate = File.GetCreationTime(filename); + metadata.Description = String.Empty; + metadata.ID = 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.ID] = metadata; + filenames[metadata.ID] = filename; + } + } + catch (Exception ex) + { + Logger.Log.Warn(ex.Message); + } + } + } + } +} diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleUtils.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleUtils.cs new file mode 100644 index 0000000..fe6491e --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleUtils.cs @@ -0,0 +1,44 @@ +using System; +using System.IO; +using OpenMetaverse; + +namespace OpenSim.Grid.AssetInventoryServer.Extensions +{ + 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; + } + } + } +} diff --git a/OpenSim/Grid/AssetInventoryServer/Interfaces.cs b/OpenSim/Grid/AssetInventoryServer/Interfaces.cs new file mode 100644 index 0000000..fd9ed2c --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Interfaces.cs @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2008 Intel Corporation + * All rights reserved. + * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 INTEL OR ITS + * 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.Net; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; + +namespace OpenSim.Grid.AssetInventoryServer +{ + /// + /// Response from a call to a backend provider + /// + public enum BackendResponse + { + /// The call succeeded + Success, + /// The resource requested was not found + NotFound, + /// A server failure prevented the call from + /// completing + 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 IStorageProvider + { + BackendResponse TryFetchMetadata(UUID assetID, out Metadata metadata); + BackendResponse TryFetchData(UUID assetID, out byte[] assetData); + BackendResponse TryFetchDataMetadata(UUID assetID, out Metadata metadata, out byte[] assetData); + BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData); + BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData, out UUID assetID); + int ForEach(Action action, int start, int count); + } + + public interface IAssetStorageProvider : IAssetInventoryServerPlugin + { + BackendResponse TryFetchMetadata(UUID assetID, out Metadata metadata); + BackendResponse TryFetchData(UUID assetID, out byte[] assetData); + BackendResponse TryFetchDataMetadata(UUID assetID, out Metadata metadata, out byte[] assetData); + BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData); + BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData, out UUID assetID); + int ForEach(Action action, int start, int count); + } + + public interface IInventoryProvider + { + BackendResponse TryFetchItem(Uri owner, UUID itemID, out InventoryItem item); + BackendResponse TryFetchFolder(Uri owner, UUID folderID, out InventoryFolder folder); + BackendResponse TryFetchFolderContents(Uri owner, UUID folderID, out InventoryCollection contents); + BackendResponse TryFetchFolderList(Uri owner, out List folders); + BackendResponse TryFetchInventory(Uri owner, out InventoryCollection inventory); + + BackendResponse TryFetchActiveGestures(Uri owner, out List gestures); + + BackendResponse TryCreateItem(Uri owner, InventoryItem item); + BackendResponse TryCreateFolder(Uri owner, InventoryFolder folder); + BackendResponse TryCreateInventory(Uri owner, InventoryFolder rootFolder); + + BackendResponse TryDeleteItem(Uri owner, UUID itemID); + BackendResponse TryDeleteFolder(Uri owner, UUID folderID); + BackendResponse TryPurgeFolder(Uri owner, UUID folderID); + } + + public interface IAuthenticationProvider + { + void AddIdentifier(UUID authToken, Uri identifier); + bool RemoveIdentifier(UUID authToken); + bool TryGetIdentifier(UUID authToken, out Uri identifier); + } + + public interface IAuthorizationProvider + { + bool IsMetadataAuthorized(UUID authToken, UUID assetID); + /// + /// Authorizes access to the data for an asset. Access to asset data + /// also implies access to the metadata for that asset + /// + /// Authentication token to check for access + /// ID of the requested asset + /// True if access is granted, otherwise false + 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 + { + 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 +} diff --git a/OpenSim/Grid/AssetInventoryServer/InventoryObjects.cs b/OpenSim/Grid/AssetInventoryServer/InventoryObjects.cs new file mode 100644 index 0000000..6f054ff --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/InventoryObjects.cs @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2008 Intel Corporation + * All rights reserved. + * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 INTEL OR ITS + * 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; + +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 Children = new Dictionary(); + + 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 InventoryCollection + { + public Dictionary Folders; + public Dictionary Items; + public UUID UserID; + } +} diff --git a/OpenSim/Grid/AssetInventoryServer/Logger.cs b/OpenSim/Grid/AssetInventoryServer/Logger.cs new file mode 100644 index 0000000..546e3c4 --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Logger.cs @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2008 Intel Corporation + * All rights reserved. + * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 INTEL OR ITS + * 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 log4net; +using log4net.Config; + +[assembly: log4net.Config.XmlConfigurator(ConfigFileExtension = "log4net")] + +namespace OpenSim.Grid.AssetInventoryServer +{ + /// + /// Singleton logging class for the entire library + /// + public static class Logger + { + /// log4net logging engine + public static ILog Log; + + static Logger() + { + Log = LogManager.GetLogger(System.Reflection.Assembly.GetExecutingAssembly().FullName); + + // If error level reporting isn't enabled we assume no logger is configured and initialize a default + // ConsoleAppender + if (!Log.Logger.IsEnabledFor(log4net.Core.Level.Error)) + { + log4net.Appender.ConsoleAppender appender = new log4net.Appender.ConsoleAppender(); + appender.Layout = new log4net.Layout.PatternLayout("%timestamp [%thread] %-5level - %message%newline"); + BasicConfigurator.Configure(appender); + + Log.Info("No log configuration found, defaulting to console logging"); + } + } + } +} diff --git a/OpenSim/Grid/AssetInventoryServer/Main.cs b/OpenSim/Grid/AssetInventoryServer/Main.cs new file mode 100644 index 0000000..69ed8c0 --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Main.cs @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2008 Intel Corporation + * All rights reserved. + * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 INTEL OR ITS + * 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.ServiceProcess; + +namespace OpenSim.Grid.AssetInventoryServer +{ + class MainEntry + { + static void Main(string[] args) + { +#if DEBUG + AssetInventoryServer server = new AssetInventoryServer(); + if (server.Start()) + { + Console.WriteLine("Asset server is running. Press CTRL+C to quit"); + + Console.CancelKeyPress += + delegate(object sender, ConsoleCancelEventArgs e) + { + Console.WriteLine("Asset server is shutting down..."); + server.Shutdown(); + Environment.Exit(0); + }; + + while (true) + Console.ReadLine(); + } +#else + ServiceBase[] servicesToRun = new ServiceBase[] { new AssetInventoryServer() }; + ServiceBase.Run(servicesToRun); +#endif + } + } +} diff --git a/OpenSim/Grid/AssetInventoryServer/Metadata.cs b/OpenSim/Grid/AssetInventoryServer/Metadata.cs new file mode 100644 index 0000000..3735ea4 --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Metadata.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Xml; +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +namespace OpenSim.Grid.AssetInventoryServer +{ + public class Metadata + { + public UUID ID; + public string Name; + public string Description; + public DateTime CreationDate; + public string ContentType; + public byte[] SHA1; + public bool Temporary; + public Dictionary Methods = new Dictionary(); + public OSDMap ExtraData; + + public OSDMap SerializeToOSD() + { + OSDMap osdata = new OSDMap(); + + if (ID != UUID.Zero) osdata["id"] = OSD.FromUUID(ID); + osdata["name"] = OSD.FromString(Name); + osdata["description"] = OSD.FromString(Description); + osdata["creation_date"] = OSD.FromDate(CreationDate); + osdata["type"] = OSD.FromString(ContentType); + osdata["sha1"] = OSD.FromBinary(SHA1); + osdata["temporary"] = OSD.FromBoolean(Temporary); + + OSDMap methods = new OSDMap(Methods.Count); + foreach (KeyValuePair kvp in Methods) + methods.Add(kvp.Key, OSD.FromUri(kvp.Value)); + osdata["methods"] = methods; + + if (ExtraData != null) osdata["extra_data"] = ExtraData; + + return osdata; + } + + public byte[] SerializeToBytes() + { + LitJson.JsonData jsonData = OSDParser.SerializeJson(SerializeToOSD()); + return System.Text.Encoding.UTF8.GetBytes(jsonData.ToJson()); + } + + public void Deserialize(byte[] data) + { + OSD osdata = OSDParser.DeserializeJson(System.Text.Encoding.UTF8.GetString(data)); + Deserialize(osdata); + } + + public void Deserialize(string data) + { + OSD osdata = OSDParser.DeserializeJson(data); + Deserialize(osdata); + } + + public void Deserialize(OSD osdata) + { + if (osdata.Type == OSDType.Map) + { + OSDMap map = (OSDMap)osdata; + ID = map["id"].AsUUID(); + Name = map["name"].AsString(); + Description = map["description"].AsString(); + CreationDate = map["creation_date"].AsDate(); + ContentType = map["type"].AsString(); + SHA1 = map["sha1"].AsBinary(); + Temporary = map["temporary"].AsBoolean(); + + OSDMap methods = map["methods"] as OSDMap; + if (methods != null) + { + foreach (KeyValuePair kvp in methods) + Methods.Add(kvp.Key, kvp.Value.AsUri()); + } + + ExtraData = map["extra_data"] as OSDMap; + } + } + } +} diff --git a/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimAssetStoragePlugin.cs b/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimAssetStoragePlugin.cs new file mode 100644 index 0000000..7f5f85a --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimAssetStoragePlugin.cs @@ -0,0 +1,352 @@ +/* + * Copyright (c) 2008 Intel Corporation + * All rights reserved. + * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 INTEL OR ITS + * 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.Net; +using System.Data; +using MySql.Data.MySqlClient; +using ExtensionLoader; +using ExtensionLoader.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Grid.AssetInventoryServer.Extensions; + +namespace OpenSim.Grid.AssetInventoryServer.Plugins +{ + public class OpenSimAssetStoragePlugin : IAssetStorageProvider + { + const string EXTENSION_NAME = "OpenSimAssetStorage"; // Used in metrics reporting + + private AssetInventoryServer server; + private IAssetProviderPlugin m_assetProvider; + + public OpenSimAssetStoragePlugin() + { + } + + #region IAssetStorageProvider implementation + + public BackendResponse TryFetchMetadata(UUID assetID, out Metadata metadata) + { + metadata = null; + BackendResponse ret; + + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + IDataReader reader; + + try + { + dbConnection.Open(); + + IDbCommand command = dbConnection.CreateCommand(); + command.CommandText = String.Format("SELECT name,description,assetType,temporary FROM assets WHERE id='{0}'", assetID.ToString()); + reader = command.ExecuteReader(); + + if (reader.Read()) + { + metadata = new Metadata(); + metadata.CreationDate = OpenMetaverse.Utils.Epoch; + metadata.SHA1 = null; + metadata.ID = assetID; + metadata.Name = reader.GetString(0); + metadata.Description = reader.GetString(1); + metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2)); + metadata.Temporary = reader.GetBoolean(3); + + ret = BackendResponse.Success; + } + else + { + ret = BackendResponse.NotFound; + } + } + catch (MySqlException ex) + { + Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); + ret = BackendResponse.Failure; + } + } + + server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now); + return ret; + } + + public BackendResponse TryFetchData(UUID assetID, out byte[] assetData) + { + assetData = null; + BackendResponse ret; + + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + IDataReader reader; + + try + { + dbConnection.Open(); + + IDbCommand command = dbConnection.CreateCommand(); + command.CommandText = String.Format("SELECT data FROM assets WHERE id='{0}'", assetID.ToString()); + reader = command.ExecuteReader(); + + if (reader.Read()) + { + assetData = (byte[])reader.GetValue(0); + ret = BackendResponse.Success; + } + else + { + ret = BackendResponse.NotFound; + } + } + catch (MySqlException ex) + { + Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); + ret = BackendResponse.Failure; + } + } + + server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (assetData != null ? assetData.Length : 0), DateTime.Now); + return ret; + } + + public BackendResponse TryFetchDataMetadata(UUID assetID, out Metadata metadata, out byte[] assetData) + { + metadata = null; + assetData = null; + BackendResponse ret; + + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + IDataReader reader; + + try + { + dbConnection.Open(); + + IDbCommand command = dbConnection.CreateCommand(); + command.CommandText = String.Format("SELECT name,description,assetType,temporary,data FROM assets WHERE id='{0}'", assetID.ToString()); + reader = command.ExecuteReader(); + + if (reader.Read()) + { + metadata = new Metadata(); + metadata.CreationDate = OpenMetaverse.Utils.Epoch; + metadata.SHA1 = null; + metadata.ID = assetID; + metadata.Name = reader.GetString(0); + metadata.Description = reader.GetString(1); + metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2)); + metadata.Temporary = reader.GetBoolean(3); + + assetData = (byte[])reader.GetValue(4); + + ret = BackendResponse.Success; + } + else + { + ret = BackendResponse.NotFound; + } + } + catch (MySqlException ex) + { + Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); + ret = BackendResponse.Failure; + } + } + + server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now); + server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (assetData != null ? assetData.Length : 0), DateTime.Now); + return ret; + } + + public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData, out UUID assetID) + { + assetID = metadata.ID = UUID.Random(); + return TryCreateAsset(metadata, assetData); + } + + public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData) + { + BackendResponse ret; + + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + try + { + dbConnection.Open(); + + MySqlCommand command = new MySqlCommand( + "REPLACE INTO assets (name,description,assetType,local,temporary,data,id) VALUES " + + "(?name,?description,?assetType,?local,?temporary,?data,?id)", dbConnection); + + command.Parameters.AddWithValue("?name", metadata.Name); + command.Parameters.AddWithValue("?description", metadata.Description); + command.Parameters.AddWithValue("?assetType", Utils.ContentTypeToSLAssetType(metadata.ContentType)); + command.Parameters.AddWithValue("?local", 0); + command.Parameters.AddWithValue("?temporary", metadata.Temporary); + command.Parameters.AddWithValue("?data", assetData); + command.Parameters.AddWithValue("?id", metadata.ID.ToString()); + + int rowsAffected = command.ExecuteNonQuery(); + if (rowsAffected == 1) + { + ret = BackendResponse.Success; + } + else if (rowsAffected == 2) + { + Logger.Log.Info("Replaced asset " + metadata.ID.ToString()); + ret = BackendResponse.Success; + } + else + { + Logger.Log.ErrorFormat("MySQL REPLACE query affected {0} rows", rowsAffected); + ret = BackendResponse.Failure; + } + } + catch (MySqlException ex) + { + Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); + ret = BackendResponse.Failure; + } + } + + server.MetricsProvider.LogAssetCreate(EXTENSION_NAME, ret, metadata.ID, assetData.Length, DateTime.Now); + return ret; + } + + public int ForEach(Action action, int start, int count) + { + int rowCount = 0; + + using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) + { + 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) + { + Logger.Log.Error("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 IAssetStorageProvider implementation + + #region IPlugin implementation + + public void Initialise(AssetInventoryServer server) + { + this.server = server; + + try + { + m_assetProvider = LoadDatabasePlugin("OpenSim.Data.MySQL.dll", server.ConfigFile.Configs["MySQL"].GetString("database_connect", null)); + if (m_assetProvider == null) + { + Logger.Log.Error("[ASSET]: Failed to load a database plugin, server halting."); + Environment.Exit(-1); + } + else + Logger.Log.InfoFormat("[ASSET]: Loaded storage backend: {0}", Version); + } + catch (Exception e) + { + Logger.Log.WarnFormat("[ASSET]: Failure loading data plugin: {0}", e.ToString()); + } + } + + /// + /// Initialises asset interface + /// + public void Initialise() + { + Logger.Log.InfoFormat("[ASSET]: {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 "AssetInventoryServer storage provider"; } + } + + #endregion IPlugin implementation + + private IAssetProviderPlugin LoadDatabasePlugin(string provider, string connect) + { + PluginLoader loader = new PluginLoader(new AssetDataInitialiser(connect)); + + // Loader will try to load all providers (MySQL, MSSQL, etc) + // unless it is constrainted to the correct "Provider" entry in the addin.xml + loader.Add("/OpenSim/AssetData", new PluginProviderFilter (provider)); + loader.Load(); + + return loader.Plugin; + } + } +} diff --git a/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/Resources/AssetInventoryServerOpenSimPlugins.addin.xml b/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/Resources/AssetInventoryServerOpenSimPlugins.addin.xml new file mode 100644 index 0000000..eeda54a --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/Resources/AssetInventoryServerOpenSimPlugins.addin.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/OpenSim/Grid/AssetInventoryServer/Utils.cs b/OpenSim/Grid/AssetInventoryServer/Utils.cs new file mode 100644 index 0000000..a81a0ba --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Utils.cs @@ -0,0 +1,1034 @@ +/* + * Copyright (c) 2008 Intel Corporation + * All rights reserved. + * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 INTEL OR ITS + * 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.Specialized; +using System.Globalization; +using System.Net; +using System.Xml; +using System.Xml.Serialization; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using HttpServer; + +namespace OpenSim.Grid.AssetInventoryServer +{ + public static class Utils + { + public static UUID GetAuthToken(IHttpRequest request) + { + UUID authToken = UUID.Zero; + + string[] authHeader = request.Headers.GetValues("Authorization"); + if (authHeader != null && authHeader.Length == 1) + { + // Example header: + // Authorization: OpenGrid 65fda0b5-4446-42f5-b828-aaf644293646 + string[] authHeaderParts = authHeader[0].Split(' '); + if (authHeaderParts.Length == 2 && authHeaderParts[0] == "OpenGrid") + UUID.TryParse(authHeaderParts[1], out authToken); + } + + if (authToken == UUID.Zero && request.Cookies != null) + { + // Check for an authToken cookie to make logins browser-compatible + RequestCookie authCookie = request.Cookies["authToken"]; + if (authCookie != null) + UUID.TryParse(authCookie.Value, out authToken); + } + + return authToken; + } + + public static Uri GetOpenSimUri(UUID avatarID) + { + return new Uri("http://opensim/" + avatarID.ToString()); + } + + public static bool TryGetOpenSimUUID(Uri avatarUri, out UUID avatarID) + { + string[] parts = avatarUri.Segments; + return UUID.TryParse(parts[parts.Length - 1], out avatarID); + } + + #region SL / file extension / content-type conversions + + public static string SLAssetTypeToContentType(int assetType) + { + switch (assetType) + { + case 0: + return "image/jp2"; + case 1: + return "application/ogg"; + case 2: + return "application/x-metaverse-callingcard"; + case 3: + return "application/x-metaverse-landmark"; + case 5: + return "application/x-metaverse-clothing"; + case 6: + return "application/x-metaverse-primitive"; + case 7: + return "application/x-metaverse-notecard"; + case 8: + return "application/x-metaverse-folder"; + case 10: + return "application/x-metaverse-lsl"; + case 11: + return "application/x-metaverse-lso"; + case 12: + return "image/tga"; + case 13: + return "application/x-metaverse-bodypart"; + case 17: + return "audio/x-wav"; + case 19: + return "image/jpeg"; + case 20: + return "application/x-metaverse-animation"; + case 21: + return "application/x-metaverse-gesture"; + case 22: + return "application/x-metaverse-simstate"; + default: + return "application/octet-stream"; + } + } + + public static int ContentTypeToSLAssetType(string contentType) + { + switch (contentType) + { + case "image/jp2": + return 0; + case "application/ogg": + return 1; + case "application/x-metaverse-callingcard": + return 2; + case "application/x-metaverse-landmark": + return 3; + case "application/x-metaverse-clothing": + return 5; + case "application/x-metaverse-primitive": + return 6; + case "application/x-metaverse-notecard": + return 7; + case "application/x-metaverse-lsl": + return 10; + case "application/x-metaverse-lso": + return 11; + case "image/tga": + return 12; + case "application/x-metaverse-bodypart": + return 13; + case "audio/x-wav": + return 17; + case "image/jpeg": + return 19; + case "application/x-metaverse-animation": + return 20; + case "application/x-metaverse-gesture": + return 21; + case "application/x-metaverse-simstate": + return 22; + default: + return -1; + } + } + + public static string ContentTypeToExtension(string contentType) + { + switch (contentType) + { + case "image/jp2": + return "texture"; + case "application/ogg": + return "ogg"; + case "application/x-metaverse-callingcard": + return "callingcard"; + case "application/x-metaverse-landmark": + return "landmark"; + case "application/x-metaverse-clothing": + return "clothing"; + case "application/x-metaverse-primitive": + return "primitive"; + case "application/x-metaverse-notecard": + return "notecard"; + case "application/x-metaverse-lsl": + return "lsl"; + case "application/x-metaverse-lso": + return "lso"; + case "image/tga": + return "tga"; + case "application/x-metaverse-bodypart": + return "bodypart"; + case "audio/x-wav": + return "wav"; + case "image/jpeg": + return "jpg"; + case "application/x-metaverse-animation": + return "animation"; + case "application/x-metaverse-gesture": + return "gesture"; + case "application/x-metaverse-simstate": + return "simstate"; + default: + return "bin"; + } + } + + public static string ExtensionToContentType(string extension) + { + switch (extension) + { + case "texture": + case "jp2": + case "j2c": + return "image/jp2"; + case "sound": + case "ogg": + return "application/ogg"; + case "callingcard": + return "application/x-metaverse-callingcard"; + case "landmark": + return "application/x-metaverse-landmark"; + case "clothing": + return "application/x-metaverse-clothing"; + case "primitive": + return "application/x-metaverse-primitive"; + case "notecard": + return "application/x-metaverse-notecard"; + case "lsl": + return "application/x-metaverse-lsl"; + case "lso": + return "application/x-metaverse-lso"; + case "tga": + return "image/tga"; + case "bodypart": + return "application/x-metaverse-bodypart"; + case "wav": + return "audio/x-wav"; + case "jpg": + case "jpeg": + return "image/jpeg"; + case "animation": + return "application/x-metaverse-animation"; + case "gesture": + return "application/x-metaverse-gesture"; + case "simstate": + return "application/x-metaverse-simstate"; + case "txt": + return "text/plain"; + case "xml": + return "application/xml"; + default: + return "application/octet-stream"; + } + } + + #endregion SL / file extension / content-type conversions + + #region XML Serialization + + public class GeneratedReader : XmlSerializationReader + { + public object ReadRoot_InventoryFolderBase() + { + Reader.MoveToContent(); + if (Reader.LocalName != "InventoryFolderBase" || Reader.NamespaceURI != "") + throw CreateUnknownNodeException(); + return ReadObject_InventoryFolder(true, true); + } + + public object ReadRoot_InventoryItemBase() + { + Reader.MoveToContent(); + if (Reader.LocalName != "InventoryItemBase" || Reader.NamespaceURI != "") + throw CreateUnknownNodeException(); + return ReadObject_InventoryItem(true, true); + } + + public object ReadRoot_InventoryCollection() + { + Reader.MoveToContent(); + if (Reader.LocalName != "InventoryCollection" || Reader.NamespaceURI != "") + throw CreateUnknownNodeException(); + return ReadObject_InventoryCollection(true, true); + } + + public InventoryFolder ReadObject_InventoryFolder(bool isNullable, bool checkType) + { + InventoryFolder ob = null; + if (isNullable && ReadNull()) return null; + + if (checkType) + { + System.Xml.XmlQualifiedName t = GetXsiType(); + if (t == null) + { } + else if (t.Name != "InventoryFolderBase" || t.Namespace != "") + throw CreateUnknownTypeException(t); + } + + ob = (InventoryFolder)Activator.CreateInstance(typeof(InventoryFolder), true); + + Reader.MoveToElement(); + + while (Reader.MoveToNextAttribute()) + { + if (IsXmlnsAttribute(Reader.Name)) + { + } + else + { + UnknownNode(ob); + } + } + + Reader.MoveToElement(); + Reader.MoveToElement(); + if (Reader.IsEmptyElement) + { + Reader.Skip(); + return ob; + } + + Reader.ReadStartElement(); + Reader.MoveToContent(); + + bool b0 = false, b1 = false, b2 = false, b3 = false, b4 = false, b5 = false; + + while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) + { + if (Reader.NodeType == System.Xml.XmlNodeType.Element) + { + if (Reader.LocalName == "Owner" && Reader.NamespaceURI == "" && !b1) + { + b1 = true; + ob.@Owner = ReadObject_UUID(false, true); + } + else if (Reader.LocalName == "Version" && Reader.NamespaceURI == "" && !b5) + { + b5 = true; + string s6 = Reader.ReadElementString(); + ob.@Version = UInt16.Parse(s6, CultureInfo.InvariantCulture); + } + else if (Reader.LocalName == "ID" && Reader.NamespaceURI == "" && !b3) + { + b3 = true; + ob.@ID = ReadObject_UUID(false, true); + } + else if (Reader.LocalName == "Type" && Reader.NamespaceURI == "" && !b4) + { + b4 = true; + string s7 = Reader.ReadElementString(); + ob.@Type = Int16.Parse(s7, CultureInfo.InvariantCulture); + } + else if (Reader.LocalName == "Name" && Reader.NamespaceURI == "" && !b0) + { + b0 = true; + string s8 = Reader.ReadElementString(); + ob.@Name = s8; + } + else if (Reader.LocalName == "ParentID" && Reader.NamespaceURI == "" && !b2) + { + b2 = true; + ob.@ParentID = ReadObject_UUID(false, true); + } + else + { + UnknownNode(ob); + } + } + else + UnknownNode(ob); + + Reader.MoveToContent(); + } + + ReadEndElement(); + + return ob; + } + + public InventoryItem ReadObject_InventoryItem(bool isNullable, bool checkType) + { + InventoryItem ob = null; + if (isNullable && ReadNull()) return null; + + if (checkType) + { + System.Xml.XmlQualifiedName t = GetXsiType(); + if (t == null) + { } + else if (t.Name != "InventoryItemBase" || t.Namespace != "") + throw CreateUnknownTypeException(t); + } + + ob = (InventoryItem)Activator.CreateInstance(typeof(InventoryItem), true); + + Reader.MoveToElement(); + + while (Reader.MoveToNextAttribute()) + { + if (IsXmlnsAttribute(Reader.Name)) + { + } + else + { + UnknownNode(ob); + } + } + + Reader.MoveToElement(); + Reader.MoveToElement(); + if (Reader.IsEmptyElement) + { + Reader.Skip(); + return ob; + } + + Reader.ReadStartElement(); + Reader.MoveToContent(); + + bool b9 = false, b10 = false, b11 = false, b12 = false, b13 = false, b14 = false, b15 = false, b16 = false, b17 = false, b18 = false, b19 = false, b20 = false, b21 = false, b22 = false, b23 = false, b24 = false, b25 = false, b26 = false, b27 = false, b28 = false; + + while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) + { + if (Reader.NodeType == System.Xml.XmlNodeType.Element) + { + if (Reader.LocalName == "GroupPermissions" && Reader.NamespaceURI == "" && !b20) + { + b20 = true; + string s29 = Reader.ReadElementString(); + ob.@GroupPermissions = UInt32.Parse(s29, CultureInfo.InvariantCulture); + } + else if (Reader.LocalName == "AssetType" && Reader.NamespaceURI == "" && !b21) + { + b21 = true; + string s30 = Reader.ReadElementString(); + ob.@AssetType = Int32.Parse(s30, CultureInfo.InvariantCulture); + } + else if (Reader.LocalName == "SalePrice" && Reader.NamespaceURI == "" && !b25) + { + b25 = true; + string s31 = Reader.ReadElementString(); + ob.@SalePrice = Int32.Parse(s31, CultureInfo.InvariantCulture); + } + else if (Reader.LocalName == "AssetID" && Reader.NamespaceURI == "" && !b22) + { + b22 = true; + ob.@AssetID = ReadObject_UUID(false, true); + } + else if (Reader.LocalName == "Folder" && Reader.NamespaceURI == "" && !b11) + { + b11 = true; + ob.@Folder = ReadObject_UUID(false, true); + } + else if (Reader.LocalName == "Name" && Reader.NamespaceURI == "" && !b14) + { + b14 = true; + string s32 = Reader.ReadElementString(); + ob.@Name = s32; + } + else if (Reader.LocalName == "NextPermissions" && Reader.NamespaceURI == "" && !b16) + { + b16 = true; + string s33 = Reader.ReadElementString(); + ob.@NextPermissions = UInt32.Parse(s33, CultureInfo.InvariantCulture); + } + else if (Reader.LocalName == "BasePermissions" && Reader.NamespaceURI == "" && !b18) + { + b18 = true; + string s34 = Reader.ReadElementString(); + ob.@BasePermissions = UInt32.Parse(s34, CultureInfo.InvariantCulture); + } + else if (Reader.LocalName == "ID" && Reader.NamespaceURI == "" && !b9) + { + b9 = true; + ob.@ID = ReadObject_UUID(false, true); + } + else if (Reader.LocalName == "Flags" && Reader.NamespaceURI == "" && !b27) + { + b27 = true; + string s35 = Reader.ReadElementString(); + ob.@Flags = UInt32.Parse(s35, CultureInfo.InvariantCulture); + } + else if (Reader.LocalName == "GroupOwned" && Reader.NamespaceURI == "" && !b24) + { + b24 = true; + string s36 = Reader.ReadElementString(); + ob.@GroupOwned = XmlConvert.ToBoolean(s36); + } + else if (Reader.LocalName == "InvType" && Reader.NamespaceURI == "" && !b10) + { + b10 = true; + string s37 = Reader.ReadElementString(); + ob.@InvType = Int32.Parse(s37, CultureInfo.InvariantCulture); + } + else if (Reader.LocalName == "GroupID" && Reader.NamespaceURI == "" && !b23) + { + b23 = true; + ob.@GroupID = ReadObject_UUID(false, true); + } + else if (Reader.LocalName == "Description" && Reader.NamespaceURI == "" && !b15) + { + b15 = true; + string s38 = Reader.ReadElementString(); + ob.@Description = s38; + } + else if (Reader.LocalName == "CreationDate" && Reader.NamespaceURI == "" && !b28) + { + b28 = true; + string s39 = Reader.ReadElementString(); + ob.@CreationDate = Int32.Parse(s39, CultureInfo.InvariantCulture); + } + else if (Reader.LocalName == "EveryOnePermissions" && Reader.NamespaceURI == "" && !b19) + { + b19 = true; + string s40 = Reader.ReadElementString(); + ob.@EveryOnePermissions = UInt32.Parse(s40, CultureInfo.InvariantCulture); + } + else if (Reader.LocalName == "Creator" && Reader.NamespaceURI == "" && !b13) + { + b13 = true; + ob.@Creator = ReadObject_UUID(false, true); + } + else if (Reader.LocalName == "Owner" && Reader.NamespaceURI == "" && !b12) + { + b12 = true; + ob.@Owner = ReadObject_UUID(false, true); + } + else if (Reader.LocalName == "SaleType" && Reader.NamespaceURI == "" && !b26) + { + b26 = true; + string s41 = Reader.ReadElementString(); + ob.@SaleType = byte.Parse(s41, CultureInfo.InvariantCulture); + } + else if (Reader.LocalName == "CurrentPermissions" && Reader.NamespaceURI == "" && !b17) + { + b17 = true; + string s42 = Reader.ReadElementString(); + ob.@CurrentPermissions = UInt32.Parse(s42, CultureInfo.InvariantCulture); + } + else + { + UnknownNode(ob); + } + } + else + UnknownNode(ob); + + Reader.MoveToContent(); + } + + ReadEndElement(); + + return ob; + } + + public InventoryCollection ReadObject_InventoryCollection(bool isNullable, bool checkType) + { + InventoryCollection ob = null; + if (isNullable && ReadNull()) return null; + + if (checkType) + { + System.Xml.XmlQualifiedName t = GetXsiType(); + if (t == null) + { } + else if (t.Name != "InventoryCollection" || t.Namespace != "") + throw CreateUnknownTypeException(t); + } + + ob = (InventoryCollection)Activator.CreateInstance(typeof(InventoryCollection), true); + + Reader.MoveToElement(); + + while (Reader.MoveToNextAttribute()) + { + if (IsXmlnsAttribute(Reader.Name)) + { + } + else + { + UnknownNode(ob); + } + } + + Reader.MoveToElement(); + Reader.MoveToElement(); + if (Reader.IsEmptyElement) + { + Reader.Skip(); + if (ob.@Folders == null) + { + ob.@Folders = new System.Collections.Generic.Dictionary(); + } + if (ob.@Items == null) + { + ob.@Items = new System.Collections.Generic.Dictionary(); + } + return ob; + } + + Reader.ReadStartElement(); + Reader.MoveToContent(); + + bool b43 = false, b44 = false, b45 = false; + + while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) + { + if (Reader.NodeType == System.Xml.XmlNodeType.Element) + { + if (Reader.LocalName == "UserID" && Reader.NamespaceURI == "" && !b45) + { + b45 = true; + ob.@UserID = ReadObject_UUID(false, true); + } + else if (Reader.LocalName == "Items" && Reader.NamespaceURI == "" && !b44) + { + System.Collections.Generic.Dictionary o46 = ob.@Items; + if (((object)o46) == null) + { + o46 = new System.Collections.Generic.Dictionary(); + ob.@Items = o46; + } + if (Reader.IsEmptyElement) + { + Reader.Skip(); + } + else + { + int n47 = 0; + Reader.ReadStartElement(); + Reader.MoveToContent(); + + while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) + { + if (Reader.NodeType == System.Xml.XmlNodeType.Element) + { + if (Reader.LocalName == "InventoryItemBase" && Reader.NamespaceURI == "") + { + if (((object)o46) == null) + throw CreateReadOnlyCollectionException("System.Collections.Generic.List"); + InventoryItem item = ReadObject_InventoryItem(true, true); + o46.Add(item.ID, item); + n47++; + } + else UnknownNode(null); + } + else UnknownNode(null); + + Reader.MoveToContent(); + } + ReadEndElement(); + } + b44 = true; + } + else if (Reader.LocalName == "Folders" && Reader.NamespaceURI == "" && !b43) + { + System.Collections.Generic.Dictionary o48 = ob.@Folders; + if (((object)o48) == null) + { + o48 = new System.Collections.Generic.Dictionary(); + ob.@Folders = o48; + } + if (Reader.IsEmptyElement) + { + Reader.Skip(); + } + else + { + int n49 = 0; + Reader.ReadStartElement(); + Reader.MoveToContent(); + + while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) + { + if (Reader.NodeType == System.Xml.XmlNodeType.Element) + { + if (Reader.LocalName == "InventoryFolderBase" && Reader.NamespaceURI == "") + { + if (((object)o48) == null) + throw CreateReadOnlyCollectionException("System.Collections.Generic.List"); + InventoryFolder folder = ReadObject_InventoryFolder(true, true); + o48.Add(folder.ID, folder); + n49++; + } + else UnknownNode(null); + } + else UnknownNode(null); + + Reader.MoveToContent(); + } + ReadEndElement(); + } + b43 = true; + } + else + { + UnknownNode(ob); + } + } + else + UnknownNode(ob); + + Reader.MoveToContent(); + } + if (ob.@Folders == null) + { + ob.@Folders = new System.Collections.Generic.Dictionary(); + } + if (ob.@Items == null) + { + ob.@Items = new System.Collections.Generic.Dictionary(); + } + + ReadEndElement(); + + return ob; + } + + public OpenMetaverse.UUID ReadObject_UUID(bool isNullable, bool checkType) + { + OpenMetaverse.UUID ob = (OpenMetaverse.UUID)Activator.CreateInstance(typeof(OpenMetaverse.UUID), true); + System.Xml.XmlQualifiedName t = GetXsiType(); + if (t == null) + { } + else if (t.Name != "UUID" || t.Namespace != "") + throw CreateUnknownTypeException(t); + + Reader.MoveToElement(); + + while (Reader.MoveToNextAttribute()) + { + if (IsXmlnsAttribute(Reader.Name)) + { + } + else + { + UnknownNode(ob); + } + } + + Reader.MoveToElement(); + Reader.MoveToElement(); + if (Reader.IsEmptyElement) + { + Reader.Skip(); + return ob; + } + + Reader.ReadStartElement(); + Reader.MoveToContent(); + + bool b52 = false; + + while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) + { + if (Reader.NodeType == System.Xml.XmlNodeType.Element) + { + if (Reader.LocalName == "Guid" && Reader.NamespaceURI == "" && !b52) + { + b52 = true; + string s53 = Reader.ReadElementString(); + ob.@Guid = XmlConvert.ToGuid(s53); + } + else + { + UnknownNode(ob); + } + } + else + UnknownNode(ob); + + Reader.MoveToContent(); + } + + ReadEndElement(); + + return ob; + } + + protected override void InitCallbacks() + { + } + + protected override void InitIDs() + { + } + } + + public class GeneratedWriter : XmlSerializationWriter + { + const string xmlNamespace = "http://www.w3.org/2000/xmlns/"; + static readonly System.Reflection.MethodInfo toBinHexStringMethod = typeof(XmlConvert).GetMethod("ToBinHexString", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic, null, new Type[] { typeof(byte[]) }, null); + static string ToBinHexString(byte[] input) + { + return input == null ? null : (string)toBinHexStringMethod.Invoke(null, new object[] { input }); + } + public void WriteRoot_InventoryFolder(object o) + { + WriteStartDocument(); + InventoryFolder ob = (InventoryFolder)o; + TopLevelElement(); + WriteObject_InventoryFolder(ob, "InventoryFolderBase", "", true, false, true); + } + + public void WriteRoot_InventoryItem(object o) + { + WriteStartDocument(); + InventoryItem ob = (InventoryItem)o; + TopLevelElement(); + WriteObject_InventoryItem(ob, "InventoryItemBase", "", true, false, true); + } + + public void WriteRoot_InventoryCollection(object o) + { + WriteStartDocument(); + InventoryCollection ob = (InventoryCollection)o; + TopLevelElement(); + WriteObject_InventoryCollection(ob, "InventoryCollection", "", true, false, true); + } + + void WriteObject_InventoryFolder(InventoryFolder ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + if (((object)ob) == null) + { + if (isNullable) + WriteNullTagLiteral(element, namesp); + return; + } + + System.Type type = ob.GetType(); + if (type == typeof(InventoryFolder)) + { } + else + { + throw CreateUnknownTypeException(ob); + } + + if (writeWrappingElem) + { + WriteStartElement(element, namesp, ob); + } + + if (needType) WriteXsiType("InventoryFolderBase", ""); + + WriteElementString("Name", "", ob.@Name); + WriteObject_UUID(ob.@Owner, "Owner", "", false, false, true); + WriteObject_UUID(ob.@ParentID, "ParentID", "", false, false, true); + WriteObject_UUID(ob.@ID, "ID", "", false, false, true); + WriteElementString("Type", "", ob.@Type.ToString(CultureInfo.InvariantCulture)); + WriteElementString("Version", "", ob.@Version.ToString(CultureInfo.InvariantCulture)); + if (writeWrappingElem) WriteEndElement(ob); + } + + void WriteObject_InventoryItem(InventoryItem ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + if (((object)ob) == null) + { + if (isNullable) + WriteNullTagLiteral(element, namesp); + return; + } + + System.Type type = ob.GetType(); + if (type == typeof(InventoryItem)) + { } + else + { + throw CreateUnknownTypeException(ob); + } + + if (writeWrappingElem) + { + WriteStartElement(element, namesp, ob); + } + + if (needType) WriteXsiType("InventoryItemBase", ""); + + WriteObject_UUID(ob.@ID, "ID", "", false, false, true); + WriteElementString("InvType", "", ob.@InvType.ToString(CultureInfo.InvariantCulture)); + WriteObject_UUID(ob.@Folder, "Folder", "", false, false, true); + WriteObject_UUID(ob.@Owner, "Owner", "", false, false, true); + WriteObject_UUID(ob.@Creator, "Creator", "", false, false, true); + WriteElementString("Name", "", ob.@Name); + WriteElementString("Description", "", ob.@Description); + WriteElementString("NextPermissions", "", ob.@NextPermissions.ToString(CultureInfo.InvariantCulture)); + WriteElementString("CurrentPermissions", "", ob.@CurrentPermissions.ToString(CultureInfo.InvariantCulture)); + WriteElementString("BasePermissions", "", ob.@BasePermissions.ToString(CultureInfo.InvariantCulture)); + WriteElementString("EveryOnePermissions", "", ob.@EveryOnePermissions.ToString(CultureInfo.InvariantCulture)); + WriteElementString("GroupPermissions", "", ob.@GroupPermissions.ToString(CultureInfo.InvariantCulture)); + WriteElementString("AssetType", "", ob.@AssetType.ToString(CultureInfo.InvariantCulture)); + WriteObject_UUID(ob.@AssetID, "AssetID", "", false, false, true); + WriteObject_UUID(ob.@GroupID, "GroupID", "", false, false, true); + WriteElementString("GroupOwned", "", (ob.@GroupOwned ? "true" : "false")); + WriteElementString("SalePrice", "", ob.@SalePrice.ToString(CultureInfo.InvariantCulture)); + WriteElementString("SaleType", "", ob.@SaleType.ToString(CultureInfo.InvariantCulture)); + WriteElementString("Flags", "", ob.@Flags.ToString(CultureInfo.InvariantCulture)); + WriteElementString("CreationDate", "", ob.@CreationDate.ToString(CultureInfo.InvariantCulture)); + if (writeWrappingElem) WriteEndElement(ob); + } + + void WriteObject_InventoryCollection(InventoryCollection ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + if (((object)ob) == null) + { + if (isNullable) + WriteNullTagLiteral(element, namesp); + return; + } + + System.Type type = ob.GetType(); + if (type == typeof(InventoryCollection)) + { } + else + { + throw CreateUnknownTypeException(ob); + } + + if (writeWrappingElem) + { + WriteStartElement(element, namesp, ob); + } + + if (needType) WriteXsiType("InventoryCollection", ""); + + if (ob.@Folders != null) + { + WriteStartElement("Folders", "", ob.@Folders); + foreach (InventoryFolder folder in ob.Folders.Values) + { + WriteObject_InventoryFolder(folder, "InventoryFolderBase", "", true, false, true); + } + WriteEndElement(ob.@Folders); + } + if (ob.@Items != null) + { + WriteStartElement("Items", "", ob.@Items); + foreach (InventoryItem item in ob.Items.Values) + { + WriteObject_InventoryItem(item, "InventoryItemBase", "", true, false, true); + } + WriteEndElement(ob.@Items); + } + WriteObject_UUID(ob.@UserID, "UserID", "", false, false, true); + if (writeWrappingElem) WriteEndElement(ob); + } + + void WriteObject_UUID(OpenMetaverse.UUID ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + System.Type type = ob.GetType(); + if (type == typeof(OpenMetaverse.UUID)) + { } + else + { + throw CreateUnknownTypeException(ob); + } + + if (writeWrappingElem) + { + WriteStartElement(element, namesp, ob); + } + + if (needType) WriteXsiType("UUID", ""); + + WriteElementString("Guid", "", XmlConvert.ToString(ob.@Guid)); + if (writeWrappingElem) WriteEndElement(ob); + } + + protected override void InitCallbacks() + { + } + + } + + public class BaseXmlSerializer : System.Xml.Serialization.XmlSerializer + { + protected override System.Xml.Serialization.XmlSerializationReader CreateReader() + { + return new GeneratedReader(); + } + + protected override System.Xml.Serialization.XmlSerializationWriter CreateWriter() + { + return new GeneratedWriter(); + } + + public override bool CanDeserialize(System.Xml.XmlReader xmlReader) + { + return true; + } + } + + public sealed class InventoryFolderSerializer : BaseXmlSerializer + { + protected override void Serialize(object obj, System.Xml.Serialization.XmlSerializationWriter writer) + { + ((GeneratedWriter)writer).WriteRoot_InventoryFolder(obj); + } + + protected override object Deserialize(System.Xml.Serialization.XmlSerializationReader reader) + { + return ((GeneratedReader)reader).ReadRoot_InventoryFolderBase(); + } + } + + public sealed class InventoryItemSerializer : BaseXmlSerializer + { + protected override void Serialize(object obj, System.Xml.Serialization.XmlSerializationWriter writer) + { + ((GeneratedWriter)writer).WriteRoot_InventoryItem(obj); + } + + protected override object Deserialize(System.Xml.Serialization.XmlSerializationReader reader) + { + return ((GeneratedReader)reader).ReadRoot_InventoryItemBase(); + } + } + + public sealed class InventoryCollectionSerializer : BaseXmlSerializer + { + protected override void Serialize(object obj, System.Xml.Serialization.XmlSerializationWriter writer) + { + ((GeneratedWriter)writer).WriteRoot_InventoryCollection(obj); + } + + protected override object Deserialize(System.Xml.Serialization.XmlSerializationReader reader) + { + return ((GeneratedReader)reader).ReadRoot_InventoryCollection(); + } + } + + #endregion XML Serialization + } +} diff --git a/OpenSim/Grid/NewAssetServer/AssetServer.cs b/OpenSim/Grid/NewAssetServer/AssetServer.cs deleted file mode 100644 index c6864e7..0000000 --- a/OpenSim/Grid/NewAssetServer/AssetServer.cs +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (c) 2008 Intel Corporation - * All rights reserved. - * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``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 INTEL OR ITS - * 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.IO; -using System.Net; -using System.Reflection; -using System.Security.Cryptography.X509Certificates; -using System.ServiceProcess; -using ExtensionLoader; -using ExtensionLoader.Config; -using HttpServer; -using log4net; -using OpenSim.Framework; - -namespace AssetServer -{ - public class AssetServer : ServiceBase - { - public const string CONFIG_FILE = "AssetServer.ini"; - - public WebServer HttpServer; - public IniConfigSource ConfigFile; - - public IAssetStorageProvider StorageProvider; - public IInventoryProvider InventoryProvider; - public IAuthenticationProvider AuthenticationProvider; - public IAuthorizationProvider AuthorizationProvider; - public IMetricsProvider MetricsProvider; - - public AssetServer() - { - this.ServiceName = "OpenSimAssetServer"; - } - - public bool Start() - { - Logger.Log.Info("Starting Asset Server"); - List extensionList = null; - int port = 0; - X509Certificate2 serverCert = null; - - try { ConfigFile = new IniConfigSource(CONFIG_FILE); } - catch (Exception) - { - Logger.Log.Error("Failed to load the config file " + CONFIG_FILE); - return false; - } - - try - { - IConfig extensionConfig = ConfigFile.Configs["Config"]; - - // Load the port number to listen on - port = extensionConfig.GetInt("ListenPort"); - - // Load the server certificate file - string certFile = extensionConfig.GetString("SSLCertFile"); - if (!String.IsNullOrEmpty(certFile)) - serverCert = new X509Certificate2(certFile); - } - catch (Exception) - { - Logger.Log.Error("Failed to load [Config] section from " + CONFIG_FILE); - return false; - } - - try - { - // Load the extension list (and ordering) from our config file - IConfig extensionConfig = ConfigFile.Configs["Extensions"]; - extensionList = new List(extensionConfig.GetKeys()); - } - catch (Exception) - { - Logger.Log.Error("Failed to load [Extensions] section from " + CONFIG_FILE); - return false; - } - - //try - //{ - // // Create a reference list for C# extensions compiled at runtime - // List references = new List(); - // references.Add("OpenMetaverseTypes.dll"); - // references.Add("OpenMetaverse.dll"); - // references.Add("OpenMetaverse.StructuredData.dll"); - // references.Add("OpenMetaverse.Http.dll"); - // references.Add("ExtensionLoader.dll"); - // references.Add("AssetServer.exe"); - - // // Get a list of all of the members of AssetServer that are interfaces - // List assignables = ExtensionLoader.GetInterfaces(this); - - // // Load all of the extensions - // ExtensionLoader.LoadAllExtensions( - // Assembly.GetExecutingAssembly(), - // Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), - // extensionList, - // references, - // "AssetServer.*.dll", - // "AssetServer.*.cs", - // this, - // assignables); - //} - //catch (ExtensionException ex) - //{ - // Logger.Log.Error("Interface loading failed, shutting down: " + ex.Message); - // if (ex.InnerException != null) - // Logger.Log.Error(ex.InnerException.Message, ex.InnerException); - // Stop(); - // return false; - //} - - StorageProvider = LoadAssetServerPlugin() as IAssetStorageProvider; - - try - { - InitHttpServer(port, serverCert); - } - catch (Exception ex) - { - Logger.Log.Error("Initializing the HTTP server failed, shutting down: " + ex.Message); - Stop(); - return false; - } - - // Start all of the extensions - //foreach (IExtension extension in ExtensionLoader.Extensions) - //{ - // Logger.Log.Info("Starting extension " + extension.GetType().Name); - // extension.Start(this); - //} - - return true; - } - - public void Shutdown() - { - foreach (IExtension extension in ExtensionLoader.Extensions) - { - Logger.Log.Debug("Disposing extension " + extension.GetType().Name); - try { extension.Stop(); } - catch (Exception ex) - { Logger.Log.ErrorFormat("Failure shutting down extension {0}: {1}", extension.GetType().Name, ex.Message); } - } - - if (HttpServer != null) - HttpServer.Stop(); - } - - void InitHttpServer(int port, X509Certificate serverCert) - { - if (serverCert != null) - HttpServer = new WebServer(IPAddress.Any, port, serverCert, null, false); - else - HttpServer = new WebServer(IPAddress.Any, port); - - HttpServer.LogWriter = new log4netLogWriter(Logger.Log); - - HttpServer.Set404Handler( - delegate(IHttpClientContext client, IHttpRequest request, IHttpResponse response) - { - Logger.Log.Warn("Requested page was not found: " + request.Uri.PathAndQuery); - - string notFoundString = "Page Not FoundThe requested page or method was not found"; - byte[] buffer = System.Text.Encoding.UTF8.GetBytes(notFoundString); - response.Body.Write(buffer, 0, buffer.Length); - response.Status = HttpStatusCode.NotFound; - return true; - } - ); - - HttpServer.Start(); - - Logger.Log.Info("Asset server is listening on port " + port); - } - - #region ServiceBase Overrides - - protected override void OnStart(string[] args) - { - Start(); - } - protected override void OnStop() - { - Shutdown(); - } - - #endregion - - private IAssetServerPlugin LoadAssetServerPlugin() - { - PluginLoader loader = new PluginLoader(new AssetServerPluginInitialiser(this)); - - //loader.Add ("/OpenSim/AssetServer/StorageProvider", new PluginProviderFilter (provider)); - loader.Add("/OpenSim/AssetServer/StorageProvider", new PluginCountConstraint(1)); - loader.Load(); - - return loader.Plugin; - } - } - - public class log4netLogWriter : ILogWriter - { - ILog Log; - - public log4netLogWriter(ILog log) - { - Log = log; - } - - public void Write(object source, LogPrio prio, string message) - { - switch (prio) - { - case LogPrio.Trace: - case LogPrio.Debug: - Log.DebugFormat("{0}: {1}", source, message); - break; - case LogPrio.Info: - Log.InfoFormat("{0}: {1}", source, message); - break; - case LogPrio.Warning: - Log.WarnFormat("{0}: {1}", source, message); - break; - case LogPrio.Error: - Log.ErrorFormat("{0}: {1}", source, message); - break; - case LogPrio.Fatal: - Log.FatalFormat("{0}: {1}", source, message); - break; - } - } - } -} diff --git a/OpenSim/Grid/NewAssetServer/Extensions/AuthorizeAll.cs b/OpenSim/Grid/NewAssetServer/Extensions/AuthorizeAll.cs deleted file mode 100644 index f112c5e..0000000 --- a/OpenSim/Grid/NewAssetServer/Extensions/AuthorizeAll.cs +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2008 Intel Corporation - * All rights reserved. - * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``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 INTEL OR ITS - * 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 ExtensionLoader; -using OpenMetaverse; - -namespace AssetServer.Extensions -{ - public class AuthorizeAll : IExtension, IAuthorizationProvider - { - AssetServer server; - - public AuthorizeAll() - { - } - - public void Start(AssetServer server) - { - this.server = server; - } - - public void Stop() - { - } - - 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; - } - } -} diff --git a/OpenSim/Grid/NewAssetServer/Extensions/BrowseFrontend.cs b/OpenSim/Grid/NewAssetServer/Extensions/BrowseFrontend.cs deleted file mode 100644 index 9f42722..0000000 --- a/OpenSim/Grid/NewAssetServer/Extensions/BrowseFrontend.cs +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2008 Intel Corporation - * All rights reserved. - * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``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 INTEL OR ITS - * 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.Collections.Specialized; -using System.Net; -using System.Text; -using System.Web; -using ExtensionLoader; -using OpenMetaverse; -using HttpServer; - -namespace AssetServer.Extensions -{ - public class BrowseFrontend : IExtension - { - AssetServer server; - - public BrowseFrontend() - { - } - - public void Start(AssetServer server) - { - this.server = server; - - // Request for / or /?... - server.HttpServer.AddHandler("get", null, @"(^/$)|(^/\?.*)", BrowseRequestHandler); - } - - public void Stop() - { - } - - bool BrowseRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) - { - const int ASSETS_PER_PAGE = 25; - const string HEADER = "Asset Server"; - const string TABLE_HEADER = - ""; - const string TABLE_FOOTER = "
NameDescriptionTypeIDTemporarySHA-1
"; - const string FOOTER = ""; - - UUID authToken = Utils.GetAuthToken(request); - - StringBuilder html = new StringBuilder(); - int start = 0; - uint page = 0; - - if (!String.IsNullOrEmpty(request.Uri.Query)) - { - NameValueCollection query = HttpUtility.ParseQueryString(request.Uri.Query); - if (!String.IsNullOrEmpty(query["page"]) && UInt32.TryParse(query["page"], out page)) - start = (int)page * ASSETS_PER_PAGE; - } - - html.AppendLine(HEADER); - - html.AppendLine("

"); - if (page > 0) - html.AppendFormat("< Previous Page | ", request.Uri.AbsolutePath, page - 1); - html.AppendFormat("Next Page >", request.Uri.AbsolutePath, page + 1); - html.AppendLine("

"); - - html.AppendLine(TABLE_HEADER); - - server.StorageProvider.ForEach( - delegate(Metadata data) - { - if (server.AuthorizationProvider.IsMetadataAuthorized(authToken, data.ID)) - { - html.AppendLine(String.Format( - "{0}{1}{2}{3}{4}{5}", - data.Name, data.Description, data.ContentType, data.ID, data.Temporary, - BitConverter.ToString(data.SHA1).Replace("-", String.Empty))); - } - else - { - html.AppendLine(String.Format( - "[Protected Asset]  {0}{1} ", - data.ID, data.Temporary)); - } - }, start, ASSETS_PER_PAGE - ); - - html.AppendLine(TABLE_FOOTER); - - html.AppendLine(FOOTER); - - byte[] responseData = System.Text.Encoding.UTF8.GetBytes(html.ToString()); - - response.Status = HttpStatusCode.OK; - response.Body.Write(responseData, 0, responseData.Length); - response.Body.Flush(); - return true; - } - } -} diff --git a/OpenSim/Grid/NewAssetServer/Extensions/DBConnString.cs b/OpenSim/Grid/NewAssetServer/Extensions/DBConnString.cs deleted file mode 100644 index 3c5f971..0000000 --- a/OpenSim/Grid/NewAssetServer/Extensions/DBConnString.cs +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2008 Intel Corporation - * All rights reserved. - * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``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 INTEL OR ITS - * 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.Xml; -using ExtensionLoader.Config; -using MySql.Data.MySqlClient; - -namespace AssetServer.Extensions -{ - public static class DBConnString - { - private static string connectionString; - - /// - /// Parses the MySQL connection string out of either the asset server - /// .ini or a OpenSim-style .xml file and caches the result for future - /// requests - /// - public static string GetConnectionString(IniConfigSource configFile) - { - if (connectionString == null) - { - // Try parsing from the ini file - try - { - // Load the extension list (and ordering) from our config file - IConfig extensionConfig = configFile.Configs["MySQL"]; - connectionString = extensionConfig.GetString("database_connect", null); - } - catch (Exception) { } - - if (connectionString != null) - { - // Force MySQL's broken connection pooling off - MySqlConnectionStringBuilder builder = new MySqlConnectionStringBuilder(connectionString); - builder.Pooling = false; - if (String.IsNullOrEmpty(builder.Database)) - Logger.Log.Error("No database selected in the connectionString: " + connectionString); - connectionString = builder.ToString(); - } - else - { - Logger.Log.Error("Database connection string is missing, check that the database_connect line is " + - "correct and uncommented in AssetServer.ini"); - } - } - - return connectionString; - } - } -} diff --git a/OpenSim/Grid/NewAssetServer/Extensions/NullAuthentication.cs b/OpenSim/Grid/NewAssetServer/Extensions/NullAuthentication.cs deleted file mode 100644 index 9d38bf4..0000000 --- a/OpenSim/Grid/NewAssetServer/Extensions/NullAuthentication.cs +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2008 Intel Corporation - * All rights reserved. - * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``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 INTEL OR ITS - * 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 ExtensionLoader; -using OpenMetaverse; - -namespace AssetServer.Extensions -{ - public class NullAuthentication : IExtension, IAuthenticationProvider - { - AssetServer server; - - public NullAuthentication() - { - } - - public void Start(AssetServer server) - { - this.server = server; - } - - public void Stop() - { - } - - 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; - } - } -} diff --git a/OpenSim/Grid/NewAssetServer/Extensions/NullMetrics.cs b/OpenSim/Grid/NewAssetServer/Extensions/NullMetrics.cs deleted file mode 100644 index 84657c4..0000000 --- a/OpenSim/Grid/NewAssetServer/Extensions/NullMetrics.cs +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2008 Intel Corporation - * All rights reserved. - * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``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 INTEL OR ITS - * 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 ExtensionLoader; -using OpenMetaverse; - -namespace AssetServer.Extensions -{ - public class NullMetrics : IExtension, IMetricsProvider - { - AssetServer server; - - public NullMetrics() - { - } - - public void Start(AssetServer server) - { - this.server = server; - } - - public void Stop() - { - } - - public void LogAssetMetadataFetch(string extension, BackendResponse response, UUID assetID, DateTime time) - { - Logger.Log.DebugFormat("[{0}] AssetMetadataFetch(): AssetID: {1}, Response: {2}", extension, assetID, response); - } - - public void LogAssetDataFetch(string extension, BackendResponse response, UUID assetID, int dataSize, DateTime time) - { - Logger.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) - { - Logger.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) - { - Logger.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) - { - Logger.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) - { - Logger.Log.DebugFormat("[{0}] InventoryFetchFolderList(): OwnerID: {1}, Response: {2}", extension, - owner, response); - } - - public void LogInventoryFetchInventory(string extension, BackendResponse response, Uri owner, DateTime time) - { - Logger.Log.DebugFormat("[{0}] InventoryFetchInventory(): OwnerID: {1}, Response: {2}", extension, - owner, response); - } - - public void LogInventoryFetchActiveGestures(string extension, BackendResponse response, Uri owner, DateTime time) - { - Logger.Log.DebugFormat("[{0}] InventoryFetchActiveGestures(): OwnerID: {1}, Response: {2}", extension, - owner, response); - } - - public void LogInventoryCreate(string extension, BackendResponse response, Uri owner, bool folder, DateTime time) - { - Logger.Log.DebugFormat("[{0}] InventoryCreate(): OwnerID: {1}, Response: {2}", extension, - owner, response); - } - - public void LogInventoryCreateInventory(string extension, BackendResponse response, DateTime time) - { - Logger.Log.DebugFormat("[{0}] InventoryCreateInventory(): Response: {1}", extension, - response); - } - - public void LogInventoryDelete(string extension, BackendResponse response, Uri owner, UUID objID, bool folder, DateTime time) - { - Logger.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) - { - Logger.Log.DebugFormat("[{0}] InventoryPurgeFolder(): OwnerID: {1}, FolderID: {2}, Response: {3}", extension, - owner, response); - } - } -} diff --git a/OpenSim/Grid/NewAssetServer/Extensions/OpenSimFrontend.cs b/OpenSim/Grid/NewAssetServer/Extensions/OpenSimFrontend.cs deleted file mode 100644 index 7a645b3..0000000 --- a/OpenSim/Grid/NewAssetServer/Extensions/OpenSimFrontend.cs +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (c) 2008 Intel Corporation - * All rights reserved. - * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``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 INTEL OR ITS - * 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.Net; -using System.IO; -using System.Xml; -using ExtensionLoader; -using OpenMetaverse; -using HttpServer; - -namespace AssetServer.Extensions -{ - public class OpenSimFrontend : IExtension - { - AssetServer server; - - public OpenSimFrontend() - { - } - - public void Start(AssetServer server) - { - this.server = server; - - // Asset request - server.HttpServer.AddHandler("get", null, @"^/assets/", AssetRequestHandler); - - // Asset creation - server.HttpServer.AddHandler("post", null, @"^/assets/", AssetPostHandler); - } - - public void Stop() - { - } - - bool AssetRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) - { - UUID assetID; - // Split the URL up to get the asset ID out - string[] rawUrl = request.Uri.PathAndQuery.Split('/'); - - if (rawUrl.Length >= 3 && rawUrl[2].Length >= 36 && UUID.TryParse(rawUrl[2].Substring(0, 36), out assetID)) - { - Metadata metadata; - byte[] assetData; - BackendResponse dataResponse; - - if ((dataResponse = server.StorageProvider.TryFetchDataMetadata(assetID, out metadata, out assetData)) == BackendResponse.Success) - { - MemoryStream stream = new MemoryStream(); - - XmlWriterSettings settings = new XmlWriterSettings(); - settings.Indent = true; - XmlWriter writer = XmlWriter.Create(stream, settings); - - writer.WriteStartDocument(); - writer.WriteStartElement("AssetBase"); - writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance"); - writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema"); - writer.WriteStartElement("FullID"); - writer.WriteStartElement("Guid"); - writer.WriteString(assetID.ToString()); - writer.WriteEndElement(); - writer.WriteEndElement(); - writer.WriteStartElement("ID"); - writer.WriteString(assetID.ToString()); - writer.WriteEndElement(); - writer.WriteStartElement("Data"); - writer.WriteBase64(assetData, 0, assetData.Length); - writer.WriteEndElement(); - writer.WriteStartElement("Type"); - writer.WriteValue(Utils.ContentTypeToSLAssetType(metadata.ContentType)); - writer.WriteEndElement(); - writer.WriteStartElement("Name"); - writer.WriteString(metadata.Name); - writer.WriteEndElement(); - writer.WriteStartElement("Description"); - writer.WriteString(metadata.Description); - writer.WriteEndElement(); - writer.WriteStartElement("Local"); - writer.WriteValue(false); - writer.WriteEndElement(); - writer.WriteStartElement("Temporary"); - writer.WriteValue(metadata.Temporary); - writer.WriteEndElement(); - writer.WriteEndElement(); - writer.WriteEndDocument(); - - writer.Flush(); - byte[] buffer = stream.GetBuffer(); - - response.Status = HttpStatusCode.OK; - response.ContentType = "application/xml"; - response.ContentLength = stream.Length; - response.Body.Write(buffer, 0, (int)stream.Length); - response.Body.Flush(); - } - else - { - Logger.Log.WarnFormat("Failed to fetch asset data or metadata for {0}: {1}", assetID, dataResponse); - response.Status = HttpStatusCode.NotFound; - } - } - else - { - Logger.Log.Warn("Unrecognized OpenSim asset request: " + request.Uri.PathAndQuery); - } - - return true; - } - - bool AssetPostHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) - { - byte[] assetData = null; - Metadata metadata = new Metadata(); - - Logger.Log.Debug("Handling OpenSim asset upload"); - - try - { - using (XmlReader reader = XmlReader.Create(request.Body)) - { - reader.MoveToContent(); - reader.ReadStartElement("AssetBase"); - - reader.ReadStartElement("FullID"); - UUID.TryParse(reader.ReadElementContentAsString("Guid", String.Empty), out metadata.ID); - reader.ReadEndElement(); - reader.ReadStartElement("ID"); - reader.Skip(); - reader.ReadEndElement(); - - // HACK: Broken on Mono. https://bugzilla.novell.com/show_bug.cgi?id=464229 - //int readBytes = 0; - //byte[] buffer = new byte[1024]; - //MemoryStream stream = new MemoryStream(); - //BinaryWriter writer = new BinaryWriter(stream); - //while ((readBytes = reader.ReadElementContentAsBase64(buffer, 0, buffer.Length)) > 0) - // writer.Write(buffer, 0, readBytes); - //writer.Flush(); - //assetData = stream.GetBuffer(); - //Array.Resize(ref assetData, (int)stream.Length); - - assetData = Convert.FromBase64String(reader.ReadElementContentAsString()); - - int type; - Int32.TryParse(reader.ReadElementContentAsString("Type", String.Empty), out type); - metadata.ContentType = Utils.SLAssetTypeToContentType(type); - metadata.Name = reader.ReadElementContentAsString("Name", String.Empty); - metadata.Description = reader.ReadElementContentAsString("Description", String.Empty); - Boolean.TryParse(reader.ReadElementContentAsString("Local", String.Empty), out metadata.Temporary); - Boolean.TryParse(reader.ReadElementContentAsString("Temporary", String.Empty), out metadata.Temporary); - - reader.ReadEndElement(); - } - - if (assetData != null && assetData.Length > 0) - { - metadata.SHA1 = OpenMetaverse.Utils.SHA1(assetData); - metadata.CreationDate = DateTime.Now; - - BackendResponse storageResponse = server.StorageProvider.TryCreateAsset(metadata, assetData); - - if (storageResponse == BackendResponse.Success) - response.Status = HttpStatusCode.Created; - else if (storageResponse == BackendResponse.NotFound) - response.Status = HttpStatusCode.NotFound; - else - response.Status = HttpStatusCode.InternalServerError; - } - else - { - Logger.Log.Warn("AssetPostHandler called with no asset data"); - response.Status = HttpStatusCode.BadRequest; - } - } - catch (Exception ex) - { - Logger.Log.Warn("Failed to parse POST data (expecting AssetBase): " + ex.Message); - response.Status = HttpStatusCode.BadRequest; - } - - Logger.Log.Debug("Finished handling OpenSim asset upload, Status: " + response.Status.ToString()); - return true; - } - } -} diff --git a/OpenSim/Grid/NewAssetServer/Extensions/OpenSimInventoryFrontend.cs b/OpenSim/Grid/NewAssetServer/Extensions/OpenSimInventoryFrontend.cs deleted file mode 100644 index a559f19..0000000 --- a/OpenSim/Grid/NewAssetServer/Extensions/OpenSimInventoryFrontend.cs +++ /dev/null @@ -1,636 +0,0 @@ -/* - * Copyright (c) 2008 Intel Corporation - * All rights reserved. - * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``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 INTEL OR ITS - * 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.Net; -using System.IO; -using System.Xml; -using ExtensionLoader; -using OpenMetaverse; -using OpenMetaverse.StructuredData; -using HttpServer; - -namespace AssetServer.Extensions -{ - public class OpenSimInventoryFrontend : IExtension - { - AssetServer server; - Utils.InventoryItemSerializer itemSerializer = new Utils.InventoryItemSerializer(); - Utils.InventoryFolderSerializer folderSerializer = new Utils.InventoryFolderSerializer(); - Utils.InventoryCollectionSerializer collectionSerializer = new Utils.InventoryCollectionSerializer(); - - public OpenSimInventoryFrontend() - { - } - - public void Start(AssetServer server) - { - this.server = server; - - server.HttpServer.AddHandler("post", null, @"^/GetInventory/", GetInventoryHandler); - server.HttpServer.AddHandler("post", null, @"^/CreateInventory/", CreateInventoryHandler); - server.HttpServer.AddHandler("post", null, @"^/NewFolder/", NewFolderHandler); - server.HttpServer.AddHandler("post", null, @"^/UpdateFolder/", UpdateFolderHandler); - server.HttpServer.AddHandler("post", null, @"^/MoveFolder/", MoveFolderHandler); - server.HttpServer.AddHandler("post", null, @"^/PurgeFolder/", PurgeFolderHandler); - server.HttpServer.AddHandler("post", null, @"^/NewItem/", NewItemHandler); - server.HttpServer.AddHandler("post", null, @"^/DeleteItem/", DeleteItemHandler); - server.HttpServer.AddHandler("post", null, @"^/RootFolders/", RootFoldersHandler); - server.HttpServer.AddHandler("post", null, @"^/ActiveGestures/", ActiveGesturesHandler); - } - - public void Stop() - { - } - - bool GetInventoryHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) - { - UUID sessionID, agentID; - UUID ownerID = DeserializeUUID(request.Body, out agentID, out sessionID); - - if (ownerID != UUID.Zero) - { - Logger.Log.Warn("GetInventory is not scalable on some inventory backends, avoid calling it wherever possible"); - - Uri owner = Utils.GetOpenSimUri(ownerID); - InventoryCollection inventory; - BackendResponse storageResponse = server.InventoryProvider.TryFetchInventory(owner, out inventory); - - if (storageResponse == BackendResponse.Success) - { - collectionSerializer.Serialize(response.Body, inventory); - response.Body.Flush(); - } - 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(); - inventory.Items = new Dictionary(); - collectionSerializer.Serialize(response.Body, inventory); - response.Body.Flush(); - } - else - { - response.Status = HttpStatusCode.InternalServerError; - } - } - else - { - response.Status = HttpStatusCode.BadRequest; - } - - return true; - } - - bool CreateInventoryHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) - { - UUID ownerID = DeserializeUUID(request.Body); - - if (ownerID != UUID.Zero) - { - Uri owner = Utils.GetOpenSimUri(ownerID); - Logger.Log.DebugFormat("Created URI {0} for inventory creation", owner); - - InventoryFolder rootFolder = new InventoryFolder("My Inventory", ownerID, UUID.Zero, (short)AssetType.Folder); - BackendResponse storageResponse = server.InventoryProvider.TryCreateInventory(owner, rootFolder); - if (storageResponse == BackendResponse.Success) - { - 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); - - SerializeBool(response.Body, true); - return true; - } - } - - SerializeBool(response.Body, false); - return true; - } - - bool NewFolderHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) - { - UUID agentID, sessionID; - InventoryFolder folder = DeserializeFolder(request.Body, 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. If this is the case we - // need to look up the name first - if (String.IsNullOrEmpty(folder.Name)) - { - InventoryFolder oldFolder; - if (server.InventoryProvider.TryFetchFolder(owner, folder.ID, out oldFolder) == BackendResponse.Success) - folder.Name = oldFolder.Name; - } - - BackendResponse storageResponse = server.InventoryProvider.TryCreateFolder(owner, folder); - - if (storageResponse == BackendResponse.Success) - { - SerializeBool(response.Body, true); - return true; - } - } - - SerializeBool(response.Body, false); - return true; - } - - bool UpdateFolderHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) - { - return NewFolderHandler(client, request, response); - } - - bool MoveFolderHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) - { - return NewFolderHandler(client, request, response); - } - - bool PurgeFolderHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) - { - UUID agentID, sessionID; - InventoryFolder folder = DeserializeFolder(request.Body, out agentID, out sessionID); - - if (folder != null) - { - Uri owner = Utils.GetOpenSimUri(folder.Owner); - BackendResponse storageResponse = server.InventoryProvider.TryPurgeFolder(owner, folder.ID); - - if (storageResponse == BackendResponse.Success) - { - SerializeBool(response.Body, true); - return true; - } - } - - SerializeBool(response.Body, false); - return true; - } - - bool NewItemHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) - { - UUID agentID, sessionID; - InventoryItem item = DeserializeItem(request.Body, out agentID, out sessionID); - - if (item != null) - { - Uri owner = Utils.GetOpenSimUri(agentID); - BackendResponse storageResponse = server.InventoryProvider.TryCreateItem(owner, item); - - if (storageResponse == BackendResponse.Success) - { - SerializeBool(response.Body, true); - return true; - } - } - - SerializeBool(response.Body, false); - return true; - } - - bool DeleteItemHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) - { - UUID agentID, sessionID; - InventoryItem item = DeserializeItem(request.Body, out agentID, out sessionID); - - if (item != null) - { - Uri owner = Utils.GetOpenSimUri(item.Owner); - BackendResponse storageResponse = server.InventoryProvider.TryDeleteItem(owner, item.ID); - - if (storageResponse == BackendResponse.Success) - { - SerializeBool(response.Body, true); - return true; - } - } - - SerializeBool(response.Body, false); - return true; - } - - bool RootFoldersHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) - { - UUID ownerID = DeserializeUUID(request.Body); - - if (ownerID != UUID.Zero) - { - Uri owner = Utils.GetOpenSimUri(ownerID); - List skeleton; - BackendResponse storageResponse = server.InventoryProvider.TryFetchFolderList(owner, out skeleton); - - if (storageResponse == BackendResponse.Success) - { - SerializeFolderList(response.Body, skeleton); - } - 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 - SerializeFolderList(response.Body, new List(0)); - } - else - { - response.Status = HttpStatusCode.InternalServerError; - } - } - else - { - response.Status = HttpStatusCode.BadRequest; - } - - return true; - } - - bool ActiveGesturesHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) - { - UUID ownerID = DeserializeUUID(request.Body); - - if (ownerID != UUID.Zero) - { - Uri owner = Utils.GetOpenSimUri(ownerID); - List gestures; - BackendResponse storageResponse = server.InventoryProvider.TryFetchActiveGestures(owner, out gestures); - - if (storageResponse == BackendResponse.Success) - { - SerializeItemList(response.Body, gestures); - } - else if (storageResponse == BackendResponse.NotFound) - { - // Return an empty set of gestures to match OpenSim.Grid.InventoryServer.exe behavior - SerializeItemList(response.Body, new List(0)); - } - else - { - response.Status = HttpStatusCode.InternalServerError; - } - } - else - { - response.Status = HttpStatusCode.BadRequest; - } - - return true; - } - - 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 server.InventoryProvider.TryCreateFolder(owner, folder); - } - - 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) - { - Logger.Log.Warn("Failed to parse POST data (expecting guid): " + ex.Message); - } - - return id; - } - - 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) - { - Logger.Log.Warn("Failed to parse GetInventory POST data: " + ex.Message); - agentID = UUID.Zero; - sessionID = UUID.Zero; - return UUID.Zero; - } - - return id; - } - - InventoryFolder DeserializeFolder(Stream stream, out UUID agentID, out UUID sessionID) - { - InventoryFolder folder = new InventoryFolder(); - - 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; - ReadUUID(reader, "Owner", out folder.Owner); - ReadUUID(reader, "ParentID", out folder.ParentID); - ReadUUID(reader, "ID", out folder.ID); - Int16.TryParse(reader.ReadElementContentAsString("Type", String.Empty), out folder.Type); - UInt16.TryParse(reader.ReadElementContentAsString("Version", String.Empty), out folder.Version); - reader.ReadEndElement(); - reader.ReadEndElement(); - } - } - catch (Exception ex) - { - Logger.Log.Warn("Failed to parse POST data (expecting InventoryFolderBase): " + ex.Message); - agentID = UUID.Zero; - sessionID = UUID.Zero; - return null; - } - - return folder; - } - - InventoryItem DeserializeItem(Stream stream, out UUID agentID, out UUID sessionID) - { - InventoryItem item = new InventoryItem(); - - 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"); - ReadUUID(reader, "ID", out item.ID); - Int32.TryParse(reader.ReadElementContentAsString("InvType", String.Empty), out item.InvType); - ReadUUID(reader, "Folder", out item.Folder); - ReadUUID(reader, "Owner", out item.Owner); - ReadUUID(reader, "Creator", out item.Creator); - item.Name = reader.ReadElementContentAsString("Name", String.Empty); - item.Description = reader.ReadElementContentAsString("Description", String.Empty); - UInt32.TryParse(reader.ReadElementContentAsString("NextPermissions", String.Empty), out item.NextPermissions); - UInt32.TryParse(reader.ReadElementContentAsString("CurrentPermissions", String.Empty), out item.CurrentPermissions); - UInt32.TryParse(reader.ReadElementContentAsString("BasePermissions", String.Empty), out item.BasePermissions); - UInt32.TryParse(reader.ReadElementContentAsString("EveryOnePermissions", String.Empty), out item.EveryOnePermissions); - UInt32.TryParse(reader.ReadElementContentAsString("GroupPermissions", String.Empty), out item.GroupPermissions); - Int32.TryParse(reader.ReadElementContentAsString("AssetType", String.Empty), out item.AssetType); - ReadUUID(reader, "AssetID", out item.AssetID); - ReadUUID(reader, "GroupID", out item.GroupID); - Boolean.TryParse(reader.ReadElementContentAsString("GroupOwned", String.Empty), out item.GroupOwned); - Int32.TryParse(reader.ReadElementContentAsString("SalePrice", String.Empty), out item.SalePrice); - Byte.TryParse(reader.ReadElementContentAsString("SaleType", String.Empty), out item.SaleType); - UInt32.TryParse(reader.ReadElementContentAsString("Flags", String.Empty), out item.Flags); - Int32.TryParse(reader.ReadElementContentAsString("CreationDate", String.Empty), out item.CreationDate); - reader.ReadEndElement(); - reader.ReadEndElement(); - } - } - catch (Exception ex) - { - Logger.Log.Warn("Failed to parse POST data (expecting InventoryItemBase): " + ex.Message); - agentID = UUID.Zero; - sessionID = UUID.Zero; - return null; - } - - return item; - } - - void SerializeBool(Stream stream, bool value) - { - using (XmlWriter writer = XmlWriter.Create(stream)) - { - 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(); - } - - stream.Flush(); - } - - void SerializeFolderList(Stream stream, List 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 (InventoryFolder 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(); - } - - void SerializeItemList(Stream stream, List 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 (InventoryItem 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); - WriteUUID(writer, "Creator", item.Creator); - 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(); - } - - void WriteUUID(XmlWriter writer, string name, UUID id) - { - writer.WriteStartElement(name); - writer.WriteElementString("Guid", XmlConvert.ToString(id.Guid)); - writer.WriteEndElement(); - } - - 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 - - /// - /// The different types of grid assets - /// - public enum AssetType : sbyte - { - /// Unknown asset type - Unknown = -1, - /// Texture asset, stores in JPEG2000 J2C stream format - Texture = 0, - /// Sound asset - Sound = 1, - /// Calling card for another avatar - CallingCard = 2, - /// Link to a location in world - Landmark = 3, - // Legacy script asset, you should never see one of these - //[Obsolete] - //Script = 4, - /// Collection of textures and parameters that can be - /// worn by an avatar - Clothing = 5, - /// Primitive that can contain textures, sounds, - /// scripts and more - Object = 6, - /// Notecard asset - Notecard = 7, - /// Holds a collection of inventory items - Folder = 8, - /// Root inventory folder - RootFolder = 9, - /// Linden scripting language script - LSLText = 10, - /// LSO bytecode for a script - LSLBytecode = 11, - /// Uncompressed TGA texture - TextureTGA = 12, - /// Collection of textures and shape parameters that can - /// be worn - Bodypart = 13, - /// Trash folder - TrashFolder = 14, - /// Snapshot folder - SnapshotFolder = 15, - /// Lost and found folder - LostAndFoundFolder = 16, - /// Uncompressed sound - SoundWAV = 17, - /// Uncompressed TGA non-square image, not to be used as a - /// texture - ImageTGA = 18, - /// Compressed JPEG non-square image, not to be used as a - /// texture - ImageJPEG = 19, - /// Animation - Animation = 20, - /// Sequence of animations, sounds, chat, and pauses - Gesture = 21, - /// Simstate file - Simstate = 22, - } - - #endregion OpenSim AssetType -} diff --git a/OpenSim/Grid/NewAssetServer/Extensions/OpenSimMySQLInventory.cs b/OpenSim/Grid/NewAssetServer/Extensions/OpenSimMySQLInventory.cs deleted file mode 100644 index 1b5facd..0000000 --- a/OpenSim/Grid/NewAssetServer/Extensions/OpenSimMySQLInventory.cs +++ /dev/null @@ -1,804 +0,0 @@ -/* - * Copyright (c) 2008 Intel Corporation - * All rights reserved. - * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``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 INTEL OR ITS - * 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.Net; -using System.Data; -using MySql.Data.MySqlClient; -using ExtensionLoader; -using ExtensionLoader.Config; -using OpenMetaverse; -using OpenMetaverse.StructuredData; - -namespace AssetServer.Extensions -{ - public class OpenSimMySQLInventory : IExtension, IInventoryProvider - { - const string EXTENSION_NAME = "OpenSimMySQLInventory"; // Used in metrics reporting - - AssetServer server; - - public OpenSimMySQLInventory() - { - } - - #region Required Interfaces - - public void Start(AssetServer server) - { - this.server = server; - - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - try - { - dbConnection.Open(); - Logger.Log.Info("Connected to MySQL inventory backend: " + dbConnection.ServerVersion); - } - catch (MySqlException ex) - { - Logger.Log.Error("Connection to MySQL inventory backend failed: " + ex.Message); - } - } - } - - public void Stop() - { - } - - public BackendResponse TryFetchItem(Uri owner, UUID itemID, out InventoryItem item) - { - item = null; - BackendResponse ret; - - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - 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 InventoryItem(); - 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) - { - Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); - ret = BackendResponse.Failure; - } - } - - server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now); - return ret; - } - - public BackendResponse TryFetchFolder(Uri owner, UUID folderID, out InventoryFolder folder) - { - folder = null; - BackendResponse ret; - - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - IDataReader reader; - - try - { - dbConnection.Open(); - - IDbCommand command = dbConnection.CreateCommand(); - command.CommandText = String.Format("SELECT folderName,type,version,agentID,parentFolderID FROM inventoryfolders WHERE folderID='{0}'", - folderID.ToString()); - reader = command.ExecuteReader(); - - if (reader.Read()) - { - folder = new InventoryFolder(); - folder.Children = null; // This call only returns data for the folder itself, no children data - folder.ID = folderID; - folder.Name = reader.GetString(0); - folder.Type = reader.GetInt16(1); - folder.Version = (ushort)reader.GetInt16(2); - folder.Owner = UUID.Parse(reader.GetString(3)); - folder.ParentID = UUID.Parse(reader.GetString(4)); - - ret = BackendResponse.Success; - } - else - { - ret = BackendResponse.NotFound; - } - } - catch (MySqlException ex) - { - Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); - ret = BackendResponse.Failure; - } - } - - 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(DBConnString.GetConnectionString(server.ConfigFile))) - { - 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(); - - while (reader.Read()) - { - InventoryFolder folder = new InventoryFolder(); - 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(); - - while (reader.Read()) - { - InventoryItem item = new InventoryItem(); - 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) - { - Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); - ret = BackendResponse.Failure; - } - } - - server.MetricsProvider.LogInventoryFetchFolderContents(EXTENSION_NAME, ret, owner, folderID, DateTime.Now); - return ret; - } - - public BackendResponse TryFetchFolderList(Uri owner, out List folders) - { - folders = null; - BackendResponse ret; - UUID ownerID; - - if (Utils.TryGetOpenSimUUID(owner, out ownerID)) - { - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - IDataReader reader; - - try - { - dbConnection.Open(); - folders = new List(); - - IDbCommand command = dbConnection.CreateCommand(); - command.CommandText = String.Format("SELECT folderName,type,version,folderID,parentFolderID FROM inventoryfolders WHERE agentID='{0}'", - ownerID.ToString()); - reader = command.ExecuteReader(); - - while (reader.Read()) - { - InventoryFolder folder = new InventoryFolder(); - folder.Owner = ownerID; - folder.Children = null; // This call does not create a folder hierarchy - folder.Name = reader.GetString(0); - folder.Type = reader.GetInt16(1); - folder.Version = (ushort)reader.GetInt16(2); - folder.ID = UUID.Parse(reader.GetString(3)); - folder.ParentID = UUID.Parse(reader.GetString(4)); - - folders.Add(folder); - } - - ret = BackendResponse.Success; - } - catch (MySqlException ex) - { - Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); - ret = BackendResponse.Failure; - } - } - } - 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; - List folders; - UUID ownerID; - - ret = TryFetchFolderList(owner, out folders); - - if (ret == BackendResponse.Success) - { - // Add the retrieved folders to the inventory collection - inventory = new InventoryCollection(); - inventory.Folders = new Dictionary(folders.Count); - foreach (InventoryFolder folder in folders) - inventory.Folders[folder.ID] = folder; - - // Fetch inventory items - if (Utils.TryGetOpenSimUUID(owner, out ownerID)) - { - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - 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,inventoryID,parentFolderID,inventoryGroupPermissions FROM inventoryitems WHERE " + - "avatarID='{0}'", ownerID.ToString()); - reader = command.ExecuteReader(); - - inventory.UserID = ownerID; - inventory.Items = new Dictionary(); - - while (reader.Read()) - { - InventoryItem item = new InventoryItem(); - item.Owner = ownerID; - 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.ID = UUID.Parse(reader.GetString(16)); - item.Folder = UUID.Parse(reader.GetString(17)); - item.GroupPermissions = (uint)reader.GetInt32(18); - - inventory.Items.Add(item.ID, item); - } - - ret = BackendResponse.Success; - } - catch (MySqlException ex) - { - Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); - ret = BackendResponse.Failure; - } - } - } - else - { - ret = BackendResponse.NotFound; - } - } - - server.MetricsProvider.LogInventoryFetchInventory(EXTENSION_NAME, ret, owner, DateTime.Now); - return ret; - } - - public BackendResponse TryFetchActiveGestures(Uri owner, out List gestures) - { - gestures = null; - BackendResponse ret; - UUID ownerID; - - if (Utils.TryGetOpenSimUUID(owner, out ownerID)) - { - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - IDataReader reader; - - try - { - dbConnection.Open(); - - MySqlCommand command = new MySqlCommand("SELECT assetID,inventoryName,inventoryDescription,inventoryNextPermissions," + - "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," + - "creationDate,groupID,groupOwned,inventoryID,parentFolderID,inventoryGroupPermissions FROM inventoryitems WHERE " + - "avatarId=?uuid AND assetType=?type AND flags=1", dbConnection); - command.Parameters.AddWithValue("?uuid", ownerID.ToString()); - command.Parameters.AddWithValue("?type", (int)AssetType.Gesture); - reader = command.ExecuteReader(); - - while (reader.Read()) - { - InventoryItem item = new InventoryItem(); - item.Owner = ownerID; - item.AssetType = (int)AssetType.Gesture; - item.Flags = (uint)1; - item.AssetID = UUID.Parse(reader.GetString(0)); - item.Name = reader.GetString(1); - item.Description = reader.GetString(2); - item.NextPermissions = (uint)reader.GetInt32(3); - item.CurrentPermissions = (uint)reader.GetInt32(4); - item.InvType = reader.GetInt32(5); - item.Creator = UUID.Parse(reader.GetString(6)); - item.BasePermissions = (uint)reader.GetInt32(7); - item.EveryOnePermissions = (uint)reader.GetInt32(8); - item.SalePrice = reader.GetInt32(9); - item.SaleType = reader.GetByte(10); - item.CreationDate = reader.GetInt32(11); - item.GroupID = UUID.Parse(reader.GetString(12)); - item.GroupOwned = reader.GetBoolean(13); - item.ID = UUID.Parse(reader.GetString(14)); - item.Folder = UUID.Parse(reader.GetString(15)); - item.GroupPermissions = (uint)reader.GetInt32(16); - - gestures.Add(item); - } - - ret = BackendResponse.Success; - } - catch (MySqlException ex) - { - Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); - ret = BackendResponse.Failure; - } - } - } - else - { - ret = BackendResponse.NotFound; - } - - server.MetricsProvider.LogInventoryFetchActiveGestures(EXTENSION_NAME, ret, owner, DateTime.Now); - return ret; - } - - public BackendResponse TryCreateItem(Uri owner, InventoryItem item) - { - BackendResponse ret; - - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - try - { - dbConnection.Open(); - - MySqlCommand command = new MySqlCommand( - "REPLACE INTO inventoryitems (assetID,assetType,inventoryName,inventoryDescription,inventoryNextPermissions," + - "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," + - "creationDate,groupID,groupOwned,flags,inventoryID,avatarID,parentFolderID,inventoryGroupPermissions) VALUES " + - - "(?assetID,?assetType,?inventoryName,?inventoryDescription,?inventoryNextPermissions,?inventoryCurrentPermissions,?invType," + - "?creatorID,?inventoryBasePermissions,?inventoryEveryOnePermissions,?salePrice,?saleType,?creationDate,?groupID,?groupOwned," + - "?flags,?inventoryID,?avatarID,?parentFolderID,?inventoryGroupPermissions)", dbConnection); - - command.Parameters.AddWithValue("?assetID", item.AssetID.ToString()); - command.Parameters.AddWithValue("?assetType", item.AssetType); - command.Parameters.AddWithValue("?inventoryName", item.Name); - command.Parameters.AddWithValue("?inventoryDescription", item.Description); - command.Parameters.AddWithValue("?inventoryNextPermissions", item.NextPermissions); - command.Parameters.AddWithValue("?inventoryCurrentPermissions", item.CurrentPermissions); - command.Parameters.AddWithValue("?invType", item.InvType); - command.Parameters.AddWithValue("?creatorID", item.Creator.ToString()); - command.Parameters.AddWithValue("?inventoryBasePermissions", item.BasePermissions); - command.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.EveryOnePermissions); - command.Parameters.AddWithValue("?salePrice", item.SalePrice); - command.Parameters.AddWithValue("?saleType", item.SaleType); - command.Parameters.AddWithValue("?creationDate", item.CreationDate); - command.Parameters.AddWithValue("?groupID", item.GroupID.ToString()); - command.Parameters.AddWithValue("?groupOwned", item.GroupOwned); - command.Parameters.AddWithValue("?flags", item.Flags); - command.Parameters.AddWithValue("?inventoryID", item.ID); - command.Parameters.AddWithValue("?avatarID", item.Owner); - command.Parameters.AddWithValue("?parentFolderID", item.Folder); - command.Parameters.AddWithValue("?inventoryGroupPermissions", item.GroupPermissions); - - int rowsAffected = command.ExecuteNonQuery(); - if (rowsAffected == 1) - { - ret = BackendResponse.Success; - } - else if (rowsAffected == 2) - { - Logger.Log.Info("Replaced inventory item " + item.ID.ToString()); - ret = BackendResponse.Success; - } - else - { - Logger.Log.ErrorFormat("MySQL REPLACE query affected {0} rows", rowsAffected); - ret = BackendResponse.Failure; - } - } - catch (MySqlException ex) - { - Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); - ret = BackendResponse.Failure; - } - } - - server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, false, DateTime.Now); - return ret; - } - - public BackendResponse TryCreateFolder(Uri owner, InventoryFolder folder) - { - BackendResponse ret; - - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - try - { - dbConnection.Open(); - - MySqlCommand command = new MySqlCommand( - "REPLACE INTO inventoryfolders (folderName,type,version,folderID,agentID,parentFolderID) VALUES " + - "(?folderName,?type,?version,?folderID,?agentID,?parentFolderID)", dbConnection); - - command.Parameters.AddWithValue("?folderName", folder.Name); - command.Parameters.AddWithValue("?type", folder.Type); - command.Parameters.AddWithValue("?version", folder.Version); - command.Parameters.AddWithValue("?folderID", folder.ID); - command.Parameters.AddWithValue("?agentID", folder.Owner); - command.Parameters.AddWithValue("?parentFolderID", folder.ParentID); - - int rowsAffected = command.ExecuteNonQuery(); - if (rowsAffected == 1) - { - ret = BackendResponse.Success; - } - else if (rowsAffected == 2) - { - Logger.Log.Info("Replaced inventory folder " + folder.ID.ToString()); - ret = BackendResponse.Success; - } - else - { - Logger.Log.ErrorFormat("MySQL REPLACE query affected {0} rows", rowsAffected); - ret = BackendResponse.Failure; - } - } - catch (MySqlException ex) - { - Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); - ret = BackendResponse.Failure; - } - } - - server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, true, DateTime.Now); - return ret; - } - - public BackendResponse TryCreateInventory(Uri owner, InventoryFolder rootFolder) - { - return TryCreateFolder(owner, rootFolder); - } - - public BackendResponse TryDeleteItem(Uri owner, UUID itemID) - { - BackendResponse ret; - UUID ownerID; - - if (Utils.TryGetOpenSimUUID(owner, out ownerID)) - { - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - try - { - dbConnection.Open(); - - MySqlCommand command = new MySqlCommand( - "DELETE FROM inventoryitems WHERE inventoryID=?inventoryID AND avatarID=?avatarID", dbConnection); - - command.Parameters.AddWithValue("?inventoryID", itemID.ToString()); - command.Parameters.AddWithValue("?avatarID", ownerID.ToString()); - - int rowsAffected = command.ExecuteNonQuery(); - if (rowsAffected == 1) - { - ret = BackendResponse.Success; - } - else - { - Logger.Log.ErrorFormat("MySQL DELETE query affected {0} rows", rowsAffected); - ret = BackendResponse.NotFound; - } - } - catch (MySqlException ex) - { - Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); - ret = BackendResponse.Failure; - } - } - } - 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; - UUID ownerID; - - if (Utils.TryGetOpenSimUUID(owner, out ownerID)) - { - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - 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 - { - Logger.Log.ErrorFormat("MySQL DELETE query affected {0} rows", rowsAffected); - ret = BackendResponse.NotFound; - } - } - catch (MySqlException ex) - { - Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); - ret = BackendResponse.Failure; - } - } - } - 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; - UUID ownerID; - - if (Utils.TryGetOpenSimUUID(owner, out ownerID)) - { - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - try - { - dbConnection.Open(); - - #region Delete items - - MySqlCommand command = new MySqlCommand( - "DELETE FROM inventoryitems WHERE parentFolderID=?parentFolderID AND avatarID=?avatarID", dbConnection); - - command.Parameters.AddWithValue("?parentFolderID", folderID.ToString()); - command.Parameters.AddWithValue("?avatarID", ownerID.ToString()); - - int rowsAffected = command.ExecuteNonQuery(); - - #endregion Delete items - - #region Delete folders - - command = new MySqlCommand( - "DELETE FROM inventoryfolders WHERE parentFolderID=?parentFolderID AND agentID=?agentID", dbConnection); - - command.Parameters.AddWithValue("?parentFolderID", folderID.ToString()); - command.Parameters.AddWithValue("?agentID", ownerID.ToString()); - - rowsAffected += command.ExecuteNonQuery(); - - #endregion Delete folders - - Logger.Log.DebugFormat("Deleted {0} inventory objects from MySQL in a folder purge", rowsAffected); - - ret = BackendResponse.Success; - } - catch (MySqlException ex) - { - Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); - ret = BackendResponse.Failure; - } - } - } - else - { - ret = BackendResponse.NotFound; - } - - server.MetricsProvider.LogInventoryPurgeFolder(EXTENSION_NAME, ret, owner, folderID, DateTime.Now); - return ret; - } - - public int ForEach(Action action, int start, int count) - { - int rowCount = 0; - - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - 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) - { - Logger.Log.Error("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 Required Interfaces - } -} diff --git a/OpenSim/Grid/NewAssetServer/Extensions/OpenSimMySQLStorage.cs b/OpenSim/Grid/NewAssetServer/Extensions/OpenSimMySQLStorage.cs deleted file mode 100644 index 34f1ef0..0000000 --- a/OpenSim/Grid/NewAssetServer/Extensions/OpenSimMySQLStorage.cs +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (c) 2008 Intel Corporation - * All rights reserved. - * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``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 INTEL OR ITS - * 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.Net; -using System.Data; -using MySql.Data.MySqlClient; -using ExtensionLoader; -using ExtensionLoader.Config; -using OpenMetaverse; -using OpenMetaverse.StructuredData; - -namespace AssetServer.Extensions -{ - public class OpenSimMySQLStorage : IExtension, IStorageProvider - { - const string EXTENSION_NAME = "OpenSimMySQLStorage"; // Used in metrics reporting - - AssetServer server; - - public OpenSimMySQLStorage() - { - } - - #region Required Interfaces - - public void Start(AssetServer server) - { - this.server = server; - - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - try - { - dbConnection.Open(); - Logger.Log.Info("Connected to MySQL storage backend: " + dbConnection.ServerVersion); - } - catch (MySqlException ex) - { - Logger.Log.Error("Connection to MySQL storage backend failed: " + ex.Message); - } - } - } - - public void Stop() - { - } - - public BackendResponse TryFetchMetadata(UUID assetID, out Metadata metadata) - { - metadata = null; - BackendResponse ret; - - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - IDataReader reader; - - try - { - dbConnection.Open(); - - IDbCommand command = dbConnection.CreateCommand(); - command.CommandText = String.Format("SELECT name,description,assetType,temporary FROM assets WHERE id='{0}'", assetID.ToString()); - reader = command.ExecuteReader(); - - if (reader.Read()) - { - metadata = new Metadata(); - metadata.CreationDate = OpenMetaverse.Utils.Epoch; - metadata.SHA1 = null; - metadata.ID = assetID; - metadata.Name = reader.GetString(0); - metadata.Description = reader.GetString(1); - metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2)); - metadata.Temporary = reader.GetBoolean(3); - - ret = BackendResponse.Success; - } - else - { - ret = BackendResponse.NotFound; - } - } - catch (MySqlException ex) - { - Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); - ret = BackendResponse.Failure; - } - } - - server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now); - return ret; - } - - public BackendResponse TryFetchData(UUID assetID, out byte[] assetData) - { - assetData = null; - BackendResponse ret; - - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - IDataReader reader; - - try - { - dbConnection.Open(); - - IDbCommand command = dbConnection.CreateCommand(); - command.CommandText = String.Format("SELECT data FROM assets WHERE id='{0}'", assetID.ToString()); - reader = command.ExecuteReader(); - - if (reader.Read()) - { - assetData = (byte[])reader.GetValue(0); - ret = BackendResponse.Success; - } - else - { - ret = BackendResponse.NotFound; - } - } - catch (MySqlException ex) - { - Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); - ret = BackendResponse.Failure; - } - } - - server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (assetData != null ? assetData.Length : 0), DateTime.Now); - return ret; - } - - public BackendResponse TryFetchDataMetadata(UUID assetID, out Metadata metadata, out byte[] assetData) - { - metadata = null; - assetData = null; - BackendResponse ret; - - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - IDataReader reader; - - try - { - dbConnection.Open(); - - IDbCommand command = dbConnection.CreateCommand(); - command.CommandText = String.Format("SELECT name,description,assetType,temporary,data FROM assets WHERE id='{0}'", assetID.ToString()); - reader = command.ExecuteReader(); - - if (reader.Read()) - { - metadata = new Metadata(); - metadata.CreationDate = OpenMetaverse.Utils.Epoch; - metadata.SHA1 = null; - metadata.ID = assetID; - metadata.Name = reader.GetString(0); - metadata.Description = reader.GetString(1); - metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2)); - metadata.Temporary = reader.GetBoolean(3); - - assetData = (byte[])reader.GetValue(4); - - ret = BackendResponse.Success; - } - else - { - ret = BackendResponse.NotFound; - } - } - catch (MySqlException ex) - { - Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); - ret = BackendResponse.Failure; - } - } - - server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now); - server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (assetData != null ? assetData.Length : 0), DateTime.Now); - return ret; - } - - public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData, out UUID assetID) - { - assetID = metadata.ID = UUID.Random(); - return TryCreateAsset(metadata, assetData); - } - - public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData) - { - BackendResponse ret; - - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - try - { - dbConnection.Open(); - - MySqlCommand command = new MySqlCommand( - "REPLACE INTO assets (name,description,assetType,local,temporary,data,id) VALUES " + - "(?name,?description,?assetType,?local,?temporary,?data,?id)", dbConnection); - - command.Parameters.AddWithValue("?name", metadata.Name); - command.Parameters.AddWithValue("?description", metadata.Description); - command.Parameters.AddWithValue("?assetType", Utils.ContentTypeToSLAssetType(metadata.ContentType)); - command.Parameters.AddWithValue("?local", 0); - command.Parameters.AddWithValue("?temporary", metadata.Temporary); - command.Parameters.AddWithValue("?data", assetData); - command.Parameters.AddWithValue("?id", metadata.ID.ToString()); - - int rowsAffected = command.ExecuteNonQuery(); - if (rowsAffected == 1) - { - ret = BackendResponse.Success; - } - else if (rowsAffected == 2) - { - Logger.Log.Info("Replaced asset " + metadata.ID.ToString()); - ret = BackendResponse.Success; - } - else - { - Logger.Log.ErrorFormat("MySQL REPLACE query affected {0} rows", rowsAffected); - ret = BackendResponse.Failure; - } - } - catch (MySqlException ex) - { - Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); - ret = BackendResponse.Failure; - } - } - - server.MetricsProvider.LogAssetCreate(EXTENSION_NAME, ret, metadata.ID, assetData.Length, DateTime.Now); - return ret; - } - - public int ForEach(Action action, int start, int count) - { - int rowCount = 0; - - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - 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) - { - Logger.Log.Error("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 Required Interfaces - } -} diff --git a/OpenSim/Grid/NewAssetServer/Extensions/ReferenceFrontend.cs b/OpenSim/Grid/NewAssetServer/Extensions/ReferenceFrontend.cs deleted file mode 100644 index 133f87c..0000000 --- a/OpenSim/Grid/NewAssetServer/Extensions/ReferenceFrontend.cs +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (c) 2008 Intel Corporation - * All rights reserved. - * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``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 INTEL OR ITS - * 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.Net; -using System.Xml; -using ExtensionLoader; -using OpenMetaverse; -using OpenMetaverse.StructuredData; -using HttpServer; - -namespace AssetServer.Extensions -{ - public class ReferenceFrontend : IExtension - { - AssetServer server; - - public ReferenceFrontend() - { - } - - public void Start(AssetServer server) - { - this.server = server; - - // Asset metadata request - server.HttpServer.AddHandler("get", null, @"^/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/metadata", - MetadataRequestHandler); - - // Asset data request - server.HttpServer.AddHandler("get", null, @"^/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/data", - DataRequestHandler); - - // Asset creation - server.HttpServer.AddHandler("post", null, "^/createasset", CreateRequestHandler); - } - - public void Stop() - { - } - - bool MetadataRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) - { - UUID assetID; - // Split the URL up into an AssetID and a method - string[] rawUrl = request.Uri.PathAndQuery.Split('/'); - - if (rawUrl.Length >= 3 && UUID.TryParse(rawUrl[1], out assetID)) - { - UUID authToken = Utils.GetAuthToken(request); - - if (server.AuthorizationProvider.IsMetadataAuthorized(authToken, assetID)) - { - Metadata metadata; - BackendResponse storageResponse = 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", - request.Uri.Scheme, request.Uri.Authority, assetID)); - } - - byte[] serializedData = metadata.SerializeToBytes(); - - response.Status = HttpStatusCode.OK; - response.ContentType = "application/json"; - response.ContentLength = serializedData.Length; - response.Body.Write(serializedData, 0, serializedData.Length); - - } - else if (storageResponse == BackendResponse.NotFound) - { - Logger.Log.Warn("Could not find metadata for asset " + assetID.ToString()); - response.Status = HttpStatusCode.NotFound; - } - else - { - response.Status = HttpStatusCode.InternalServerError; - } - } - else - { - response.Status = HttpStatusCode.Forbidden; - } - - return true; - } - - response.Status = HttpStatusCode.NotFound; - return true; - } - - bool DataRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) - { - UUID assetID; - // Split the URL up into an AssetID and a method - string[] rawUrl = request.Uri.PathAndQuery.Split('/'); - - if (rawUrl.Length >= 3 && UUID.TryParse(rawUrl[1], out assetID)) - { - UUID authToken = Utils.GetAuthToken(request); - - if (server.AuthorizationProvider.IsDataAuthorized(authToken, assetID)) - { - byte[] assetData; - BackendResponse storageResponse = server.StorageProvider.TryFetchData(assetID, out assetData); - - if (storageResponse == BackendResponse.Success) - { - response.Status = HttpStatusCode.OK; - response.Status = HttpStatusCode.OK; - response.ContentType = "application/octet-stream"; - response.AddHeader("Content-Disposition", "attachment; filename=" + assetID.ToString()); - response.ContentLength = assetData.Length; - response.Body.Write(assetData, 0, assetData.Length); - } - else if (storageResponse == BackendResponse.NotFound) - { - response.Status = HttpStatusCode.NotFound; - } - else - { - response.Status = HttpStatusCode.InternalServerError; - } - } - else - { - response.Status = HttpStatusCode.Forbidden; - } - - return true; - } - - response.Status = HttpStatusCode.BadRequest; - return true; - } - - bool CreateRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) - { - UUID authToken = Utils.GetAuthToken(request); - - if (server.AuthorizationProvider.IsCreateAuthorized(authToken)) - { - try - { - OSD osdata = OSDParser.DeserializeJson(request.Body); - - 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 = server.StorageProvider.TryCreateAsset(metadata, assetData); - else - storageResponse = server.StorageProvider.TryCreateAsset(metadata, assetData, out metadata.ID); - - if (storageResponse == BackendResponse.Success) - { - response.Status = HttpStatusCode.Created; - OSDMap responseMap = new OSDMap(1); - responseMap["id"] = OSD.FromUUID(metadata.ID); - LitJson.JsonData jsonData = OSDParser.SerializeJson(responseMap); - byte[] responseData = System.Text.Encoding.UTF8.GetBytes(jsonData.ToJson()); - response.Body.Write(responseData, 0, responseData.Length); - response.Body.Flush(); - } - else if (storageResponse == BackendResponse.NotFound) - { - response.Status = HttpStatusCode.NotFound; - } - else - { - response.Status = HttpStatusCode.InternalServerError; - } - } - else - { - response.Status = HttpStatusCode.BadRequest; - } - } - else - { - response.Status = HttpStatusCode.BadRequest; - } - } - catch (Exception ex) - { - response.Status = HttpStatusCode.InternalServerError; - response.Reason = ex.Message; - } - } - else - { - response.Status = HttpStatusCode.Forbidden; - } - - return true; - } - } -} diff --git a/OpenSim/Grid/NewAssetServer/Extensions/SimpleInventory.cs b/OpenSim/Grid/NewAssetServer/Extensions/SimpleInventory.cs deleted file mode 100644 index 782b6b4..0000000 --- a/OpenSim/Grid/NewAssetServer/Extensions/SimpleInventory.cs +++ /dev/null @@ -1,602 +0,0 @@ -/* - * Copyright (c) 2008 Intel Corporation - * All rights reserved. - * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``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 INTEL OR ITS - * 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.Net; -using System.IO; -using System.Text; -using ExtensionLoader; -using OpenMetaverse; -using OpenMetaverse.StructuredData; - -namespace AssetServer.Extensions -{ - public class SimpleInventory : IExtension, IInventoryProvider - { - const string EXTENSION_NAME = "SimpleInventory"; // Used for metrics reporting - const string DEFAULT_INVENTORY_DIR = "SimpleInventory"; - - AssetServer server; - Dictionary inventories = new Dictionary(); - Dictionary> activeGestures = new Dictionary>(); - Utils.InventoryItemSerializer itemSerializer = new Utils.InventoryItemSerializer(); - Utils.InventoryFolderSerializer folderSerializer = new Utils.InventoryFolderSerializer(); - - public SimpleInventory() - { - } - - #region Required Interfaces - - public void Start(AssetServer server) - { - this.server = server; - - LoadFiles(DEFAULT_INVENTORY_DIR); - - Logger.Log.InfoFormat("Initialized the inventory index with data for {0} avatars", - inventories.Count); - } - - public void Stop() - { - } - - public BackendResponse TryFetchItem(Uri owner, UUID itemID, out InventoryItem 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 InventoryFolder 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; - InventoryFolder folder; - - if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder)) - { - contents = new InventoryCollection(); - contents.UserID = collection.UserID; - contents.Folders = new Dictionary(); - contents.Items = new Dictionary(); - - foreach (InventoryBase invBase in folder.Children.Values) - { - if (invBase is InventoryItem) - { - InventoryItem invItem = invBase as InventoryItem; - contents.Items.Add(invItem.ID, invItem); - } - else - { - InventoryFolder invFolder = invBase as InventoryFolder; - 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 folders) - { - folders = null; - BackendResponse ret; - - InventoryCollection collection; - if (inventories.TryGetValue(owner, out collection)) - { - folders = new List(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 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, InventoryItem item) - { - BackendResponse ret; - - InventoryCollection collection; - if (inventories.TryGetValue(owner, out collection)) - { - // Delete this item first if it already exists - InventoryItem 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 - InventoryFolder 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) - { - Logger.Log.Error(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, InventoryFolder folder) - { - BackendResponse ret; - - InventoryCollection collection; - if (inventories.TryGetValue(owner, out collection)) - { - // Delete this folder first if it already exists - InventoryFolder 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 - InventoryFolder parent; - if (collection.Folders.TryGetValue(folder.ParentID, out parent)) - lock (parent.Children) parent.Children.Add(folder.ID, folder); - - ret = BackendResponse.Success; - } - catch (Exception ex) - { - Logger.Log.Error(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, InventoryFolder rootFolder) - { - BackendResponse ret; - - lock (inventories) - { - if (!inventories.ContainsKey(owner)) - { - InventoryCollection collection = new InventoryCollection(); - collection.UserID = rootFolder.Owner; - collection.Folders = new Dictionary(); - collection.Folders.Add(rootFolder.ID, rootFolder); - collection.Items = new Dictionary(); - - 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) - { - Logger.Log.Error(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; - InventoryItem item; - if (inventories.TryGetValue(owner, out collection) && collection.Items.TryGetValue(itemID, out item)) - { - // Remove the item from its parent folder - InventoryFolder 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) { Logger.Log.ErrorFormat("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; - InventoryFolder folder; - if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder)) - { - // Remove the folder from its parent folder - InventoryFolder 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) { Logger.Log.ErrorFormat("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; - InventoryFolder folder; - if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder)) - { - // Delete all of the folder children - foreach (InventoryBase obj in new List(folder.Children.Values)) - { - if (obj is InventoryItem) - { - TryDeleteItem(owner, (obj as InventoryItem).ID); - } - else - { - InventoryFolder childFolder = obj as InventoryFolder; - 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(InventoryItem 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(InventoryFolder 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) - { - Logger.Log.Warn(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) - { - Logger.Log.WarnFormat("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()); - - 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(folders.Length); - - for (int j = 0; j < folders.Length; j++) - { - InventoryFolder invFolder = (InventoryFolder)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 (InventoryFolder invFolder in collection.Folders.Values) - { - InventoryFolder 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(files.Length); - - for (int j = 0; j < files.Length; j++) - { - InventoryItem invItem = (InventoryItem)itemSerializer.Deserialize( - new FileStream(files[j], FileMode.Open, FileAccess.Read)); - collection.Items[invItem.ID] = invItem; - - // Add items to their parent folders - InventoryFolder 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) - { - Logger.Log.ErrorFormat("Failed loading inventory from {0}: {1}", folder, ex.Message); - } - } - } -} diff --git a/OpenSim/Grid/NewAssetServer/Extensions/SimpleStorage.cs b/OpenSim/Grid/NewAssetServer/Extensions/SimpleStorage.cs deleted file mode 100644 index 1c0fe33..0000000 --- a/OpenSim/Grid/NewAssetServer/Extensions/SimpleStorage.cs +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2008 Intel Corporation - * All rights reserved. - * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``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 INTEL OR ITS - * 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.Net; -using System.IO; -using ExtensionLoader; -using OpenMetaverse; -using OpenMetaverse.StructuredData; - -namespace AssetServer.Extensions -{ - public class SimpleStorage : IExtension, IStorageProvider - { - const string EXTENSION_NAME = ""; // Used in metrics reporting - const string DEFAULT_DATA_DIR = "SimpleAssets"; - const string TEMP_DATA_DIR = "SimpleAssetsTemp"; - - AssetServer server; - Dictionary metadataStorage; - Dictionary filenames; - - public SimpleStorage() - { - } - - #region Required Interfaces - - public void Start(AssetServer server) - { - this.server = server; - metadataStorage = new Dictionary(); - filenames = new Dictionary(); - - LoadFiles(DEFAULT_DATA_DIR, false); - LoadFiles(TEMP_DATA_DIR, true); - - Logger.Log.InfoFormat("Initialized the store index with metadata for {0} assets", - metadataStorage.Count); - } - - public void Stop() - { - WipeTemporary(); - } - - public BackendResponse TryFetchMetadata(UUID assetID, out Metadata 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) - { - Logger.Log.ErrorFormat("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 Metadata metadata, out byte[] assetData) - { - metadata = null; - assetData = null; - string filename; - BackendResponse ret; - - if (metadataStorage.TryGetValue(assetID, out metadata) && - filenames.TryGetValue(assetID, out filename)) - { - try - { - assetData = File.ReadAllBytes(filename); - ret = BackendResponse.Success; - } - catch (Exception ex) - { - Logger.Log.ErrorFormat("Failed reading data for asset {0} from {1}: {2}", assetID, filename, ex.Message); - ret = BackendResponse.Failure; - } - } - else - { - ret = BackendResponse.NotFound; - } - - server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now); - server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (assetData != null ? assetData.Length : 0), DateTime.Now); - return ret; - } - - public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData, out UUID assetID) - { - assetID = metadata.ID = UUID.Random(); - return TryCreateAsset(metadata, assetData); - } - - public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData) - { - BackendResponse ret; - - string path; - string filename = String.Format("{0}.{1}", metadata.ID, Utils.ContentTypeToExtension(metadata.ContentType)); - - if (metadata.Temporary) - path = Path.Combine(TEMP_DATA_DIR, filename); - else - path = Path.Combine(DEFAULT_DATA_DIR, filename); - - try - { - File.WriteAllBytes(path, assetData); - lock (filenames) filenames[metadata.ID] = path; - - // Set the creation date to right now - metadata.CreationDate = DateTime.Now; - - lock (metadataStorage) - metadataStorage[metadata.ID] = metadata; - - ret = BackendResponse.Success; - } - catch (Exception ex) - { - Logger.Log.ErrorFormat("Failed writing data for asset {0} to {1}: {2}", metadata.ID, filename, ex.Message); - ret = BackendResponse.Failure; - } - - server.MetricsProvider.LogAssetCreate(EXTENSION_NAME, ret, metadata.ID, assetData.Length, DateTime.Now); - return ret; - } - - public int ForEach(Action action, int start, int count) - { - int rowCount = 0; - - lock (metadataStorage) - { - foreach (Metadata metadata in metadataStorage.Values) - { - action(metadata); - ++rowCount; - } - } - - return rowCount; - } - - #endregion Required Interfaces - - public void WipeTemporary() - { - if (Directory.Exists(TEMP_DATA_DIR)) - { - try { Directory.Delete(TEMP_DATA_DIR); } - catch (Exception ex) { Logger.Log.Error(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) - { - Logger.Log.Warn(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); - - Metadata metadata = new Metadata(); - metadata.CreationDate = File.GetCreationTime(filename); - metadata.Description = String.Empty; - metadata.ID = 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.ID] = metadata; - filenames[metadata.ID] = filename; - } - } - catch (Exception ex) - { - Logger.Log.Warn(ex.Message); - } - } - } - } -} diff --git a/OpenSim/Grid/NewAssetServer/Extensions/SimpleUtils.cs b/OpenSim/Grid/NewAssetServer/Extensions/SimpleUtils.cs deleted file mode 100644 index 6642f90..0000000 --- a/OpenSim/Grid/NewAssetServer/Extensions/SimpleUtils.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.IO; -using OpenMetaverse; - -namespace AssetServer.Extensions -{ - 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; - } - } - } -} diff --git a/OpenSim/Grid/NewAssetServer/Interfaces.cs b/OpenSim/Grid/NewAssetServer/Interfaces.cs deleted file mode 100644 index 8368922..0000000 --- a/OpenSim/Grid/NewAssetServer/Interfaces.cs +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2008 Intel Corporation - * All rights reserved. - * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``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 INTEL OR ITS - * 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.Net; -using OpenMetaverse; -using OpenMetaverse.StructuredData; -using OpenSim.Framework; - -namespace AssetServer -{ - /// - /// Response from a call to a backend provider - /// - public enum BackendResponse - { - /// The call succeeded - Success, - /// The resource requested was not found - NotFound, - /// A server failure prevented the call from - /// completing - Failure - } - - public class AssetServerPluginInitialiser : PluginInitialiserBase - { - private AssetServer server; - - public AssetServerPluginInitialiser (AssetServer server) - { - this.server = server; - } - - public override void Initialise (IPlugin plugin) - { - IAssetServerPlugin p = plugin as IAssetServerPlugin; - p.Initialise (server); - } - } - - #region Interfaces - - public interface IAssetServerPlugin : IPlugin - { - void Initialise(AssetServer server); - } - - public interface IStorageProvider - { - BackendResponse TryFetchMetadata(UUID assetID, out Metadata metadata); - BackendResponse TryFetchData(UUID assetID, out byte[] assetData); - BackendResponse TryFetchDataMetadata(UUID assetID, out Metadata metadata, out byte[] assetData); - BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData); - BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData, out UUID assetID); - int ForEach(Action action, int start, int count); - } - - public interface IAssetStorageProvider : IAssetServerPlugin - { - BackendResponse TryFetchMetadata(UUID assetID, out Metadata metadata); - BackendResponse TryFetchData(UUID assetID, out byte[] assetData); - BackendResponse TryFetchDataMetadata(UUID assetID, out Metadata metadata, out byte[] assetData); - BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData); - BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData, out UUID assetID); - int ForEach(Action action, int start, int count); - } - - public interface IInventoryProvider - { - BackendResponse TryFetchItem(Uri owner, UUID itemID, out InventoryItem item); - BackendResponse TryFetchFolder(Uri owner, UUID folderID, out InventoryFolder folder); - BackendResponse TryFetchFolderContents(Uri owner, UUID folderID, out InventoryCollection contents); - BackendResponse TryFetchFolderList(Uri owner, out List folders); - BackendResponse TryFetchInventory(Uri owner, out InventoryCollection inventory); - - BackendResponse TryFetchActiveGestures(Uri owner, out List gestures); - - BackendResponse TryCreateItem(Uri owner, InventoryItem item); - BackendResponse TryCreateFolder(Uri owner, InventoryFolder folder); - BackendResponse TryCreateInventory(Uri owner, InventoryFolder rootFolder); - - BackendResponse TryDeleteItem(Uri owner, UUID itemID); - BackendResponse TryDeleteFolder(Uri owner, UUID folderID); - BackendResponse TryPurgeFolder(Uri owner, UUID folderID); - } - - public interface IAuthenticationProvider - { - void AddIdentifier(UUID authToken, Uri identifier); - bool RemoveIdentifier(UUID authToken); - bool TryGetIdentifier(UUID authToken, out Uri identifier); - } - - public interface IAuthorizationProvider - { - bool IsMetadataAuthorized(UUID authToken, UUID assetID); - /// - /// Authorizes access to the data for an asset. Access to asset data - /// also implies access to the metadata for that asset - /// - /// Authentication token to check for access - /// ID of the requested asset - /// True if access is granted, otherwise false - 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 - { - 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 -} diff --git a/OpenSim/Grid/NewAssetServer/InventoryObjects.cs b/OpenSim/Grid/NewAssetServer/InventoryObjects.cs deleted file mode 100644 index cffa643..0000000 --- a/OpenSim/Grid/NewAssetServer/InventoryObjects.cs +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2008 Intel Corporation - * All rights reserved. - * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``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 INTEL OR ITS - * 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; - -namespace AssetServer -{ - 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 Children = new Dictionary(); - - 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 InventoryCollection - { - public Dictionary Folders; - public Dictionary Items; - public UUID UserID; - } -} diff --git a/OpenSim/Grid/NewAssetServer/Logger.cs b/OpenSim/Grid/NewAssetServer/Logger.cs deleted file mode 100644 index dd40115..0000000 --- a/OpenSim/Grid/NewAssetServer/Logger.cs +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2008 Intel Corporation - * All rights reserved. - * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``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 INTEL OR ITS - * 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 log4net; -using log4net.Config; - -[assembly: log4net.Config.XmlConfigurator(ConfigFileExtension = "log4net")] - -namespace AssetServer -{ - /// - /// Singleton logging class for the entire library - /// - public static class Logger - { - /// log4net logging engine - public static ILog Log; - - static Logger() - { - Log = LogManager.GetLogger(System.Reflection.Assembly.GetExecutingAssembly().FullName); - - // If error level reporting isn't enabled we assume no logger is configured and initialize a default - // ConsoleAppender - if (!Log.Logger.IsEnabledFor(log4net.Core.Level.Error)) - { - log4net.Appender.ConsoleAppender appender = new log4net.Appender.ConsoleAppender(); - appender.Layout = new log4net.Layout.PatternLayout("%timestamp [%thread] %-5level - %message%newline"); - BasicConfigurator.Configure(appender); - - Log.Info("No log configuration found, defaulting to console logging"); - } - } - } -} diff --git a/OpenSim/Grid/NewAssetServer/Main.cs b/OpenSim/Grid/NewAssetServer/Main.cs deleted file mode 100644 index 9f7dd3e..0000000 --- a/OpenSim/Grid/NewAssetServer/Main.cs +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2008 Intel Corporation - * All rights reserved. - * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``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 INTEL OR ITS - * 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.ServiceProcess; - -namespace AssetServer -{ - class MainEntry - { - static void Main(string[] args) - { -#if DEBUG - AssetServer server = new AssetServer(); - if (server.Start()) - { - Console.WriteLine("Asset server is running. Press CTRL+C to quit"); - - Console.CancelKeyPress += - delegate(object sender, ConsoleCancelEventArgs e) - { - Console.WriteLine("Asset server is shutting down..."); - server.Shutdown(); - Environment.Exit(0); - }; - - while (true) - Console.ReadLine(); - } -#else - ServiceBase[] servicesToRun = new ServiceBase[] { new AssetServer() }; - ServiceBase.Run(servicesToRun); -#endif - } - } -} diff --git a/OpenSim/Grid/NewAssetServer/Metadata.cs b/OpenSim/Grid/NewAssetServer/Metadata.cs deleted file mode 100644 index 247a3e8..0000000 --- a/OpenSim/Grid/NewAssetServer/Metadata.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Xml; -using OpenMetaverse; -using OpenMetaverse.StructuredData; - -namespace AssetServer -{ - public class Metadata - { - public UUID ID; - public string Name; - public string Description; - public DateTime CreationDate; - public string ContentType; - public byte[] SHA1; - public bool Temporary; - public Dictionary Methods = new Dictionary(); - public OSDMap ExtraData; - - public OSDMap SerializeToOSD() - { - OSDMap osdata = new OSDMap(); - - if (ID != UUID.Zero) osdata["id"] = OSD.FromUUID(ID); - osdata["name"] = OSD.FromString(Name); - osdata["description"] = OSD.FromString(Description); - osdata["creation_date"] = OSD.FromDate(CreationDate); - osdata["type"] = OSD.FromString(ContentType); - osdata["sha1"] = OSD.FromBinary(SHA1); - osdata["temporary"] = OSD.FromBoolean(Temporary); - - OSDMap methods = new OSDMap(Methods.Count); - foreach (KeyValuePair kvp in Methods) - methods.Add(kvp.Key, OSD.FromUri(kvp.Value)); - osdata["methods"] = methods; - - if (ExtraData != null) osdata["extra_data"] = ExtraData; - - return osdata; - } - - public byte[] SerializeToBytes() - { - LitJson.JsonData jsonData = OSDParser.SerializeJson(SerializeToOSD()); - return System.Text.Encoding.UTF8.GetBytes(jsonData.ToJson()); - } - - public void Deserialize(byte[] data) - { - OSD osdata = OSDParser.DeserializeJson(System.Text.Encoding.UTF8.GetString(data)); - Deserialize(osdata); - } - - public void Deserialize(string data) - { - OSD osdata = OSDParser.DeserializeJson(data); - Deserialize(osdata); - } - - public void Deserialize(OSD osdata) - { - if (osdata.Type == OSDType.Map) - { - OSDMap map = (OSDMap)osdata; - ID = map["id"].AsUUID(); - Name = map["name"].AsString(); - Description = map["description"].AsString(); - CreationDate = map["creation_date"].AsDate(); - ContentType = map["type"].AsString(); - SHA1 = map["sha1"].AsBinary(); - Temporary = map["temporary"].AsBoolean(); - - OSDMap methods = map["methods"] as OSDMap; - if (methods != null) - { - foreach (KeyValuePair kvp in methods) - Methods.Add(kvp.Key, kvp.Value.AsUri()); - } - - ExtraData = map["extra_data"] as OSDMap; - } - } - } -} diff --git a/OpenSim/Grid/NewAssetServer/Plugins/OpenSim/OpenSimAssetStoragePlugin.cs b/OpenSim/Grid/NewAssetServer/Plugins/OpenSim/OpenSimAssetStoragePlugin.cs deleted file mode 100644 index dd05e5d..0000000 --- a/OpenSim/Grid/NewAssetServer/Plugins/OpenSim/OpenSimAssetStoragePlugin.cs +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (c) 2008 Intel Corporation - * All rights reserved. - * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``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 INTEL OR ITS - * 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.Net; -using System.Data; -using MySql.Data.MySqlClient; -using ExtensionLoader; -using ExtensionLoader.Config; -using OpenMetaverse; -using OpenMetaverse.StructuredData; -using OpenSim.Framework; -using AssetServer.Extensions; - -namespace AssetServer.Plugins -{ - public class OpenSimAssetStoragePlugin : IAssetStorageProvider - { - const string EXTENSION_NAME = "OpenSimAssetStorage"; // Used in metrics reporting - - private AssetServer server; - private IAssetProviderPlugin m_assetProvider; - - public OpenSimAssetStoragePlugin() - { - } - - #region IAssetStorageProvider implementation - - public BackendResponse TryFetchMetadata(UUID assetID, out Metadata metadata) - { - metadata = null; - BackendResponse ret; - - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - IDataReader reader; - - try - { - dbConnection.Open(); - - IDbCommand command = dbConnection.CreateCommand(); - command.CommandText = String.Format("SELECT name,description,assetType,temporary FROM assets WHERE id='{0}'", assetID.ToString()); - reader = command.ExecuteReader(); - - if (reader.Read()) - { - metadata = new Metadata(); - metadata.CreationDate = OpenMetaverse.Utils.Epoch; - metadata.SHA1 = null; - metadata.ID = assetID; - metadata.Name = reader.GetString(0); - metadata.Description = reader.GetString(1); - metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2)); - metadata.Temporary = reader.GetBoolean(3); - - ret = BackendResponse.Success; - } - else - { - ret = BackendResponse.NotFound; - } - } - catch (MySqlException ex) - { - Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); - ret = BackendResponse.Failure; - } - } - - server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now); - return ret; - } - - public BackendResponse TryFetchData(UUID assetID, out byte[] assetData) - { - assetData = null; - BackendResponse ret; - - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - IDataReader reader; - - try - { - dbConnection.Open(); - - IDbCommand command = dbConnection.CreateCommand(); - command.CommandText = String.Format("SELECT data FROM assets WHERE id='{0}'", assetID.ToString()); - reader = command.ExecuteReader(); - - if (reader.Read()) - { - assetData = (byte[])reader.GetValue(0); - ret = BackendResponse.Success; - } - else - { - ret = BackendResponse.NotFound; - } - } - catch (MySqlException ex) - { - Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); - ret = BackendResponse.Failure; - } - } - - server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (assetData != null ? assetData.Length : 0), DateTime.Now); - return ret; - } - - public BackendResponse TryFetchDataMetadata(UUID assetID, out Metadata metadata, out byte[] assetData) - { - metadata = null; - assetData = null; - BackendResponse ret; - - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - IDataReader reader; - - try - { - dbConnection.Open(); - - IDbCommand command = dbConnection.CreateCommand(); - command.CommandText = String.Format("SELECT name,description,assetType,temporary,data FROM assets WHERE id='{0}'", assetID.ToString()); - reader = command.ExecuteReader(); - - if (reader.Read()) - { - metadata = new Metadata(); - metadata.CreationDate = OpenMetaverse.Utils.Epoch; - metadata.SHA1 = null; - metadata.ID = assetID; - metadata.Name = reader.GetString(0); - metadata.Description = reader.GetString(1); - metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2)); - metadata.Temporary = reader.GetBoolean(3); - - assetData = (byte[])reader.GetValue(4); - - ret = BackendResponse.Success; - } - else - { - ret = BackendResponse.NotFound; - } - } - catch (MySqlException ex) - { - Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); - ret = BackendResponse.Failure; - } - } - - server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now); - server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (assetData != null ? assetData.Length : 0), DateTime.Now); - return ret; - } - - public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData, out UUID assetID) - { - assetID = metadata.ID = UUID.Random(); - return TryCreateAsset(metadata, assetData); - } - - public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData) - { - BackendResponse ret; - - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - try - { - dbConnection.Open(); - - MySqlCommand command = new MySqlCommand( - "REPLACE INTO assets (name,description,assetType,local,temporary,data,id) VALUES " + - "(?name,?description,?assetType,?local,?temporary,?data,?id)", dbConnection); - - command.Parameters.AddWithValue("?name", metadata.Name); - command.Parameters.AddWithValue("?description", metadata.Description); - command.Parameters.AddWithValue("?assetType", Utils.ContentTypeToSLAssetType(metadata.ContentType)); - command.Parameters.AddWithValue("?local", 0); - command.Parameters.AddWithValue("?temporary", metadata.Temporary); - command.Parameters.AddWithValue("?data", assetData); - command.Parameters.AddWithValue("?id", metadata.ID.ToString()); - - int rowsAffected = command.ExecuteNonQuery(); - if (rowsAffected == 1) - { - ret = BackendResponse.Success; - } - else if (rowsAffected == 2) - { - Logger.Log.Info("Replaced asset " + metadata.ID.ToString()); - ret = BackendResponse.Success; - } - else - { - Logger.Log.ErrorFormat("MySQL REPLACE query affected {0} rows", rowsAffected); - ret = BackendResponse.Failure; - } - } - catch (MySqlException ex) - { - Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); - ret = BackendResponse.Failure; - } - } - - server.MetricsProvider.LogAssetCreate(EXTENSION_NAME, ret, metadata.ID, assetData.Length, DateTime.Now); - return ret; - } - - public int ForEach(Action action, int start, int count) - { - int rowCount = 0; - - using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) - { - 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) - { - Logger.Log.Error("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 IAssetStorageProvider implementation - - #region IPlugin implementation - - public void Initialise(AssetServer server) - { - this.server = server; - - try - { - m_assetProvider = LoadDatabasePlugin("OpenSim.Data.MySQL.dll", server.ConfigFile.Configs["MySQL"].GetString("database_connect", null)); - if (m_assetProvider == null) - { - Logger.Log.Error("[ASSET]: Failed to load a database plugin, server halting."); - Environment.Exit(-1); - } - else - Logger.Log.InfoFormat("[ASSET]: Loaded storage backend: {0}", Version); - } - catch (Exception e) - { - Logger.Log.WarnFormat("[ASSET]: Failure loading data plugin: {0}", e.ToString()); - } - } - - /// - /// Initialises asset interface - /// - public void Initialise() - { - Logger.Log.InfoFormat("[ASSET]: {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 "AssetServer storage provider"; } - } - - #endregion IPlugin implementation - - private IAssetProviderPlugin LoadDatabasePlugin(string provider, string connect) - { - PluginLoader loader = new PluginLoader(new AssetDataInitialiser(connect)); - - // Loader will try to load all providers (MySQL, MSSQL, etc) - // unless it is constrainted to the correct "Provider" entry in the addin.xml - loader.Add("/OpenSim/AssetData", new PluginProviderFilter (provider)); - loader.Load(); - - return loader.Plugin; - } - } -} diff --git a/OpenSim/Grid/NewAssetServer/Plugins/OpenSim/Resources/AssetServerOpenSimPlugins.addin.xml b/OpenSim/Grid/NewAssetServer/Plugins/OpenSim/Resources/AssetServerOpenSimPlugins.addin.xml deleted file mode 100644 index 0e473ad..0000000 --- a/OpenSim/Grid/NewAssetServer/Plugins/OpenSim/Resources/AssetServerOpenSimPlugins.addin.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/OpenSim/Grid/NewAssetServer/Utils.cs b/OpenSim/Grid/NewAssetServer/Utils.cs deleted file mode 100644 index 5499933..0000000 --- a/OpenSim/Grid/NewAssetServer/Utils.cs +++ /dev/null @@ -1,1034 +0,0 @@ -/* - * Copyright (c) 2008 Intel Corporation - * All rights reserved. - * 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``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 INTEL OR ITS - * 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.Specialized; -using System.Globalization; -using System.Net; -using System.Xml; -using System.Xml.Serialization; -using OpenMetaverse; -using OpenMetaverse.StructuredData; -using HttpServer; - -namespace AssetServer -{ - public static class Utils - { - public static UUID GetAuthToken(IHttpRequest request) - { - UUID authToken = UUID.Zero; - - string[] authHeader = request.Headers.GetValues("Authorization"); - if (authHeader != null && authHeader.Length == 1) - { - // Example header: - // Authorization: OpenGrid 65fda0b5-4446-42f5-b828-aaf644293646 - string[] authHeaderParts = authHeader[0].Split(' '); - if (authHeaderParts.Length == 2 && authHeaderParts[0] == "OpenGrid") - UUID.TryParse(authHeaderParts[1], out authToken); - } - - if (authToken == UUID.Zero && request.Cookies != null) - { - // Check for an authToken cookie to make logins browser-compatible - RequestCookie authCookie = request.Cookies["authToken"]; - if (authCookie != null) - UUID.TryParse(authCookie.Value, out authToken); - } - - return authToken; - } - - public static Uri GetOpenSimUri(UUID avatarID) - { - return new Uri("http://opensim/" + avatarID.ToString()); - } - - public static bool TryGetOpenSimUUID(Uri avatarUri, out UUID avatarID) - { - string[] parts = avatarUri.Segments; - return UUID.TryParse(parts[parts.Length - 1], out avatarID); - } - - #region SL / file extension / content-type conversions - - public static string SLAssetTypeToContentType(int assetType) - { - switch (assetType) - { - case 0: - return "image/jp2"; - case 1: - return "application/ogg"; - case 2: - return "application/x-metaverse-callingcard"; - case 3: - return "application/x-metaverse-landmark"; - case 5: - return "application/x-metaverse-clothing"; - case 6: - return "application/x-metaverse-primitive"; - case 7: - return "application/x-metaverse-notecard"; - case 8: - return "application/x-metaverse-folder"; - case 10: - return "application/x-metaverse-lsl"; - case 11: - return "application/x-metaverse-lso"; - case 12: - return "image/tga"; - case 13: - return "application/x-metaverse-bodypart"; - case 17: - return "audio/x-wav"; - case 19: - return "image/jpeg"; - case 20: - return "application/x-metaverse-animation"; - case 21: - return "application/x-metaverse-gesture"; - case 22: - return "application/x-metaverse-simstate"; - default: - return "application/octet-stream"; - } - } - - public static int ContentTypeToSLAssetType(string contentType) - { - switch (contentType) - { - case "image/jp2": - return 0; - case "application/ogg": - return 1; - case "application/x-metaverse-callingcard": - return 2; - case "application/x-metaverse-landmark": - return 3; - case "application/x-metaverse-clothing": - return 5; - case "application/x-metaverse-primitive": - return 6; - case "application/x-metaverse-notecard": - return 7; - case "application/x-metaverse-lsl": - return 10; - case "application/x-metaverse-lso": - return 11; - case "image/tga": - return 12; - case "application/x-metaverse-bodypart": - return 13; - case "audio/x-wav": - return 17; - case "image/jpeg": - return 19; - case "application/x-metaverse-animation": - return 20; - case "application/x-metaverse-gesture": - return 21; - case "application/x-metaverse-simstate": - return 22; - default: - return -1; - } - } - - public static string ContentTypeToExtension(string contentType) - { - switch (contentType) - { - case "image/jp2": - return "texture"; - case "application/ogg": - return "ogg"; - case "application/x-metaverse-callingcard": - return "callingcard"; - case "application/x-metaverse-landmark": - return "landmark"; - case "application/x-metaverse-clothing": - return "clothing"; - case "application/x-metaverse-primitive": - return "primitive"; - case "application/x-metaverse-notecard": - return "notecard"; - case "application/x-metaverse-lsl": - return "lsl"; - case "application/x-metaverse-lso": - return "lso"; - case "image/tga": - return "tga"; - case "application/x-metaverse-bodypart": - return "bodypart"; - case "audio/x-wav": - return "wav"; - case "image/jpeg": - return "jpg"; - case "application/x-metaverse-animation": - return "animation"; - case "application/x-metaverse-gesture": - return "gesture"; - case "application/x-metaverse-simstate": - return "simstate"; - default: - return "bin"; - } - } - - public static string ExtensionToContentType(string extension) - { - switch (extension) - { - case "texture": - case "jp2": - case "j2c": - return "image/jp2"; - case "sound": - case "ogg": - return "application/ogg"; - case "callingcard": - return "application/x-metaverse-callingcard"; - case "landmark": - return "application/x-metaverse-landmark"; - case "clothing": - return "application/x-metaverse-clothing"; - case "primitive": - return "application/x-metaverse-primitive"; - case "notecard": - return "application/x-metaverse-notecard"; - case "lsl": - return "application/x-metaverse-lsl"; - case "lso": - return "application/x-metaverse-lso"; - case "tga": - return "image/tga"; - case "bodypart": - return "application/x-metaverse-bodypart"; - case "wav": - return "audio/x-wav"; - case "jpg": - case "jpeg": - return "image/jpeg"; - case "animation": - return "application/x-metaverse-animation"; - case "gesture": - return "application/x-metaverse-gesture"; - case "simstate": - return "application/x-metaverse-simstate"; - case "txt": - return "text/plain"; - case "xml": - return "application/xml"; - default: - return "application/octet-stream"; - } - } - - #endregion SL / file extension / content-type conversions - - #region XML Serialization - - public class GeneratedReader : XmlSerializationReader - { - public object ReadRoot_InventoryFolderBase() - { - Reader.MoveToContent(); - if (Reader.LocalName != "InventoryFolderBase" || Reader.NamespaceURI != "") - throw CreateUnknownNodeException(); - return ReadObject_InventoryFolder(true, true); - } - - public object ReadRoot_InventoryItemBase() - { - Reader.MoveToContent(); - if (Reader.LocalName != "InventoryItemBase" || Reader.NamespaceURI != "") - throw CreateUnknownNodeException(); - return ReadObject_InventoryItem(true, true); - } - - public object ReadRoot_InventoryCollection() - { - Reader.MoveToContent(); - if (Reader.LocalName != "InventoryCollection" || Reader.NamespaceURI != "") - throw CreateUnknownNodeException(); - return ReadObject_InventoryCollection(true, true); - } - - public InventoryFolder ReadObject_InventoryFolder(bool isNullable, bool checkType) - { - InventoryFolder ob = null; - if (isNullable && ReadNull()) return null; - - if (checkType) - { - System.Xml.XmlQualifiedName t = GetXsiType(); - if (t == null) - { } - else if (t.Name != "InventoryFolderBase" || t.Namespace != "") - throw CreateUnknownTypeException(t); - } - - ob = (InventoryFolder)Activator.CreateInstance(typeof(InventoryFolder), true); - - Reader.MoveToElement(); - - while (Reader.MoveToNextAttribute()) - { - if (IsXmlnsAttribute(Reader.Name)) - { - } - else - { - UnknownNode(ob); - } - } - - Reader.MoveToElement(); - Reader.MoveToElement(); - if (Reader.IsEmptyElement) - { - Reader.Skip(); - return ob; - } - - Reader.ReadStartElement(); - Reader.MoveToContent(); - - bool b0 = false, b1 = false, b2 = false, b3 = false, b4 = false, b5 = false; - - while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) - { - if (Reader.NodeType == System.Xml.XmlNodeType.Element) - { - if (Reader.LocalName == "Owner" && Reader.NamespaceURI == "" && !b1) - { - b1 = true; - ob.@Owner = ReadObject_UUID(false, true); - } - else if (Reader.LocalName == "Version" && Reader.NamespaceURI == "" && !b5) - { - b5 = true; - string s6 = Reader.ReadElementString(); - ob.@Version = UInt16.Parse(s6, CultureInfo.InvariantCulture); - } - else if (Reader.LocalName == "ID" && Reader.NamespaceURI == "" && !b3) - { - b3 = true; - ob.@ID = ReadObject_UUID(false, true); - } - else if (Reader.LocalName == "Type" && Reader.NamespaceURI == "" && !b4) - { - b4 = true; - string s7 = Reader.ReadElementString(); - ob.@Type = Int16.Parse(s7, CultureInfo.InvariantCulture); - } - else if (Reader.LocalName == "Name" && Reader.NamespaceURI == "" && !b0) - { - b0 = true; - string s8 = Reader.ReadElementString(); - ob.@Name = s8; - } - else if (Reader.LocalName == "ParentID" && Reader.NamespaceURI == "" && !b2) - { - b2 = true; - ob.@ParentID = ReadObject_UUID(false, true); - } - else - { - UnknownNode(ob); - } - } - else - UnknownNode(ob); - - Reader.MoveToContent(); - } - - ReadEndElement(); - - return ob; - } - - public InventoryItem ReadObject_InventoryItem(bool isNullable, bool checkType) - { - InventoryItem ob = null; - if (isNullable && ReadNull()) return null; - - if (checkType) - { - System.Xml.XmlQualifiedName t = GetXsiType(); - if (t == null) - { } - else if (t.Name != "InventoryItemBase" || t.Namespace != "") - throw CreateUnknownTypeException(t); - } - - ob = (InventoryItem)Activator.CreateInstance(typeof(InventoryItem), true); - - Reader.MoveToElement(); - - while (Reader.MoveToNextAttribute()) - { - if (IsXmlnsAttribute(Reader.Name)) - { - } - else - { - UnknownNode(ob); - } - } - - Reader.MoveToElement(); - Reader.MoveToElement(); - if (Reader.IsEmptyElement) - { - Reader.Skip(); - return ob; - } - - Reader.ReadStartElement(); - Reader.MoveToContent(); - - bool b9 = false, b10 = false, b11 = false, b12 = false, b13 = false, b14 = false, b15 = false, b16 = false, b17 = false, b18 = false, b19 = false, b20 = false, b21 = false, b22 = false, b23 = false, b24 = false, b25 = false, b26 = false, b27 = false, b28 = false; - - while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) - { - if (Reader.NodeType == System.Xml.XmlNodeType.Element) - { - if (Reader.LocalName == "GroupPermissions" && Reader.NamespaceURI == "" && !b20) - { - b20 = true; - string s29 = Reader.ReadElementString(); - ob.@GroupPermissions = UInt32.Parse(s29, CultureInfo.InvariantCulture); - } - else if (Reader.LocalName == "AssetType" && Reader.NamespaceURI == "" && !b21) - { - b21 = true; - string s30 = Reader.ReadElementString(); - ob.@AssetType = Int32.Parse(s30, CultureInfo.InvariantCulture); - } - else if (Reader.LocalName == "SalePrice" && Reader.NamespaceURI == "" && !b25) - { - b25 = true; - string s31 = Reader.ReadElementString(); - ob.@SalePrice = Int32.Parse(s31, CultureInfo.InvariantCulture); - } - else if (Reader.LocalName == "AssetID" && Reader.NamespaceURI == "" && !b22) - { - b22 = true; - ob.@AssetID = ReadObject_UUID(false, true); - } - else if (Reader.LocalName == "Folder" && Reader.NamespaceURI == "" && !b11) - { - b11 = true; - ob.@Folder = ReadObject_UUID(false, true); - } - else if (Reader.LocalName == "Name" && Reader.NamespaceURI == "" && !b14) - { - b14 = true; - string s32 = Reader.ReadElementString(); - ob.@Name = s32; - } - else if (Reader.LocalName == "NextPermissions" && Reader.NamespaceURI == "" && !b16) - { - b16 = true; - string s33 = Reader.ReadElementString(); - ob.@NextPermissions = UInt32.Parse(s33, CultureInfo.InvariantCulture); - } - else if (Reader.LocalName == "BasePermissions" && Reader.NamespaceURI == "" && !b18) - { - b18 = true; - string s34 = Reader.ReadElementString(); - ob.@BasePermissions = UInt32.Parse(s34, CultureInfo.InvariantCulture); - } - else if (Reader.LocalName == "ID" && Reader.NamespaceURI == "" && !b9) - { - b9 = true; - ob.@ID = ReadObject_UUID(false, true); - } - else if (Reader.LocalName == "Flags" && Reader.NamespaceURI == "" && !b27) - { - b27 = true; - string s35 = Reader.ReadElementString(); - ob.@Flags = UInt32.Parse(s35, CultureInfo.InvariantCulture); - } - else if (Reader.LocalName == "GroupOwned" && Reader.NamespaceURI == "" && !b24) - { - b24 = true; - string s36 = Reader.ReadElementString(); - ob.@GroupOwned = XmlConvert.ToBoolean(s36); - } - else if (Reader.LocalName == "InvType" && Reader.NamespaceURI == "" && !b10) - { - b10 = true; - string s37 = Reader.ReadElementString(); - ob.@InvType = Int32.Parse(s37, CultureInfo.InvariantCulture); - } - else if (Reader.LocalName == "GroupID" && Reader.NamespaceURI == "" && !b23) - { - b23 = true; - ob.@GroupID = ReadObject_UUID(false, true); - } - else if (Reader.LocalName == "Description" && Reader.NamespaceURI == "" && !b15) - { - b15 = true; - string s38 = Reader.ReadElementString(); - ob.@Description = s38; - } - else if (Reader.LocalName == "CreationDate" && Reader.NamespaceURI == "" && !b28) - { - b28 = true; - string s39 = Reader.ReadElementString(); - ob.@CreationDate = Int32.Parse(s39, CultureInfo.InvariantCulture); - } - else if (Reader.LocalName == "EveryOnePermissions" && Reader.NamespaceURI == "" && !b19) - { - b19 = true; - string s40 = Reader.ReadElementString(); - ob.@EveryOnePermissions = UInt32.Parse(s40, CultureInfo.InvariantCulture); - } - else if (Reader.LocalName == "Creator" && Reader.NamespaceURI == "" && !b13) - { - b13 = true; - ob.@Creator = ReadObject_UUID(false, true); - } - else if (Reader.LocalName == "Owner" && Reader.NamespaceURI == "" && !b12) - { - b12 = true; - ob.@Owner = ReadObject_UUID(false, true); - } - else if (Reader.LocalName == "SaleType" && Reader.NamespaceURI == "" && !b26) - { - b26 = true; - string s41 = Reader.ReadElementString(); - ob.@SaleType = byte.Parse(s41, CultureInfo.InvariantCulture); - } - else if (Reader.LocalName == "CurrentPermissions" && Reader.NamespaceURI == "" && !b17) - { - b17 = true; - string s42 = Reader.ReadElementString(); - ob.@CurrentPermissions = UInt32.Parse(s42, CultureInfo.InvariantCulture); - } - else - { - UnknownNode(ob); - } - } - else - UnknownNode(ob); - - Reader.MoveToContent(); - } - - ReadEndElement(); - - return ob; - } - - public InventoryCollection ReadObject_InventoryCollection(bool isNullable, bool checkType) - { - InventoryCollection ob = null; - if (isNullable && ReadNull()) return null; - - if (checkType) - { - System.Xml.XmlQualifiedName t = GetXsiType(); - if (t == null) - { } - else if (t.Name != "InventoryCollection" || t.Namespace != "") - throw CreateUnknownTypeException(t); - } - - ob = (InventoryCollection)Activator.CreateInstance(typeof(InventoryCollection), true); - - Reader.MoveToElement(); - - while (Reader.MoveToNextAttribute()) - { - if (IsXmlnsAttribute(Reader.Name)) - { - } - else - { - UnknownNode(ob); - } - } - - Reader.MoveToElement(); - Reader.MoveToElement(); - if (Reader.IsEmptyElement) - { - Reader.Skip(); - if (ob.@Folders == null) - { - ob.@Folders = new System.Collections.Generic.Dictionary(); - } - if (ob.@Items == null) - { - ob.@Items = new System.Collections.Generic.Dictionary(); - } - return ob; - } - - Reader.ReadStartElement(); - Reader.MoveToContent(); - - bool b43 = false, b44 = false, b45 = false; - - while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) - { - if (Reader.NodeType == System.Xml.XmlNodeType.Element) - { - if (Reader.LocalName == "UserID" && Reader.NamespaceURI == "" && !b45) - { - b45 = true; - ob.@UserID = ReadObject_UUID(false, true); - } - else if (Reader.LocalName == "Items" && Reader.NamespaceURI == "" && !b44) - { - System.Collections.Generic.Dictionary o46 = ob.@Items; - if (((object)o46) == null) - { - o46 = new System.Collections.Generic.Dictionary(); - ob.@Items = o46; - } - if (Reader.IsEmptyElement) - { - Reader.Skip(); - } - else - { - int n47 = 0; - Reader.ReadStartElement(); - Reader.MoveToContent(); - - while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) - { - if (Reader.NodeType == System.Xml.XmlNodeType.Element) - { - if (Reader.LocalName == "InventoryItemBase" && Reader.NamespaceURI == "") - { - if (((object)o46) == null) - throw CreateReadOnlyCollectionException("System.Collections.Generic.List"); - InventoryItem item = ReadObject_InventoryItem(true, true); - o46.Add(item.ID, item); - n47++; - } - else UnknownNode(null); - } - else UnknownNode(null); - - Reader.MoveToContent(); - } - ReadEndElement(); - } - b44 = true; - } - else if (Reader.LocalName == "Folders" && Reader.NamespaceURI == "" && !b43) - { - System.Collections.Generic.Dictionary o48 = ob.@Folders; - if (((object)o48) == null) - { - o48 = new System.Collections.Generic.Dictionary(); - ob.@Folders = o48; - } - if (Reader.IsEmptyElement) - { - Reader.Skip(); - } - else - { - int n49 = 0; - Reader.ReadStartElement(); - Reader.MoveToContent(); - - while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) - { - if (Reader.NodeType == System.Xml.XmlNodeType.Element) - { - if (Reader.LocalName == "InventoryFolderBase" && Reader.NamespaceURI == "") - { - if (((object)o48) == null) - throw CreateReadOnlyCollectionException("System.Collections.Generic.List"); - InventoryFolder folder = ReadObject_InventoryFolder(true, true); - o48.Add(folder.ID, folder); - n49++; - } - else UnknownNode(null); - } - else UnknownNode(null); - - Reader.MoveToContent(); - } - ReadEndElement(); - } - b43 = true; - } - else - { - UnknownNode(ob); - } - } - else - UnknownNode(ob); - - Reader.MoveToContent(); - } - if (ob.@Folders == null) - { - ob.@Folders = new System.Collections.Generic.Dictionary(); - } - if (ob.@Items == null) - { - ob.@Items = new System.Collections.Generic.Dictionary(); - } - - ReadEndElement(); - - return ob; - } - - public OpenMetaverse.UUID ReadObject_UUID(bool isNullable, bool checkType) - { - OpenMetaverse.UUID ob = (OpenMetaverse.UUID)Activator.CreateInstance(typeof(OpenMetaverse.UUID), true); - System.Xml.XmlQualifiedName t = GetXsiType(); - if (t == null) - { } - else if (t.Name != "UUID" || t.Namespace != "") - throw CreateUnknownTypeException(t); - - Reader.MoveToElement(); - - while (Reader.MoveToNextAttribute()) - { - if (IsXmlnsAttribute(Reader.Name)) - { - } - else - { - UnknownNode(ob); - } - } - - Reader.MoveToElement(); - Reader.MoveToElement(); - if (Reader.IsEmptyElement) - { - Reader.Skip(); - return ob; - } - - Reader.ReadStartElement(); - Reader.MoveToContent(); - - bool b52 = false; - - while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) - { - if (Reader.NodeType == System.Xml.XmlNodeType.Element) - { - if (Reader.LocalName == "Guid" && Reader.NamespaceURI == "" && !b52) - { - b52 = true; - string s53 = Reader.ReadElementString(); - ob.@Guid = XmlConvert.ToGuid(s53); - } - else - { - UnknownNode(ob); - } - } - else - UnknownNode(ob); - - Reader.MoveToContent(); - } - - ReadEndElement(); - - return ob; - } - - protected override void InitCallbacks() - { - } - - protected override void InitIDs() - { - } - } - - public class GeneratedWriter : XmlSerializationWriter - { - const string xmlNamespace = "http://www.w3.org/2000/xmlns/"; - static readonly System.Reflection.MethodInfo toBinHexStringMethod = typeof(XmlConvert).GetMethod("ToBinHexString", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic, null, new Type[] { typeof(byte[]) }, null); - static string ToBinHexString(byte[] input) - { - return input == null ? null : (string)toBinHexStringMethod.Invoke(null, new object[] { input }); - } - public void WriteRoot_InventoryFolder(object o) - { - WriteStartDocument(); - InventoryFolder ob = (InventoryFolder)o; - TopLevelElement(); - WriteObject_InventoryFolder(ob, "InventoryFolderBase", "", true, false, true); - } - - public void WriteRoot_InventoryItem(object o) - { - WriteStartDocument(); - InventoryItem ob = (InventoryItem)o; - TopLevelElement(); - WriteObject_InventoryItem(ob, "InventoryItemBase", "", true, false, true); - } - - public void WriteRoot_InventoryCollection(object o) - { - WriteStartDocument(); - InventoryCollection ob = (InventoryCollection)o; - TopLevelElement(); - WriteObject_InventoryCollection(ob, "InventoryCollection", "", true, false, true); - } - - void WriteObject_InventoryFolder(InventoryFolder ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) - { - if (((object)ob) == null) - { - if (isNullable) - WriteNullTagLiteral(element, namesp); - return; - } - - System.Type type = ob.GetType(); - if (type == typeof(InventoryFolder)) - { } - else - { - throw CreateUnknownTypeException(ob); - } - - if (writeWrappingElem) - { - WriteStartElement(element, namesp, ob); - } - - if (needType) WriteXsiType("InventoryFolderBase", ""); - - WriteElementString("Name", "", ob.@Name); - WriteObject_UUID(ob.@Owner, "Owner", "", false, false, true); - WriteObject_UUID(ob.@ParentID, "ParentID", "", false, false, true); - WriteObject_UUID(ob.@ID, "ID", "", false, false, true); - WriteElementString("Type", "", ob.@Type.ToString(CultureInfo.InvariantCulture)); - WriteElementString("Version", "", ob.@Version.ToString(CultureInfo.InvariantCulture)); - if (writeWrappingElem) WriteEndElement(ob); - } - - void WriteObject_InventoryItem(InventoryItem ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) - { - if (((object)ob) == null) - { - if (isNullable) - WriteNullTagLiteral(element, namesp); - return; - } - - System.Type type = ob.GetType(); - if (type == typeof(InventoryItem)) - { } - else - { - throw CreateUnknownTypeException(ob); - } - - if (writeWrappingElem) - { - WriteStartElement(element, namesp, ob); - } - - if (needType) WriteXsiType("InventoryItemBase", ""); - - WriteObject_UUID(ob.@ID, "ID", "", false, false, true); - WriteElementString("InvType", "", ob.@InvType.ToString(CultureInfo.InvariantCulture)); - WriteObject_UUID(ob.@Folder, "Folder", "", false, false, true); - WriteObject_UUID(ob.@Owner, "Owner", "", false, false, true); - WriteObject_UUID(ob.@Creator, "Creator", "", false, false, true); - WriteElementString("Name", "", ob.@Name); - WriteElementString("Description", "", ob.@Description); - WriteElementString("NextPermissions", "", ob.@NextPermissions.ToString(CultureInfo.InvariantCulture)); - WriteElementString("CurrentPermissions", "", ob.@CurrentPermissions.ToString(CultureInfo.InvariantCulture)); - WriteElementString("BasePermissions", "", ob.@BasePermissions.ToString(CultureInfo.InvariantCulture)); - WriteElementString("EveryOnePermissions", "", ob.@EveryOnePermissions.ToString(CultureInfo.InvariantCulture)); - WriteElementString("GroupPermissions", "", ob.@GroupPermissions.ToString(CultureInfo.InvariantCulture)); - WriteElementString("AssetType", "", ob.@AssetType.ToString(CultureInfo.InvariantCulture)); - WriteObject_UUID(ob.@AssetID, "AssetID", "", false, false, true); - WriteObject_UUID(ob.@GroupID, "GroupID", "", false, false, true); - WriteElementString("GroupOwned", "", (ob.@GroupOwned ? "true" : "false")); - WriteElementString("SalePrice", "", ob.@SalePrice.ToString(CultureInfo.InvariantCulture)); - WriteElementString("SaleType", "", ob.@SaleType.ToString(CultureInfo.InvariantCulture)); - WriteElementString("Flags", "", ob.@Flags.ToString(CultureInfo.InvariantCulture)); - WriteElementString("CreationDate", "", ob.@CreationDate.ToString(CultureInfo.InvariantCulture)); - if (writeWrappingElem) WriteEndElement(ob); - } - - void WriteObject_InventoryCollection(InventoryCollection ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) - { - if (((object)ob) == null) - { - if (isNullable) - WriteNullTagLiteral(element, namesp); - return; - } - - System.Type type = ob.GetType(); - if (type == typeof(InventoryCollection)) - { } - else - { - throw CreateUnknownTypeException(ob); - } - - if (writeWrappingElem) - { - WriteStartElement(element, namesp, ob); - } - - if (needType) WriteXsiType("InventoryCollection", ""); - - if (ob.@Folders != null) - { - WriteStartElement("Folders", "", ob.@Folders); - foreach (InventoryFolder folder in ob.Folders.Values) - { - WriteObject_InventoryFolder(folder, "InventoryFolderBase", "", true, false, true); - } - WriteEndElement(ob.@Folders); - } - if (ob.@Items != null) - { - WriteStartElement("Items", "", ob.@Items); - foreach (InventoryItem item in ob.Items.Values) - { - WriteObject_InventoryItem(item, "InventoryItemBase", "", true, false, true); - } - WriteEndElement(ob.@Items); - } - WriteObject_UUID(ob.@UserID, "UserID", "", false, false, true); - if (writeWrappingElem) WriteEndElement(ob); - } - - void WriteObject_UUID(OpenMetaverse.UUID ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) - { - System.Type type = ob.GetType(); - if (type == typeof(OpenMetaverse.UUID)) - { } - else - { - throw CreateUnknownTypeException(ob); - } - - if (writeWrappingElem) - { - WriteStartElement(element, namesp, ob); - } - - if (needType) WriteXsiType("UUID", ""); - - WriteElementString("Guid", "", XmlConvert.ToString(ob.@Guid)); - if (writeWrappingElem) WriteEndElement(ob); - } - - protected override void InitCallbacks() - { - } - - } - - public class BaseXmlSerializer : System.Xml.Serialization.XmlSerializer - { - protected override System.Xml.Serialization.XmlSerializationReader CreateReader() - { - return new GeneratedReader(); - } - - protected override System.Xml.Serialization.XmlSerializationWriter CreateWriter() - { - return new GeneratedWriter(); - } - - public override bool CanDeserialize(System.Xml.XmlReader xmlReader) - { - return true; - } - } - - public sealed class InventoryFolderSerializer : BaseXmlSerializer - { - protected override void Serialize(object obj, System.Xml.Serialization.XmlSerializationWriter writer) - { - ((GeneratedWriter)writer).WriteRoot_InventoryFolder(obj); - } - - protected override object Deserialize(System.Xml.Serialization.XmlSerializationReader reader) - { - return ((GeneratedReader)reader).ReadRoot_InventoryFolderBase(); - } - } - - public sealed class InventoryItemSerializer : BaseXmlSerializer - { - protected override void Serialize(object obj, System.Xml.Serialization.XmlSerializationWriter writer) - { - ((GeneratedWriter)writer).WriteRoot_InventoryItem(obj); - } - - protected override object Deserialize(System.Xml.Serialization.XmlSerializationReader reader) - { - return ((GeneratedReader)reader).ReadRoot_InventoryItemBase(); - } - } - - public sealed class InventoryCollectionSerializer : BaseXmlSerializer - { - protected override void Serialize(object obj, System.Xml.Serialization.XmlSerializationWriter writer) - { - ((GeneratedWriter)writer).WriteRoot_InventoryCollection(obj); - } - - protected override object Deserialize(System.Xml.Serialization.XmlSerializationReader reader) - { - return ((GeneratedReader)reader).ReadRoot_InventoryCollection(); - } - } - - #endregion XML Serialization - } -} diff --git a/bin/AssetInventoryServer.ini.example b/bin/AssetInventoryServer.ini.example new file mode 100644 index 0000000..f346624 --- /dev/null +++ b/bin/AssetInventoryServer.ini.example @@ -0,0 +1,153 @@ +[Config] + +; The port number for the asset server to listen on. If a valid SSL certificate +; file is given for SSLCertFile, the HTTPS protocol will be used. Otherwise, the +; HTTP protocol is used. +ListenPort = 8003 + +; An SSL certificate file for the server. If a valid raw certificate or PKCS#12 +; file is given the server will run in HTTPS mode. +;SSLCertFile = server.p12 + +[Extensions] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Storage Providers +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Simple storage is a very basic storage system for the purposes of illustrating +; a storage backend example. The assets are stored in SimpleAssets/ and +; TempAssets/ (which is deleted when the server shuts down). Metadata is +; generated for all of the files at startup and when new assets are uploaded. +;SimpleStorage + +; OpenSimMySQL storage connects to a MySQL server that has an assets table created +; by OpenSim. Open the AssetServer_Config.xml file from OpenSim and use the +; database connection string for the database_connect option in the MySQL section +; below. This backend combined with the OpenSimFrontend will allow the asset +; server to be used as a drop-in replacement for OpenSim.Grid.AssetServer.exe, +; while also allowing other frontends to run. +OpenSimMySQLStorage + +; Uses Amazon.com's Simple Storage Service (http://aws.amazon.com/s3/) to store +; asset data and metadata. This backend does not handle any data requests, as the +; data is stored remotely and metadata replies will contain the amazon.com URL +; holding the actual asset data. Your Access Key ID and Secret Access Key must be +; set in the [Amazon] section below for this backend to function. If +; UseCloudFront is true and your Amazon account has CloudFront enabled, +; CloudFront URLs will be returned in metadata instead of normal S3 URLs. +;AmazonS3Storage + +; Uses memcached (http://www.danga.com/memcached/) as a caching layer on top of +; another storage backend. If you use this, make sure you enable another storage +; provider as the actual backend, and that the MemcacheStorage line appears in +; this config file after the other storage provider. +;MemcachedStorage + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Inventory Providers +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Simple inventory is a very basic inventory storage system for the purposes of +; illustrating an inventory backend example. The inventory is stored in +; SimpleInventory/ by creating a folder for each agent that contains all of the +; inventory items and folders serialized as XML files. +;SimpleInventory + +; OpenSimMySQL inventory connects to a MySQL server that has an inventory table +; created by OpenSim. If the OpenSimMySQLStorage backend is also being used, the +; inventory and asset tables must be stored in the same database. The +; database_connect string in the MySQL section below is used to connect to the +; database. This backend combined with the OpenSimInventoryFrontend will allow +; the server to be used as a drop-in replacement for +; OpenSim.Grid.InventoryServer.exe, while also allowing other frontends to run. +OpenSimMySQLInventory + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Authentication Providers +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; OpenID provides a direct method of authenticating with the asset server. Users +; can provide credentials and receive a session token directly from the asset +; server. The OpenIdAuth module provides a browser-based form login and an +; XML-based API, both accessible through the URL /authenticate. +;OpenIdAuth +NullAuthentication + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Authorization Providers +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Authorize all is a dummy authorization module that allows all requests for +; metadata, data, and asset creation. Use this extension if your primary +; storage provider or front-end interface does not support authentication. +AuthorizeAll + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Metrics Providers +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; NullMetrics contains empty logging functions. Use this metrics provider if +; you want to disable metrics collection and reporting. +NullMetrics + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Frontends +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; A simple frontend that provides three basic REST methods. /assetid/metadata +; will return the metadata for an asset (currently in LLSD format, that will +; change soon). /assetid/data will return the raw asset data with proper +; Content-Type and Content-Disposition headers to make downloading assets in a +; web browser easy. +ReferenceFrontend + +; A frontend that matches the existing OpenSim XML for transferring grid +; assets. This will allow the asset server to function as a drop-in replacement +; for OpenSim.Grid.AssetServer.exe, and can be combined with OpenSimMySQLStorage +; to provide an identical replacement or any other storage backend. +OpenSimFrontend + +; A frontend that matches the existing OpenSim XML for handling inventory +; transactions. This will allow the asset server to function as a drop-in +; replacement for OpenSim.Grid.InventoryServer.exe, and can be combined with +; OpenSimMySQLInventory to provide an identical replacement or any other +; inventory backend. +OpenSimInventoryFrontend + +; An HTML interface for browsing through the asset store +BrowseFrontend + +[MySQL] + +; Database connection string used by the OpenSim MySQL backend. If this line is +; commented out or missing, the server will look for an AssetServer_Config.xml +; in the current working directory. This file is generated by +; OpenSim.Grid.AssetServer.exe and can be used without modification. +database_connect = "Server=localhost; Database=opensim; User=changeme; Password=changeme;" + +[Amazon] + +; Get these values by logging in to your Amazon S3 account and going to +; https://aws-portal.amazon.com/gp/aws/developer/account/index.html?ie=UTF8&action=access-key +AccessKeyID = xxxxxxxxxxxxxxxxxxxx +SecretAccessKey = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +; The bucket, or namespace, in your Amazon S3 account for storing assets in. +; Bucket names on S3 are global identifiers, and must be unique. Think up +; something clever or random. +BucketName = changeme + +; Amazon CloudFront is a Content Distribution Network for S3 stores. If this is +; set to true, AmazonS3Storage will try to locate the first available CloudFront +; distribution tied to the active S3 bucket. If no usable distribution is found, +; a new one will be created. +UseCloudFront = true + +[Memcached] + +; A comma-separated list of the memcached servers that make up your caching +; pool. Each server is a hostname or IP address, optionally followed by a +; colon and port number if the server is not listening on the default 11211 +; port. +Servers = localhost diff --git a/bin/AssetServer.ini.example b/bin/AssetServer.ini.example deleted file mode 100644 index f346624..0000000 --- a/bin/AssetServer.ini.example +++ /dev/null @@ -1,153 +0,0 @@ -[Config] - -; The port number for the asset server to listen on. If a valid SSL certificate -; file is given for SSLCertFile, the HTTPS protocol will be used. Otherwise, the -; HTTP protocol is used. -ListenPort = 8003 - -; An SSL certificate file for the server. If a valid raw certificate or PKCS#12 -; file is given the server will run in HTTPS mode. -;SSLCertFile = server.p12 - -[Extensions] - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Storage Providers -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; Simple storage is a very basic storage system for the purposes of illustrating -; a storage backend example. The assets are stored in SimpleAssets/ and -; TempAssets/ (which is deleted when the server shuts down). Metadata is -; generated for all of the files at startup and when new assets are uploaded. -;SimpleStorage - -; OpenSimMySQL storage connects to a MySQL server that has an assets table created -; by OpenSim. Open the AssetServer_Config.xml file from OpenSim and use the -; database connection string for the database_connect option in the MySQL section -; below. This backend combined with the OpenSimFrontend will allow the asset -; server to be used as a drop-in replacement for OpenSim.Grid.AssetServer.exe, -; while also allowing other frontends to run. -OpenSimMySQLStorage - -; Uses Amazon.com's Simple Storage Service (http://aws.amazon.com/s3/) to store -; asset data and metadata. This backend does not handle any data requests, as the -; data is stored remotely and metadata replies will contain the amazon.com URL -; holding the actual asset data. Your Access Key ID and Secret Access Key must be -; set in the [Amazon] section below for this backend to function. If -; UseCloudFront is true and your Amazon account has CloudFront enabled, -; CloudFront URLs will be returned in metadata instead of normal S3 URLs. -;AmazonS3Storage - -; Uses memcached (http://www.danga.com/memcached/) as a caching layer on top of -; another storage backend. If you use this, make sure you enable another storage -; provider as the actual backend, and that the MemcacheStorage line appears in -; this config file after the other storage provider. -;MemcachedStorage - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Inventory Providers -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; Simple inventory is a very basic inventory storage system for the purposes of -; illustrating an inventory backend example. The inventory is stored in -; SimpleInventory/ by creating a folder for each agent that contains all of the -; inventory items and folders serialized as XML files. -;SimpleInventory - -; OpenSimMySQL inventory connects to a MySQL server that has an inventory table -; created by OpenSim. If the OpenSimMySQLStorage backend is also being used, the -; inventory and asset tables must be stored in the same database. The -; database_connect string in the MySQL section below is used to connect to the -; database. This backend combined with the OpenSimInventoryFrontend will allow -; the server to be used as a drop-in replacement for -; OpenSim.Grid.InventoryServer.exe, while also allowing other frontends to run. -OpenSimMySQLInventory - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Authentication Providers -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; OpenID provides a direct method of authenticating with the asset server. Users -; can provide credentials and receive a session token directly from the asset -; server. The OpenIdAuth module provides a browser-based form login and an -; XML-based API, both accessible through the URL /authenticate. -;OpenIdAuth -NullAuthentication - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Authorization Providers -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; Authorize all is a dummy authorization module that allows all requests for -; metadata, data, and asset creation. Use this extension if your primary -; storage provider or front-end interface does not support authentication. -AuthorizeAll - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Metrics Providers -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; NullMetrics contains empty logging functions. Use this metrics provider if -; you want to disable metrics collection and reporting. -NullMetrics - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Frontends -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; A simple frontend that provides three basic REST methods. /assetid/metadata -; will return the metadata for an asset (currently in LLSD format, that will -; change soon). /assetid/data will return the raw asset data with proper -; Content-Type and Content-Disposition headers to make downloading assets in a -; web browser easy. -ReferenceFrontend - -; A frontend that matches the existing OpenSim XML for transferring grid -; assets. This will allow the asset server to function as a drop-in replacement -; for OpenSim.Grid.AssetServer.exe, and can be combined with OpenSimMySQLStorage -; to provide an identical replacement or any other storage backend. -OpenSimFrontend - -; A frontend that matches the existing OpenSim XML for handling inventory -; transactions. This will allow the asset server to function as a drop-in -; replacement for OpenSim.Grid.InventoryServer.exe, and can be combined with -; OpenSimMySQLInventory to provide an identical replacement or any other -; inventory backend. -OpenSimInventoryFrontend - -; An HTML interface for browsing through the asset store -BrowseFrontend - -[MySQL] - -; Database connection string used by the OpenSim MySQL backend. If this line is -; commented out or missing, the server will look for an AssetServer_Config.xml -; in the current working directory. This file is generated by -; OpenSim.Grid.AssetServer.exe and can be used without modification. -database_connect = "Server=localhost; Database=opensim; User=changeme; Password=changeme;" - -[Amazon] - -; Get these values by logging in to your Amazon S3 account and going to -; https://aws-portal.amazon.com/gp/aws/developer/account/index.html?ie=UTF8&action=access-key -AccessKeyID = xxxxxxxxxxxxxxxxxxxx -SecretAccessKey = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - -; The bucket, or namespace, in your Amazon S3 account for storing assets in. -; Bucket names on S3 are global identifiers, and must be unique. Think up -; something clever or random. -BucketName = changeme - -; Amazon CloudFront is a Content Distribution Network for S3 stores. If this is -; set to true, AmazonS3Storage will try to locate the first available CloudFront -; distribution tied to the active S3 bucket. If no usable distribution is found, -; a new one will be created. -UseCloudFront = true - -[Memcached] - -; A comma-separated list of the memcached servers that make up your caching -; pool. Each server is a hostname or IP address, optionally followed by a -; colon and port number if the server is not listening on the default 11211 -; port. -Servers = localhost diff --git a/bin/OpenSim.Grid.AssetInventoryServer.addin.xml b/bin/OpenSim.Grid.AssetInventoryServer.addin.xml new file mode 100644 index 0000000..b85d3da --- /dev/null +++ b/bin/OpenSim.Grid.AssetInventoryServer.addin.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/bin/OpenSim.Grid.NewAssetServer.addin.xml b/bin/OpenSim.Grid.NewAssetServer.addin.xml deleted file mode 100644 index 8d8a863..0000000 --- a/bin/OpenSim.Grid.NewAssetServer.addin.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/prebuild.xml b/prebuild.xml index c157cdf..f215c9f 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -746,7 +746,7 @@ - + ../../../bin/ @@ -783,7 +783,7 @@ - + ../../../../../bin/ @@ -799,7 +799,7 @@ - + @@ -814,7 +814,7 @@ -