From aac8ca041170f6d1d648c6c5244dc3dfad428587 Mon Sep 17 00:00:00 2001 From: diva Date: Sun, 17 May 2009 01:38:43 +0000 Subject: [PATCH] HG asset transfers starting to work -- GETs only for now. --- .../ServiceConnectors/Asset/HGAssetBroker.cs | 62 +++++++++----- .../Scenes/Hypergrid/HGAssetMapper.cs | 76 ++++-------------- .../Connectors/Asset/AssetServiceConnector.cs | 11 ++- OpenSim/Services/AssetService/AssetService.cs | 1 + .../Services/AssetService/HGAssetService.cs | 80 ++++++++++++++++--- bin/OpenSim.ini.example | 9 ++- prebuild.xml | 1 + 7 files changed, 138 insertions(+), 102 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectors/Asset/HGAssetBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectors/Asset/HGAssetBroker.cs index d537d7bebc..c3a878ee60 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectors/Asset/HGAssetBroker.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectors/Asset/HGAssetBroker.cs @@ -35,6 +35,7 @@ using OpenSim.Servers.Base; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; +using OpenMetaverse; namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset { @@ -46,7 +47,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset MethodBase.GetCurrentMethod().DeclaringType); private IImprovedAssetCache m_Cache = null; - private IAssetService m_LocalService; + private IAssetService m_GridService; private IAssetService m_HGService; private bool m_Enabled = false; @@ -67,29 +68,29 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset IConfig assetConfig = source.Configs["AssetService"]; if (assetConfig == null) { - m_log.Error("[ASSET CONNECTOR]: AssetService missing from OpanSim.ini"); + m_log.Error("[HG ASSET CONNECTOR]: AssetService missing from OpenSim.ini"); return; } - string localDll = assetConfig.GetString("LocalModule", + string localDll = assetConfig.GetString("LocalGridAssetService", String.Empty); - string HGDll = assetConfig.GetString("HypergridModule", + string HGDll = assetConfig.GetString("HypergridAssetService", String.Empty); if (localDll == String.Empty) { - m_log.Error("[ASSET CONNECTOR]: No LocalModule named in section AssetService"); + m_log.Error("[HG ASSET CONNECTOR]: No LocalGridAssetService named in section AssetService"); return; } if (HGDll == String.Empty) { - m_log.Error("[ASSET CONNECTOR]: No HypergridModule named in section AssetService"); + m_log.Error("[HG ASSET CONNECTOR]: No HypergridAssetService named in section AssetService"); return; } Object[] args = new Object[] { source }; - m_LocalService = + m_GridService = ServerUtils.LoadPlugin(localDll, args); @@ -97,19 +98,19 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset ServerUtils.LoadPlugin(HGDll, args); - if (m_LocalService == null) + if (m_GridService == null) { - m_log.Error("[ASSET CONNECTOR]: Can't load local asset service"); + m_log.Error("[HG ASSET CONNECTOR]: Can't load local asset service"); return; } if (m_HGService == null) { - m_log.Error("[ASSET CONNECTOR]: Can't load hypergrid asset service"); + m_log.Error("[HG ASSET CONNECTOR]: Can't load hypergrid asset service"); return; } m_Enabled = true; - m_log.Info("[ASSET CONNECTOR]: HG asset broker enabled"); + m_log.Info("[HG ASSET CONNECTOR]: HG asset broker enabled"); } } } @@ -147,11 +148,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset m_Cache = null; } - m_log.InfoFormat("[ASSET CONNECTOR]: Enabled hypergrid asset broker for region {0}", scene.RegionInfo.RegionName); + m_log.InfoFormat("[HG ASSET CONNECTOR]: Enabled hypergrid asset broker for region {0}", scene.RegionInfo.RegionName); if (m_Cache != null) { - m_log.InfoFormat("[ASSET CONNECTOR]: Enabled asset caching for region {0}", scene.RegionInfo.RegionName); + m_log.InfoFormat("[HG ASSET CONNECTOR]: Enabled asset caching for region {0}", scene.RegionInfo.RegionName); } } @@ -168,20 +169,36 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset public AssetBase Get(string id) { + m_log.DebugFormat("[HG ASSET CONNECTOR]: Get {0}", id); AssetBase asset = null; if (m_Cache != null) { - m_Cache.Get(id); + asset = m_Cache.Get(id); if (asset != null) return asset; + else + m_log.DebugFormat("[HG ASSSET CONNECTOR]: Requested asset is not in cache. This shouldn't happen."); } if (IsHG(id)) + { asset = m_HGService.Get(id); + if (asset != null) + { + // Now store it locally + // For now, let me just do it for textures and scripts + if (((AssetType)asset.Type == AssetType.Texture) || + ((AssetType)asset.Type == AssetType.LSLBytecode) || + ((AssetType)asset.Type == AssetType.LSLText)) + { + m_GridService.Store(asset); + } + } + } else - asset = m_LocalService.Get(id); + asset = m_GridService.Get(id); if (asset != null) { @@ -210,7 +227,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset if (IsHG(id)) metadata = m_HGService.GetMetadata(id); else - metadata = m_LocalService.GetMetadata(id); + metadata = m_GridService.GetMetadata(id); return metadata; } @@ -231,7 +248,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset if (IsHG(id)) asset = m_HGService.Get(id); else - asset = m_LocalService.Get(id); + asset = m_GridService.Get(id); if (asset != null) { @@ -267,7 +284,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset } else { - return m_LocalService.Get(id, sender, delegate (string assetID, Object s, AssetBase a) + return m_GridService.Get(id, sender, delegate (string assetID, Object s, AssetBase a) { if (a != null && m_Cache != null) m_Cache.Cache(a); @@ -281,10 +298,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset if (m_Cache != null) m_Cache.Cache(asset); + if (asset.Temporary || asset.Local) + return asset.ID; + if (IsHG(asset.ID)) return m_HGService.Store(asset); else - return m_LocalService.Store(asset); + return m_GridService.Store(asset); } public bool UpdateContent(string id, byte[] data) @@ -303,7 +323,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset if (IsHG(id)) return m_HGService.UpdateContent(id, data); else - return m_LocalService.UpdateContent(id, data); + return m_GridService.UpdateContent(id, data); } public bool Delete(string id) @@ -314,7 +334,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset if (IsHG(id)) return m_HGService.Delete(id); else - return m_LocalService.Delete(id); + return m_GridService.Delete(id); } } } diff --git a/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs b/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs index 985ee9813c..e659ad16f0 100644 --- a/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs +++ b/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs @@ -108,50 +108,16 @@ namespace OpenSim.Region.Framework.Scenes.Hypergrid return m_assetMap.ContainsKey(uuid); } - private bool FetchAsset(GridAssetClient asscli, UUID assetID, bool isTexture) + private AssetBase FetchAsset(string url, UUID assetID, bool isTexture) { - // I'm not going over 3 seconds since this will be blocking processing of all the other inbound - // packets from the client. - int pollPeriod = 200; - int maxPolls = 15; + AssetBase asset = m_scene.AssetService.Get(url + "/" + assetID.ToString()); - AssetBase asset; - - // Maybe it came late, and it's already here. Check first. - if (m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset)) + if (asset != null) { - m_log.Debug("[HGScene]: Asset already in asset cache. " + assetID); - return true; + m_log.Debug("[HGScene]: Asset made it to asset cache. " + asset.Name + " " + assetID); + return asset; } - - - asscli.RequestAsset(assetID, isTexture); - - do - { - Thread.Sleep(pollPeriod); - - if (m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset) && (asset != null)) - { - m_log.Debug("[HGScene]: Asset made it to asset cache. " + asset.Name + " " + assetID); - // I think I need to store it in the asset DB too. - // For now, let me just do it for textures and scripts - if (((AssetType)asset.Type == AssetType.Texture) || - ((AssetType)asset.Type == AssetType.LSLBytecode) || - ((AssetType)asset.Type == AssetType.LSLText)) - { - AssetBase asset1 = new AssetBase(); - Copy(asset, asset1); - m_scene.CommsManager.AssetCache.AssetServer.StoreAsset(asset1); - } - return true; - } - } while (--maxPolls > 0); - - m_log.WarnFormat("[HGScene]: {0} {1} was not received before the retrieval timeout was reached", - isTexture ? "texture" : "asset", assetID.ToString()); - - return false; + return null; } private bool PostAsset(GridAssetClient asscli, UUID assetID, bool isTexture) @@ -291,39 +257,25 @@ namespace OpenSim.Region.Framework.Scenes.Hypergrid public void Get(UUID assetID, UUID ownerID) { - if (!IsInAssetMap(assetID) && !IsLocalUser(ownerID)) + if (!IsLocalUser(ownerID)) { // Get the item from the remote asset server onto the local AssetCache // and place an entry in m_assetMap - GridAssetClient asscli = null; string userAssetURL = UserAssetURL(ownerID); if (userAssetURL != null) { - m_assetServers.TryGetValue(userAssetURL, out asscli); - if (asscli == null) - { - m_log.Debug("[HGScene]: Starting new GridAssetClient for " + userAssetURL); - asscli = new GridAssetClient(userAssetURL); - asscli.SetReceiver(m_scene.CommsManager.AssetCache); // Straight to the asset cache! - m_assetServers.Add(userAssetURL, asscli); - asscli.Start(); - } - m_log.Debug("[HGScene]: Fetching object " + assetID + " to asset server " + userAssetURL); - bool success = FetchAsset(asscli, assetID, false); // asscli.RequestAsset(item.ItemID, false); + AssetBase asset = FetchAsset(userAssetURL, assetID, false); - // OK, now fetch the inside. - Dictionary ids = SniffUUIDs(assetID); - Dump(ids); - foreach (KeyValuePair kvp in ids) - FetchAsset(asscli, kvp.Key, kvp.Value); - - - if (success) + if (asset != null) { m_log.Debug("[HGScene]: Successfully fetched item from remote asset server " + userAssetURL); - m_assetMap.Add(assetID, asscli); + // OK, now fetch the inside. + Dictionary ids = SniffUUIDs(asset); + Dump(ids); + foreach (KeyValuePair kvp in ids) + FetchAsset(userAssetURL, kvp.Key, kvp.Value); } else m_log.Warn("[HGScene]: Could not fetch asset from remote asset server " + userAssetURL); diff --git a/OpenSim/Servers/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Servers/Connectors/Asset/AssetServiceConnector.cs index 8888c87d3c..b2b4cc2758 100644 --- a/OpenSim/Servers/Connectors/Asset/AssetServiceConnector.cs +++ b/OpenSim/Servers/Connectors/Asset/AssetServiceConnector.cs @@ -45,10 +45,15 @@ namespace OpenSim.Servers.Connectors MethodBase.GetCurrentMethod().DeclaringType); private string m_ServerURI = String.Empty; - private IImprovedAssetCache m_Cache = null; + private IImprovedAssetCache m_Cache = null; + + public AssetServicesConnector() + { + } - public AssetServicesConnector() - { + public AssetServicesConnector(string serverURI) + { + m_ServerURI = serverURI; } public AssetServicesConnector(IConfigSource source) diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs index af3a7467ab..968cf5cbef 100644 --- a/OpenSim/Services/AssetService/AssetService.cs +++ b/OpenSim/Services/AssetService/AssetService.cs @@ -66,6 +66,7 @@ namespace OpenSim.Services.AssetService public AssetBase Get(string id) { + m_log.DebugFormat("[ASSET SERVICE]: Get asset {0}", id); UUID assetID; if (!UUID.TryParse(id, out assetID)) diff --git a/OpenSim/Services/AssetService/HGAssetService.cs b/OpenSim/Services/AssetService/HGAssetService.cs index 87e42fe883..0b6389f794 100644 --- a/OpenSim/Services/AssetService/HGAssetService.cs +++ b/OpenSim/Services/AssetService/HGAssetService.cs @@ -28,11 +28,13 @@ using log4net; using Nini.Config; using System; +using System.Collections.Generic; using System.Reflection; using OpenSim.Framework; +using OpenSim.Servers.Connectors; using OpenSim.Services.Interfaces; -namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset +namespace OpenSim.Services.AssetService { public class HGAssetService : IAssetService { @@ -40,6 +42,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType); + private Dictionary m_connectors = new Dictionary(); + public HGAssetService(IConfigSource source) { IConfig moduleConfig = source.Configs["ServiceConnectors"]; @@ -50,27 +54,68 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset IConfig assetConfig = source.Configs["AssetService"]; if (assetConfig == null) { - m_log.Error("[ASSET CONNECTOR]: AssetService missing from OpanSim.ini"); + m_log.Error("[HG ASSET SERVICE]: AssetService missing from OpanSim.ini"); return; } - m_log.Info("[ASSET CONNECTOR]: HG asset service enabled"); + m_log.Info("[HG ASSET SERVICE]: HG asset service enabled"); } } - // - // Note to Diva: - // - // This is not the broker! - // This module is not supposed to route anything anywhere. This is where - // the code to access remote assets (by URL) goes. It can be assumed - // that the ID is a URL. The broker makes sure of that. - // - // This is a disposable comment :) Feel free to remove it - // + private bool StringToUrlAndAssetID(string id, out string url, out string assetID) + { + url = String.Empty; + assetID = String.Empty; + + Uri assetUri; + + if (Uri.TryCreate(id, UriKind.Absolute, out assetUri) && + assetUri.Scheme == Uri.UriSchemeHttp) + { + url = "http://" + assetUri.Authority; + assetID = assetUri.LocalPath; + return true; + } + + return false; + } + + private IAssetService GetConnector(string url) + { + AssetServicesConnector connector = null; + lock (m_connectors) + { + if (m_connectors.ContainsKey(url)) + { + connector = m_connectors[url]; + } + else + { + // We're instantiating this class explicitly, but this won't + // work in general, because the remote grid may be running + // an asset server that has a different protocol. + // Eventually we will want a piece of meta-protocol asking + // the remote server about its kind, and even asking it + // to send its own connector, which we would instantiate + // dynamically. Definitely coo, thing to do! + connector = new AssetServicesConnector(url); + m_connectors.Add(url, connector); + } + } + return connector; + } public AssetBase Get(string id) { + string url = string.Empty; + string assetID = string.Empty; + + if (StringToUrlAndAssetID(id, out url, out assetID)) + { + IAssetService connector = GetConnector(url); + return connector.Get(assetID); + } + return null; } @@ -86,6 +131,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset public bool Get(string id, Object sender, AssetRetrieved handler) { + string url = string.Empty; + string assetID = string.Empty; + + if (StringToUrlAndAssetID(id, out url, out assetID)) + { + IAssetService connector = GetConnector(url); + return connector.Get(assetID, sender, handler); + } + return false; } diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index e84cd5760d..6d061bbdb6 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -1297,9 +1297,12 @@ ; Paremeters for the Hypergrid connector - ; Parameters for the HG Broker - ;LocalModule = "OpenSim.Services.AssetService.dll:AssetService" - ;HypergridModule = "OpenSim.Services.AssetService.dll:HGAssetService" + ;; Parameters for the HG Broker + ; Use this one if you have a standalone grid + LocalGridAssetService = "OpenSim.Services.AssetService.dll:AssetService" + ; Use this one if this sim is connected to a grid-wide asset server + ;LocalGridAssetService = "OpenSim.Servers.Connectors.dll:AssetServiceConnector" + HypergridAssetService = "OpenSim.Services.AssetService.dll:HGAssetService" [AssetCache] ; Number of buckets for assets diff --git a/prebuild.xml b/prebuild.xml index 38ab757968..d2ed73edd7 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1318,6 +1318,7 @@ +