OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
LocalAssetServiceConnector.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors, http://opensimulator.org/
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using log4net;
29 using Mono.Addins;
30 using Nini.Config;
31 using System;
32 using System.Collections.Generic;
33 using System.Reflection;
34 using OpenSim.Framework;
35 using OpenSim.Server.Base;
36 using OpenSim.Region.Framework.Interfaces;
37 using OpenSim.Region.Framework.Scenes;
38 using OpenSim.Services.Interfaces;
39 
40 namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
41 {
42  [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalAssetServicesConnector")]
44  {
45  private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 
47  private IImprovedAssetCache m_Cache = null;
48 
49  private IAssetService m_AssetService;
50 
51  private bool m_Enabled = false;
52 
53  public Type ReplaceableInterface
54  {
55  get { return null; }
56  }
57 
58  public string Name
59  {
60  get { return "LocalAssetServicesConnector"; }
61  }
62 
63  public void Initialise(IConfigSource source)
64  {
65  IConfig moduleConfig = source.Configs["Modules"];
66  if (moduleConfig != null)
67  {
68  string name = moduleConfig.GetString("AssetServices", "");
69  if (name == Name)
70  {
71  IConfig assetConfig = source.Configs["AssetService"];
72  if (assetConfig == null)
73  {
74  m_log.Error("[LOCAL ASSET SERVICES CONNECTOR]: AssetService missing from OpenSim.ini");
75  return;
76  }
77 
78  string serviceDll = assetConfig.GetString("LocalServiceModule", String.Empty);
79 
80  if (serviceDll == String.Empty)
81  {
82  m_log.Error("[LOCAL ASSET SERVICES CONNECTOR]: No LocalServiceModule named in section AssetService");
83  return;
84  }
85  else
86  {
87  m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Loading asset service at {0}", serviceDll);
88  }
89 
90  Object[] args = new Object[] { source };
91  m_AssetService = ServerUtils.LoadPlugin<IAssetService>(serviceDll, args);
92 
93  if (m_AssetService == null)
94  {
95  m_log.Error("[LOCAL ASSET SERVICES CONNECTOR]: Can't load asset service");
96  return;
97  }
98  m_Enabled = true;
99  m_log.Info("[LOCAL ASSET SERVICES CONNECTOR]: Local asset connector enabled");
100  }
101  }
102  }
103 
104  public void PostInitialise()
105  {
106  }
107 
108  public void Close()
109  {
110  }
111 
112  public void AddRegion(Scene scene)
113  {
114  if (!m_Enabled)
115  return;
116 
117  scene.RegisterModuleInterface<IAssetService>(this);
118  }
119 
120  public void RemoveRegion(Scene scene)
121  {
122  }
123 
124  public void RegionLoaded(Scene scene)
125  {
126  if (!m_Enabled)
127  return;
128 
129  if (m_Cache == null)
130  {
131  m_Cache = scene.RequestModuleInterface<IImprovedAssetCache>();
132 
133  if (!(m_Cache is ISharedRegionModule))
134  m_Cache = null;
135  }
136 
137  m_log.DebugFormat(
138  "[LOCAL ASSET SERVICES CONNECTOR]: Enabled connector for region {0}", scene.RegionInfo.RegionName);
139 
140  if (m_Cache != null)
141  {
142  m_log.DebugFormat(
143  "[LOCAL ASSET SERVICES CONNECTOR]: Enabled asset caching for region {0}",
144  scene.RegionInfo.RegionName);
145  }
146  else
147  {
148  // Short-circuit directly to storage layer. This ends up storing temporary and local assets.
149  //
150  scene.UnregisterModuleInterface<IAssetService>(this);
151  scene.RegisterModuleInterface<IAssetService>(m_AssetService);
152  }
153  }
154 
155  public AssetBase Get(string id)
156  {
157 // m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Synchronously requesting asset {0}", id);
158 
159  AssetBase asset = null;
160  if (m_Cache != null)
161  asset = m_Cache.Get(id);
162 
163  if (asset == null)
164  {
165  asset = m_AssetService.Get(id);
166  if ((m_Cache != null) && (asset != null))
167  m_Cache.Cache(asset);
168 
169 // if (null == asset)
170 // m_log.WarnFormat("[LOCAL ASSET SERVICES CONNECTOR]: Could not synchronously find asset with id {0}", id);
171  }
172 
173  return asset;
174  }
175 
176  public AssetBase GetCached(string id)
177  {
178 // m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Cache request for {0}", id);
179 
180  if (m_Cache != null)
181  return m_Cache.Get(id);
182 
183  return null;
184  }
185 
186  public AssetMetadata GetMetadata(string id)
187  {
188  AssetBase asset = null;
189  if (m_Cache != null)
190  asset = m_Cache.Get(id);
191 
192  if (asset != null)
193  return asset.Metadata;
194 
195  asset = m_AssetService.Get(id);
196  if (asset != null)
197  {
198  if (m_Cache != null)
199  m_Cache.Cache(asset);
200  return asset.Metadata;
201  }
202 
203  return null;
204  }
205 
206  public byte[] GetData(string id)
207  {
208 // m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Requesting data for asset {0}", id);
209 
210  AssetBase asset = null;
211 
212  if (m_Cache != null)
213  asset = m_Cache.Get(id);
214 
215  if (asset != null)
216  return asset.Data;
217 
218  asset = m_AssetService.Get(id);
219  if (asset != null)
220  {
221  if (m_Cache != null)
222  m_Cache.Cache(asset);
223  return asset.Data;
224  }
225 
226  return null;
227  }
228 
229  public bool Get(string id, Object sender, AssetRetrieved handler)
230  {
231 // m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Asynchronously requesting asset {0}", id);
232 
233  if (m_Cache != null)
234  {
235  AssetBase asset = m_Cache.Get(id);
236 
237  if (asset != null)
238  {
239  Util.FireAndForget(
240  o => handler(id, sender, asset), null, "LocalAssetServiceConnector.GotFromCacheCallback");
241  return true;
242  }
243  }
244 
245  return m_AssetService.Get(id, sender, delegate (string assetID, Object s, AssetBase a)
246  {
247  if ((a != null) && (m_Cache != null))
248  m_Cache.Cache(a);
249 
250 // if (null == a)
251 // m_log.WarnFormat("[LOCAL ASSET SERVICES CONNECTOR]: Could not asynchronously find asset with id {0}", id);
252 
253  Util.FireAndForget(
254  o => handler(assetID, s, a), null, "LocalAssetServiceConnector.GotFromServiceCallback");
255  });
256  }
257 
258  public bool[] AssetsExist(string[] ids)
259  {
260  return m_AssetService.AssetsExist(ids);
261  }
262 
263  public string Store(AssetBase asset)
264  {
265  if (m_Cache != null)
266  m_Cache.Cache(asset);
267 
268  if (asset.Local)
269  {
270 // m_log.DebugFormat(
271 // "[LOCAL ASSET SERVICE CONNECTOR]: Returning asset {0} {1} without querying database since status Temporary = {2}, Local = {3}",
272 // asset.Name, asset.ID, asset.Temporary, asset.Local);
273 
274  return asset.ID;
275  }
276  else
277  {
278 // m_log.DebugFormat(
279 // "[LOCAL ASSET SERVICE CONNECTOR]: Passing {0} {1} on to asset service for storage, status Temporary = {2}, Local = {3}",
280 // asset.Name, asset.ID, asset.Temporary, asset.Local);
281 
282  return m_AssetService.Store(asset);
283  }
284  }
285 
286  public bool UpdateContent(string id, byte[] data)
287  {
288  AssetBase asset = null;
289  if (m_Cache != null)
290  m_Cache.Get(id);
291  if (asset != null)
292  {
293  asset.Data = data;
294  if (m_Cache != null)
295  m_Cache.Cache(asset);
296  }
297 
298  return m_AssetService.UpdateContent(id, data);
299  }
300 
301  public bool Delete(string id)
302  {
303  if (m_Cache != null)
304  m_Cache.Expire(id);
305 
306  return m_AssetService.Delete(id);
307  }
308  }
309 }
bool Get(string id, Object sender, AssetRetrieved handler)
Get an asset synchronously or asynchronously (depending on whether it is locally cached) and fire a c...
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
void Initialise(IConfigSource source)
This is called to initialize the region module. For shared modules, this is called exactly once...
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
bool Local
Is this a region only asset, or does this exist on the asset server also
Definition: AssetBase.cs:213
Asset class. All Assets are reference by this class or a class derived from this class ...
Definition: AssetBase.cs:49
void PostInitialise()
This is called exactly once after all the shared region-modules have been instanciated and IRegionMod...
Non-texture assets
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
delegate void AssetRetrieved(string id, Object sender, AssetBase asset)
AssetBase GetCached(string id)
Synchronously fetches an asset from the local cache only.