OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
HGAssetServiceConnector.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 Nini.Config;
30 using System;
31 using System.Collections.Generic;
32 using System.Collections.Specialized;
33 using System.Reflection;
34 using System.Web;
35 using OpenSim.Framework;
36 using OpenSim.Services.Interfaces;
37 using OpenSim.Services.Connectors.Hypergrid;
38 using OpenSim.Services.Connectors.SimianGrid;
39 using OpenMetaverse;
40 
41 namespace OpenSim.Services.Connectors
42 {
44  {
45  private static readonly ILog m_log =
46  LogManager.GetLogger(
47  MethodBase.GetCurrentMethod().DeclaringType);
48 
49  private Dictionary<IAssetService, object> m_endpointSerializer = new Dictionary<IAssetService, object>();
50  private object EndPointLock(IAssetService connector)
51  {
52  lock (m_endpointSerializer)
53  {
54  object eplock = null;
55 
56  if (! m_endpointSerializer.TryGetValue(connector, out eplock))
57  {
58  eplock = new object();
59  m_endpointSerializer.Add(connector, eplock);
60  // m_log.WarnFormat("[WEB UTIL] add a new host to end point serializer {0}",endpoint);
61  }
62 
63  return eplock;
64  }
65  }
66 
67  private Dictionary<string, IAssetService> m_connectors = new Dictionary<string, IAssetService>();
68 
69  public HGAssetServiceConnector(IConfigSource source)
70  {
71  IConfig moduleConfig = source.Configs["Modules"];
72  if (moduleConfig != null)
73  {
74  // string name = moduleConfig.GetString("AssetServices", "");
75 
76  IConfig assetConfig = source.Configs["AssetService"];
77  if (assetConfig == null)
78  {
79  m_log.Error("[HG ASSET SERVICE]: AssetService missing from OpenSim.ini");
80  return;
81  }
82 
83  m_log.Info("[HG ASSET SERVICE]: HG asset service enabled");
84  }
85  }
86 
87  private IAssetService GetConnector(string url)
88  {
89  IAssetService connector = null;
90  lock (m_connectors)
91  {
92  if (m_connectors.ContainsKey(url))
93  {
94  connector = m_connectors[url];
95  }
96  else
97  {
98  // Still not as flexible as I would like this to be,
99  // but good enough for now
100  string connectorType = new HeloServicesConnector(url).Helo();
101  m_log.DebugFormat("[HG ASSET SERVICE]: HELO returned {0}", connectorType);
102  if (connectorType == "opensim-simian")
103  {
104  connector = new SimianAssetServiceConnector(url);
105  }
106  else
107  connector = new AssetServicesConnector(url);
108 
109  m_connectors.Add(url, connector);
110  }
111  }
112  return connector;
113  }
114 
115  public AssetBase Get(string id)
116  {
117  string url = string.Empty;
118  string assetID = string.Empty;
119 
120  if (Util.ParseForeignAssetID(id, out url, out assetID))
121  {
122  IAssetService connector = GetConnector(url);
123  return connector.Get(assetID);
124  }
125 
126  return null;
127  }
128 
129  public AssetBase GetCached(string id)
130  {
131  string url = string.Empty;
132  string assetID = string.Empty;
133 
134  if (Util.ParseForeignAssetID(id, out url, out assetID))
135  {
136  IAssetService connector = GetConnector(url);
137  return connector.GetCached(assetID);
138  }
139 
140  return null;
141  }
142 
143  public AssetMetadata GetMetadata(string id)
144  {
145  string url = string.Empty;
146  string assetID = string.Empty;
147 
148  if (Util.ParseForeignAssetID(id, out url, out assetID))
149  {
150  IAssetService connector = GetConnector(url);
151  return connector.GetMetadata(assetID);
152  }
153 
154  return null;
155  }
156 
157  public byte[] GetData(string id)
158  {
159  return null;
160  }
161 
162  public bool Get(string id, Object sender, AssetRetrieved handler)
163  {
164  string url = string.Empty;
165  string assetID = string.Empty;
166 
167  if (Util.ParseForeignAssetID(id, out url, out assetID))
168  {
169  IAssetService connector = GetConnector(url);
170  return connector.Get(assetID, sender, handler);
171  }
172 
173  return false;
174  }
175 
176 
177  private struct AssetAndIndex
178  {
179  public UUID assetID;
180  public int index;
181 
182  public AssetAndIndex(UUID assetID, int index)
183  {
184  this.assetID = assetID;
185  this.index = index;
186  }
187  }
188 
189  public virtual bool[] AssetsExist(string[] ids)
190  {
191  // This method is a bit complicated because it works even if the assets belong to different
192  // servers; that requires sending separate requests to each server.
193 
194  // Group the assets by the server they belong to
195 
196  var url2assets = new Dictionary<string, List<AssetAndIndex>>();
197 
198  for (int i = 0; i < ids.Length; i++)
199  {
200  string url = string.Empty;
201  string assetID = string.Empty;
202 
203  if (Util.ParseForeignAssetID(ids[i], out url, out assetID))
204  {
205  if (!url2assets.ContainsKey(url))
206  url2assets.Add(url, new List<AssetAndIndex>());
207  url2assets[url].Add(new AssetAndIndex(UUID.Parse(assetID), i));
208  }
209  }
210 
211  // Query each of the servers in turn
212 
213  bool[] exist = new bool[ids.Length];
214 
215  foreach (string url in url2assets.Keys)
216  {
217  IAssetService connector = GetConnector(url);
218  lock (EndPointLock(connector))
219  {
220  List<AssetAndIndex> curAssets = url2assets[url];
221  string[] assetIDs = curAssets.ConvertAll(a => a.assetID.ToString()).ToArray();
222  bool[] curExist = connector.AssetsExist(assetIDs);
223 
224  int i = 0;
225  foreach (AssetAndIndex ai in curAssets)
226  {
227  exist[ai.index] = curExist[i];
228  ++i;
229  }
230  }
231  }
232 
233  return exist;
234  }
235 
236  public string Store(AssetBase asset)
237  {
238  string url = string.Empty;
239  string assetID = string.Empty;
240 
241  if (Util.ParseForeignAssetID(asset.ID, out url, out assetID))
242  {
243  IAssetService connector = GetConnector(url);
244  // Restore the assetID to a simple UUID
245  asset.ID = assetID;
246  lock (EndPointLock(connector))
247  return connector.Store(asset);
248  }
249 
250  return String.Empty;
251  }
252 
253  public bool UpdateContent(string id, byte[] data)
254  {
255  return false;
256  }
257 
258  public bool Delete(string id)
259  {
260  return false;
261  }
262  }
263 }
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...
AssetBase GetCached(string id)
Synchronously fetches an asset from the local cache only.
Asset class. All Assets are reference by this class or a class derived from this class ...
Definition: AssetBase.cs:49
byte[] GetData(string id)
Get an asset's data, ignoring the metadata.
AssetBase Get(string id)
Get an asset synchronously.
bool UpdateContent(string id, byte[] data)
Update an asset's content
virtual bool[] AssetsExist(string[] ids)
Check if assets exist in the database.
string Store(AssetBase asset)
Creates a new asset
delegate void AssetRetrieved(string id, Object sender, AssetBase asset)
string ID
Asset MetaData ID (transferring from UUID to string ID)
Definition: AssetBase.cs:177
AssetMetadata GetMetadata(string id)
Get an asset's metadata