diff options
author | Oren Hurvitz | 2014-03-31 11:53:12 +0300 |
---|---|---|
committer | Oren Hurvitz | 2014-04-02 06:30:57 +0100 |
commit | d1c3f8eef58b29eb8760eeb1ac03852a2387f927 (patch) | |
tree | b8686f4ea01b6dac3740b9685734686e2178dd2d /OpenSim/Services | |
parent | fix orphaned code in sun module per mantis 7068 (diff) | |
download | opensim-SC-d1c3f8eef58b29eb8760eeb1ac03852a2387f927.zip opensim-SC-d1c3f8eef58b29eb8760eeb1ac03852a2387f927.tar.gz opensim-SC-d1c3f8eef58b29eb8760eeb1ac03852a2387f927.tar.bz2 opensim-SC-d1c3f8eef58b29eb8760eeb1ac03852a2387f927.tar.xz |
Added assets service method AssetsExist(), which returns whether the given list of assets exist.
This method is used to optimize sending assets with embedded assets: e.g., when a Hypergrid visitor takes an item into the inventory.
Diffstat (limited to 'OpenSim/Services')
6 files changed, 140 insertions, 42 deletions
diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs index 08fd3f8..0aefa16 100644 --- a/OpenSim/Services/AssetService/AssetService.cs +++ b/OpenSim/Services/AssetService/AssetService.cs | |||
@@ -153,9 +153,24 @@ namespace OpenSim.Services.AssetService | |||
153 | return true; | 153 | return true; |
154 | } | 154 | } |
155 | 155 | ||
156 | public virtual bool[] AssetsExist(string[] ids) | ||
157 | { | ||
158 | try | ||
159 | { | ||
160 | UUID[] uuid = Array.ConvertAll(ids, id => UUID.Parse(id)); | ||
161 | return m_Database.AssetsExist(uuid); | ||
162 | } | ||
163 | catch (Exception e) | ||
164 | { | ||
165 | m_log.Error("[ASSET SERVICE]: Exception getting assets ", e); | ||
166 | return new bool[ids.Length]; | ||
167 | } | ||
168 | } | ||
169 | |||
156 | public virtual string Store(AssetBase asset) | 170 | public virtual string Store(AssetBase asset) |
157 | { | 171 | { |
158 | if (!m_Database.ExistsAsset(asset.FullID)) | 172 | bool exists = m_Database.AssetsExist(new[] { asset.FullID })[0]; |
173 | if (!exists) | ||
159 | { | 174 | { |
160 | // m_log.DebugFormat( | 175 | // m_log.DebugFormat( |
161 | // "[ASSET SERVICE]: Storing asset {0} {1}, bytes {2}", asset.Name, asset.FullID, asset.Data.Length); | 176 | // "[ASSET SERVICE]: Storing asset {0} {1}, bytes {2}", asset.Name, asset.FullID, asset.Data.Length); |
@@ -186,4 +201,4 @@ namespace OpenSim.Services.AssetService | |||
186 | return m_Database.Delete(id); | 201 | return m_Database.Delete(id); |
187 | } | 202 | } |
188 | } | 203 | } |
189 | } \ No newline at end of file | 204 | } |
diff --git a/OpenSim/Services/AssetService/XAssetService.cs b/OpenSim/Services/AssetService/XAssetService.cs index 6047616..f58b769 100644 --- a/OpenSim/Services/AssetService/XAssetService.cs +++ b/OpenSim/Services/AssetService/XAssetService.cs | |||
@@ -175,9 +175,16 @@ namespace OpenSim.Services.AssetService | |||
175 | return true; | 175 | return true; |
176 | } | 176 | } |
177 | 177 | ||
178 | public virtual bool[] AssetsExist(string[] ids) | ||
179 | { | ||
180 | UUID[] uuid = Array.ConvertAll(ids, id => UUID.Parse(id)); | ||
181 | return m_Database.AssetsExist(uuid); | ||
182 | } | ||
183 | |||
178 | public virtual string Store(AssetBase asset) | 184 | public virtual string Store(AssetBase asset) |
179 | { | 185 | { |
180 | if (!m_Database.ExistsAsset(asset.FullID)) | 186 | bool exists = m_Database.AssetsExist(new[] { asset.FullID })[0]; |
187 | if (!exists) | ||
181 | { | 188 | { |
182 | // m_log.DebugFormat( | 189 | // m_log.DebugFormat( |
183 | // "[XASSET SERVICE]: Storing asset {0} {1}, bytes {2}", asset.Name, asset.FullID, asset.Data.Length); | 190 | // "[XASSET SERVICE]: Storing asset {0} {1}, bytes {2}", asset.Name, asset.FullID, asset.Data.Length); |
@@ -217,4 +224,4 @@ namespace OpenSim.Services.AssetService | |||
217 | m_ChainedAssetService.Delete(asset.ID); | 224 | m_ChainedAssetService.Delete(asset.ID); |
218 | } | 225 | } |
219 | } | 226 | } |
220 | } \ No newline at end of file | 227 | } |
diff --git a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs index 8b04d7f..32415e9 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs | |||
@@ -254,6 +254,27 @@ namespace OpenSim.Services.Connectors | |||
254 | return true; | 254 | return true; |
255 | } | 255 | } |
256 | 256 | ||
257 | public virtual bool[] AssetsExist(string[] ids) | ||
258 | { | ||
259 | string uri = m_ServerURI + "/get_assets_exist"; | ||
260 | |||
261 | bool[] exist = null; | ||
262 | try | ||
263 | { | ||
264 | exist = SynchronousRestObjectRequester.MakeRequest<string[], bool[]>("POST", uri, ids); | ||
265 | } | ||
266 | catch (Exception) | ||
267 | { | ||
268 | // This is most likely to happen because the server doesn't support this function, | ||
269 | // so just silently return "doesn't exist" for all the assets. | ||
270 | } | ||
271 | |||
272 | if (exist == null) | ||
273 | exist = new bool[ids.Length]; | ||
274 | |||
275 | return exist; | ||
276 | } | ||
277 | |||
257 | public string Store(AssetBase asset) | 278 | public string Store(AssetBase asset) |
258 | { | 279 | { |
259 | if (asset.Local) | 280 | if (asset.Local) |
diff --git a/OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs index c395178..3710c86 100644 --- a/OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs | |||
@@ -36,6 +36,7 @@ using OpenSim.Framework; | |||
36 | using OpenSim.Services.Interfaces; | 36 | using OpenSim.Services.Interfaces; |
37 | using OpenSim.Services.Connectors.Hypergrid; | 37 | using OpenSim.Services.Connectors.Hypergrid; |
38 | using OpenSim.Services.Connectors.SimianGrid; | 38 | using OpenSim.Services.Connectors.SimianGrid; |
39 | using OpenMetaverse; | ||
39 | 40 | ||
40 | namespace OpenSim.Services.Connectors | 41 | namespace OpenSim.Services.Connectors |
41 | { | 42 | { |
@@ -83,39 +84,6 @@ namespace OpenSim.Services.Connectors | |||
83 | } | 84 | } |
84 | } | 85 | } |
85 | 86 | ||
86 | private bool StringToUrlAndAssetID(string id, out string url, out string assetID) | ||
87 | { | ||
88 | url = String.Empty; | ||
89 | assetID = String.Empty; | ||
90 | |||
91 | Uri assetUri; | ||
92 | |||
93 | if (Uri.TryCreate(id, UriKind.Absolute, out assetUri) && | ||
94 | assetUri.Scheme == Uri.UriSchemeHttp) | ||
95 | { | ||
96 | // Simian | ||
97 | if (assetUri.Query != string.Empty) | ||
98 | { | ||
99 | NameValueCollection qscoll = HttpUtility.ParseQueryString(assetUri.Query); | ||
100 | assetID = qscoll["id"]; | ||
101 | if (assetID != null) | ||
102 | url = id.Replace(assetID, ""); // Malformed again, as simian expects | ||
103 | else | ||
104 | url = id; // !!! best effort | ||
105 | } | ||
106 | else // robust | ||
107 | { | ||
108 | url = "http://" + assetUri.Authority; | ||
109 | assetID = assetUri.LocalPath.Trim(new char[] { '/' }); | ||
110 | } | ||
111 | |||
112 | return true; | ||
113 | } | ||
114 | |||
115 | m_log.DebugFormat("[HG ASSET SERVICE]: Malformed URL {0}", id); | ||
116 | return false; | ||
117 | } | ||
118 | |||
119 | private IAssetService GetConnector(string url) | 87 | private IAssetService GetConnector(string url) |
120 | { | 88 | { |
121 | IAssetService connector = null; | 89 | IAssetService connector = null; |
@@ -149,7 +117,7 @@ namespace OpenSim.Services.Connectors | |||
149 | string url = string.Empty; | 117 | string url = string.Empty; |
150 | string assetID = string.Empty; | 118 | string assetID = string.Empty; |
151 | 119 | ||
152 | if (StringToUrlAndAssetID(id, out url, out assetID)) | 120 | if (Util.ParseForeignAssetID(id, out url, out assetID)) |
153 | { | 121 | { |
154 | IAssetService connector = GetConnector(url); | 122 | IAssetService connector = GetConnector(url); |
155 | return connector.Get(assetID); | 123 | return connector.Get(assetID); |
@@ -163,7 +131,7 @@ namespace OpenSim.Services.Connectors | |||
163 | string url = string.Empty; | 131 | string url = string.Empty; |
164 | string assetID = string.Empty; | 132 | string assetID = string.Empty; |
165 | 133 | ||
166 | if (StringToUrlAndAssetID(id, out url, out assetID)) | 134 | if (Util.ParseForeignAssetID(id, out url, out assetID)) |
167 | { | 135 | { |
168 | IAssetService connector = GetConnector(url); | 136 | IAssetService connector = GetConnector(url); |
169 | return connector.GetCached(assetID); | 137 | return connector.GetCached(assetID); |
@@ -177,7 +145,7 @@ namespace OpenSim.Services.Connectors | |||
177 | string url = string.Empty; | 145 | string url = string.Empty; |
178 | string assetID = string.Empty; | 146 | string assetID = string.Empty; |
179 | 147 | ||
180 | if (StringToUrlAndAssetID(id, out url, out assetID)) | 148 | if (Util.ParseForeignAssetID(id, out url, out assetID)) |
181 | { | 149 | { |
182 | IAssetService connector = GetConnector(url); | 150 | IAssetService connector = GetConnector(url); |
183 | return connector.GetMetadata(assetID); | 151 | return connector.GetMetadata(assetID); |
@@ -196,7 +164,7 @@ namespace OpenSim.Services.Connectors | |||
196 | string url = string.Empty; | 164 | string url = string.Empty; |
197 | string assetID = string.Empty; | 165 | string assetID = string.Empty; |
198 | 166 | ||
199 | if (StringToUrlAndAssetID(id, out url, out assetID)) | 167 | if (Util.ParseForeignAssetID(id, out url, out assetID)) |
200 | { | 168 | { |
201 | IAssetService connector = GetConnector(url); | 169 | IAssetService connector = GetConnector(url); |
202 | return connector.Get(assetID, sender, handler); | 170 | return connector.Get(assetID, sender, handler); |
@@ -205,12 +173,72 @@ namespace OpenSim.Services.Connectors | |||
205 | return false; | 173 | return false; |
206 | } | 174 | } |
207 | 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 | |||
208 | public string Store(AssetBase asset) | 236 | public string Store(AssetBase asset) |
209 | { | 237 | { |
210 | string url = string.Empty; | 238 | string url = string.Empty; |
211 | string assetID = string.Empty; | 239 | string assetID = string.Empty; |
212 | 240 | ||
213 | if (StringToUrlAndAssetID(asset.ID, out url, out assetID)) | 241 | if (Util.ParseForeignAssetID(asset.ID, out url, out assetID)) |
214 | { | 242 | { |
215 | IAssetService connector = GetConnector(url); | 243 | IAssetService connector = GetConnector(url); |
216 | // Restore the assetID to a simple UUID | 244 | // Restore the assetID to a simple UUID |
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs index 6f8d9ed..01cbf91 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs | |||
@@ -231,6 +231,26 @@ namespace OpenSim.Services.Connectors.SimianGrid | |||
231 | return true; | 231 | return true; |
232 | } | 232 | } |
233 | 233 | ||
234 | public bool[] AssetsExist(string[] ids) | ||
235 | { | ||
236 | if (String.IsNullOrEmpty(m_serverUrl)) | ||
237 | { | ||
238 | m_log.Error("[SIMIAN ASSET CONNECTOR]: No AssetServerURI configured"); | ||
239 | throw new InvalidOperationException(); | ||
240 | } | ||
241 | |||
242 | bool[] exist = new bool[ids.Length]; | ||
243 | |||
244 | for (int i = 0; i < ids.Length; i++) | ||
245 | { | ||
246 | AssetMetadata metadata = GetMetadata(ids[i]); | ||
247 | if (metadata != null) | ||
248 | exist[i] = true; | ||
249 | } | ||
250 | |||
251 | return exist; | ||
252 | } | ||
253 | |||
234 | /// <summary> | 254 | /// <summary> |
235 | /// Creates a new asset | 255 | /// Creates a new asset |
236 | /// </summary> | 256 | /// </summary> |
diff --git a/OpenSim/Services/Interfaces/IAssetService.cs b/OpenSim/Services/Interfaces/IAssetService.cs index 3c469c6..8f1e039 100644 --- a/OpenSim/Services/Interfaces/IAssetService.cs +++ b/OpenSim/Services/Interfaces/IAssetService.cs | |||
@@ -75,6 +75,13 @@ namespace OpenSim.Services.Interfaces | |||
75 | /// </param> | 75 | /// </param> |
76 | /// <returns>True if the id was parseable, false otherwise</returns> | 76 | /// <returns>True if the id was parseable, false otherwise</returns> |
77 | bool Get(string id, Object sender, AssetRetrieved handler); | 77 | bool Get(string id, Object sender, AssetRetrieved handler); |
78 | |||
79 | /// <summary> | ||
80 | /// Check if assets exist in the database. | ||
81 | /// </summary> | ||
82 | /// <param name="ids">The assets' IDs</param> | ||
83 | /// <returns>For each asset: true if it exists, false otherwise</returns> | ||
84 | bool[] AssetsExist(string[] ids); | ||
78 | 85 | ||
79 | /// <summary> | 86 | /// <summary> |
80 | /// Creates a new asset | 87 | /// Creates a new asset |