From 924d6e892a7b5a61e900b910a5a35de488963529 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 15 Mar 2013 21:53:39 +0000 Subject: [PATCH] Make it possible to chain another asset service underneath the de-duplicating XAssetService. This makes it possible to use the dedupliicating service without needing to migrate all the existing asset data beforehand. Currently controlled by a ChainedServiceModule setting in [AssetService] (e.g. ChainedServiceModule = "OpenSim.Services.AssetService.dll:AssetService") Not yet ready for use. --- .../Services/AssetService/XAssetService.cs | 51 ++++++++++++++----- .../AssetService/XAssetServiceBase.cs | 47 +++++++++++++---- prebuild.xml | 1 + 3 files changed, 76 insertions(+), 23 deletions(-) diff --git a/OpenSim/Services/AssetService/XAssetService.cs b/OpenSim/Services/AssetService/XAssetService.cs index a1d10ed5c5..7dd48c9a94 100644 --- a/OpenSim/Services/AssetService/XAssetService.cs +++ b/OpenSim/Services/AssetService/XAssetService.cs @@ -39,8 +39,7 @@ using OpenMetaverse; namespace OpenSim.Services.AssetService { /// - /// This will be developed into a de-duplicating asset service. - /// XXX: Currently it's a just a copy of the existing AssetService. so please don't attempt to use it. + /// A de-duplicating asset service. /// public class XAssetService : XAssetServiceBase, IAssetService { @@ -48,7 +47,9 @@ namespace OpenSim.Services.AssetService protected static XAssetService m_RootInstance; - public XAssetService(IConfigSource config) : base(config) + public XAssetService(IConfigSource config) : this(config, "AssetService") {} + + public XAssetService(IConfigSource config, string configName) : base(config, configName) { if (m_RootInstance == null) { @@ -56,22 +57,21 @@ namespace OpenSim.Services.AssetService if (m_AssetLoader != null) { - IConfig assetConfig = config.Configs["AssetService"]; + IConfig assetConfig = config.Configs[configName]; if (assetConfig == null) throw new Exception("No AssetService configuration"); - string loaderArgs = assetConfig.GetString("AssetLoaderArgs", - String.Empty); + string loaderArgs = assetConfig.GetString("AssetLoaderArgs", String.Empty); bool assetLoaderEnabled = assetConfig.GetBoolean("AssetLoaderEnabled", true); - if (assetLoaderEnabled) + if (assetLoaderEnabled && !HasChainedAssetService) { m_log.DebugFormat("[XASSET SERVICE]: Loading default asset set from {0}", loaderArgs); m_AssetLoader.ForEachDefaultXmlAsset( loaderArgs, - delegate(AssetBase a) + a => { AssetBase existingAsset = Get(a.ID); // AssetMetadata existingMetadata = GetMetadata(a.ID); @@ -103,7 +103,14 @@ namespace OpenSim.Services.AssetService try { - return m_Database.GetAsset(assetID); + AssetBase asset = m_Database.GetAsset(assetID); + + if (asset != null) + return asset; + else if (HasChainedAssetService) + return m_ChainedAssetService.Get(id); + else + return null; } catch (Exception e) { @@ -128,9 +135,17 @@ namespace OpenSim.Services.AssetService AssetBase asset = m_Database.GetAsset(assetID); if (asset != null) + { return asset.Metadata; - - return null; + } + else if (HasChainedAssetService) + { + return m_ChainedAssetService.GetMetadata(id); + } + else + { + return null; + } } public virtual byte[] GetData(string id) @@ -143,7 +158,13 @@ namespace OpenSim.Services.AssetService return null; AssetBase asset = m_Database.GetAsset(assetID); - return asset.Data; + + if (asset != null) + return asset.Data; + else if (HasChainedAssetService) + return m_ChainedAssetService.GetData(id); + else + return null; } public virtual bool Get(string id, Object sender, AssetRetrieved handler) @@ -157,6 +178,9 @@ namespace OpenSim.Services.AssetService AssetBase asset = m_Database.GetAsset(assetID); + if (asset == null && HasChainedAssetService) + asset = m_ChainedAssetService.Get(id); + //m_log.DebugFormat("[XASSET SERVICE]: Got asset {0}", asset); handler(id, sender, asset); @@ -194,6 +218,9 @@ namespace OpenSim.Services.AssetService if (!UUID.TryParse(id, out assetID)) return false; + // Don't bother deleting from a chained asset service. This isn't a big deal since deleting happens + // very rarely. + return m_Database.Delete(id); } } diff --git a/OpenSim/Services/AssetService/XAssetServiceBase.cs b/OpenSim/Services/AssetService/XAssetServiceBase.cs index 0c5c2c3d15..c118c9dac1 100644 --- a/OpenSim/Services/AssetService/XAssetServiceBase.cs +++ b/OpenSim/Services/AssetService/XAssetServiceBase.cs @@ -27,9 +27,11 @@ using System; using System.Reflection; +using log4net; using Nini.Config; using OpenSim.Framework; using OpenSim.Data; +using OpenSim.Server.Base; using OpenSim.Services.Interfaces; using OpenSim.Services.Base; @@ -37,10 +39,15 @@ namespace OpenSim.Services.AssetService { public class XAssetServiceBase : ServiceBase { - protected IXAssetDataPlugin m_Database = null; - protected IAssetLoader m_AssetLoader = null; + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - public XAssetServiceBase(IConfigSource config) : base(config) + protected IXAssetDataPlugin m_Database; + protected IAssetLoader m_AssetLoader; + protected IAssetService m_ChainedAssetService; + + protected bool HasChainedAssetService { get { return m_ChainedAssetService != null; } } + + public XAssetServiceBase(IConfigSource config, string configName) : base(config) { string dllName = String.Empty; string connString = String.Empty; @@ -48,7 +55,7 @@ namespace OpenSim.Services.AssetService // // Try reading the [AssetService] section first, if it exists // - IConfig assetConfig = config.Configs["AssetService"]; + IConfig assetConfig = config.Configs[configName]; if (assetConfig != null) { dllName = assetConfig.GetString("StorageProvider", dllName); @@ -77,17 +84,35 @@ namespace OpenSim.Services.AssetService if (m_Database == null) throw new Exception("Could not find a storage interface in the given module"); + string chainedAssetServiceDesignator = assetConfig.GetString("ChainedServiceModule", null); + + if (chainedAssetServiceDesignator != null) + { + m_log.InfoFormat( + "[XASSET SERVICE BASE]: Loading chained asset service from {0}", chainedAssetServiceDesignator); + + Object[] args = new Object[] { config, configName }; + m_ChainedAssetService = ServerUtils.LoadPlugin(chainedAssetServiceDesignator, args); + + if (!HasChainedAssetService) + throw new Exception( + String.Format("Failed to load ChainedAssetService from {0}", chainedAssetServiceDesignator)); + } + m_Database.Initialise(connString); - string loaderName = assetConfig.GetString("DefaultAssetLoader", - String.Empty); - - if (loaderName != String.Empty) + if (HasChainedAssetService) { - m_AssetLoader = LoadPlugin(loaderName); + string loaderName = assetConfig.GetString("DefaultAssetLoader", + String.Empty); - if (m_AssetLoader == null) - throw new Exception("Asset loader could not be loaded"); + if (loaderName != String.Empty) + { + m_AssetLoader = LoadPlugin(loaderName); + + if (m_AssetLoader == null) + throw new Exception("Asset loader could not be loaded"); + } } } } diff --git a/prebuild.xml b/prebuild.xml index 00451283a8..4d27a0bb4c 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -899,6 +899,7 @@ +