From 3f3dfd7ac1c6c859a1d0db7315eeb0fb144b0ace Mon Sep 17 00:00:00 2001 From: Mike Mazur Date: Mon, 16 Feb 2009 02:26:18 +0000 Subject: - added Simple AssetInventoryServer plugin (asset storage only) - removed OpenSim storage and frontend classes in Extensions dir - put OpenSim plugins in OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim namespace --- .../AssetInventoryServer/AssetInventoryServer.cs | 17 +- .../Extensions/OpenSimFrontend.cs | 215 -------------- .../Extensions/OpenSimMySQLStorage.cs | 311 --------------------- .../Extensions/SimpleStorage.cs | 260 ----------------- OpenSim/Grid/AssetInventoryServer/Interfaces.cs | 10 - .../Plugins/OpenSim/OpenSimAssetFrontendPlugin.cs | 2 +- .../Plugins/OpenSim/OpenSimAssetStoragePlugin.cs | 2 +- .../AssetInventoryServerOpenSimPlugins.addin.xml | 4 +- .../AssetInventoryServerSimplePlugins.addin.xml | 13 + .../Plugins/Simple/SimpleAssetStoragePlugin.cs | 286 +++++++++++++++++++ .../Plugins/Simple/SimpleUtils.cs | 73 +++++ 11 files changed, 386 insertions(+), 807 deletions(-) delete mode 100644 OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimFrontend.cs delete mode 100644 OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLStorage.cs delete mode 100644 OpenSim/Grid/AssetInventoryServer/Extensions/SimpleStorage.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/Plugins/Simple/Resources/AssetInventoryServerSimplePlugins.addin.xml create mode 100644 OpenSim/Grid/AssetInventoryServer/Plugins/Simple/SimpleAssetStoragePlugin.cs create mode 100644 OpenSim/Grid/AssetInventoryServer/Plugins/Simple/SimpleUtils.cs (limited to 'OpenSim/Grid') diff --git a/OpenSim/Grid/AssetInventoryServer/AssetInventoryServer.cs b/OpenSim/Grid/AssetInventoryServer/AssetInventoryServer.cs index d37c63d..e51f559 100644 --- a/OpenSim/Grid/AssetInventoryServer/AssetInventoryServer.cs +++ b/OpenSim/Grid/AssetInventoryServer/AssetInventoryServer.cs @@ -106,8 +106,8 @@ namespace OpenSim.Grid.AssetInventoryServer return false; } - StorageProvider = LoadAssetInventoryServerPlugin("/OpenSim/AssetInventoryServer/StorageProvider") as IAssetStorageProvider; - MetricsProvider = LoadAssetInventoryServerPlugin("/OpenSim/AssetInventoryServer/MetricsProvider") as IMetricsProvider; + StorageProvider = LoadAssetInventoryServerPlugin("/OpenSim/AssetInventoryServer/StorageProvider", "OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim.dll") as IAssetStorageProvider; + MetricsProvider = LoadAssetInventoryServerPlugin("/OpenSim/AssetInventoryServer/MetricsProvider", "") as IMetricsProvider; try { @@ -120,7 +120,7 @@ namespace OpenSim.Grid.AssetInventoryServer return false; } - frontend = LoadAssetInventoryServerPlugin("/OpenSim/AssetInventoryServer/Frontend"); + frontend = LoadAssetInventoryServerPlugin("/OpenSim/AssetInventoryServer/Frontend", ""); return true; } @@ -179,13 +179,16 @@ namespace OpenSim.Grid.AssetInventoryServer #endregion - private IAssetInventoryServerPlugin LoadAssetInventoryServerPlugin(string addinPath) + private IAssetInventoryServerPlugin LoadAssetInventoryServerPlugin(string addinPath, string provider) { 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(addinPath); + if (provider == String.Empty) + loader.Add(addinPath); + else + loader.Add(addinPath, new PluginProviderFilter(provider)); + //loader.Add(addinPath, new PluginCountConstraint(1)); + loader.Load(); return loader.Plugin; diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimFrontend.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimFrontend.cs deleted file mode 100644 index e34a235..0000000 --- a/OpenSim/Grid/AssetInventoryServer/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 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/OpenSimMySQLStorage.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLStorage.cs deleted file mode 100644 index 48fa25b..0000000 --- a/OpenSim/Grid/AssetInventoryServer/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 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/SimpleStorage.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleStorage.cs deleted file mode 100644 index 9456ef5..0000000 --- a/OpenSim/Grid/AssetInventoryServer/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 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/Interfaces.cs b/OpenSim/Grid/AssetInventoryServer/Interfaces.cs index 67ffa2f..870cf89 100644 --- a/OpenSim/Grid/AssetInventoryServer/Interfaces.cs +++ b/OpenSim/Grid/AssetInventoryServer/Interfaces.cs @@ -73,16 +73,6 @@ namespace OpenSim.Grid.AssetInventoryServer 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); diff --git a/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimAssetFrontendPlugin.cs b/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimAssetFrontendPlugin.cs index 0326771..f0ad3cf 100644 --- a/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimAssetFrontendPlugin.cs +++ b/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimAssetFrontendPlugin.cs @@ -39,7 +39,7 @@ using OpenMetaverse; using HttpServer; using OpenSim.Framework; -namespace OpenSim.Grid.AssetInventoryServer.Plugins +namespace OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim { public class OpenSimAssetFrontendPlugin : IAssetInventoryServerPlugin { diff --git a/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimAssetStoragePlugin.cs b/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimAssetStoragePlugin.cs index 37dd241..6c02cde 100644 --- a/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimAssetStoragePlugin.cs +++ b/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimAssetStoragePlugin.cs @@ -40,7 +40,7 @@ using OpenSim.Framework; using OpenSim.Grid.AssetInventoryServer.Extensions; using OpenSim.Data; -namespace OpenSim.Grid.AssetInventoryServer.Plugins +namespace OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim { public class OpenSimAssetStoragePlugin : IAssetStorageProvider { diff --git a/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/Resources/AssetInventoryServerOpenSimPlugins.addin.xml b/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/Resources/AssetInventoryServerOpenSimPlugins.addin.xml index 0fe2f48..f458909 100644 --- a/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/Resources/AssetInventoryServerOpenSimPlugins.addin.xml +++ b/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/Resources/AssetInventoryServerOpenSimPlugins.addin.xml @@ -13,9 +13,9 @@ - + - + diff --git a/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/Resources/AssetInventoryServerSimplePlugins.addin.xml b/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/Resources/AssetInventoryServerSimplePlugins.addin.xml new file mode 100644 index 0000000..53534c4 --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/Resources/AssetInventoryServerSimplePlugins.addin.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/SimpleAssetStoragePlugin.cs b/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/SimpleAssetStoragePlugin.cs new file mode 100644 index 0000000..fd198d9 --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/SimpleAssetStoragePlugin.cs @@ -0,0 +1,286 @@ +/* + * 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; +using OpenSim.Framework; + +namespace OpenSim.Grid.AssetInventoryServer.Plugins.Simple +{ + public class SimpleAssetStoragePlugin : IAssetStorageProvider + { + const string EXTENSION_NAME = "SimpleAssetStorage"; // Used in metrics reporting + const string DEFAULT_DATA_DIR = "SimpleAssets"; + const string TEMP_DATA_DIR = "SimpleAssetsTemp"; + + AssetInventoryServer server; + Dictionary metadataStorage; + Dictionary filenames; + + public SimpleAssetStoragePlugin() + { + } + + #region Required Interfaces + + 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 + + #region IPlugin implementation + + public void Initialise(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); + } + + /// + /// Initialises asset interface + /// + public void Initialise() + { + Logger.Log.InfoFormat("[ASSET]: {0} cannot be default-initialized!", Name); + throw new PluginNotInitialisedException(Name); + } + + public void Dispose() + { + WipeTemporary(); + } + + public string Version + { + // TODO: this should be something meaningful and not hardcoded? + get { return "0.1"; } + } + + public string Name + { + get { return "AssetInventoryServer Simple asset storage provider"; } + } + + #endregion IPlugin implementation + + 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/Plugins/Simple/SimpleUtils.cs b/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/SimpleUtils.cs new file mode 100644 index 0000000..6a32718 --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/SimpleUtils.cs @@ -0,0 +1,73 @@ +/* + * 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.IO; +using OpenMetaverse; + +namespace OpenSim.Grid.AssetInventoryServer.Plugins.Simple +{ + public static class SimpleUtils + { + public static string ParseNameFromFilename(string filename) + { + filename = Path.GetFileName(filename); + + int dot = filename.LastIndexOf('.'); + int firstDash = filename.IndexOf('-'); + + if (dot - 37 > 0 && firstDash > 0) + return filename.Substring(0, firstDash); + else + return String.Empty; + } + + public static UUID ParseUUIDFromFilename(string filename) + { + int dot = filename.LastIndexOf('.'); + + if (dot > 35) + { + // Grab the last 36 characters of the filename + string uuidString = filename.Substring(dot - 36, 36); + UUID uuid; + UUID.TryParse(uuidString, out uuid); + return uuid; + } + else + { + UUID uuid; + if (UUID.TryParse(Path.GetFileName(filename), out uuid)) + return uuid; + else + return UUID.Zero; + } + } + } +} -- cgit v1.1