diff options
Diffstat (limited to 'OpenSim/Grid/AssetInventoryServer/Plugins/Simple')
3 files changed, 372 insertions, 0 deletions
diff --git a/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/Resources/AssetInventoryServerSimplePlugins.addin.xml b/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/Resources/AssetInventoryServerSimplePlugins.addin.xml new file mode 100644 index 0000000..53534c4 --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/Resources/AssetInventoryServerSimplePlugins.addin.xml | |||
@@ -0,0 +1,13 @@ | |||
1 | <Addin id="OpenSim.Grid.AssetInventoryServer.Plugins.Simple" version="0.1"> | ||
2 | <Runtime> | ||
3 | <Import assembly="OpenSim.Grid.AssetInventoryServer.Plugins.Simple.dll" /> | ||
4 | </Runtime> | ||
5 | |||
6 | <Dependencies> | ||
7 | <Addin id="OpenSim.Grid.AssetInventoryServer" version="0.1" /> | ||
8 | </Dependencies> | ||
9 | |||
10 | <Extension path="/OpenSim/AssetInventoryServer/StorageProvider"> | ||
11 | <Plugin id="SimpleAssetStorage" provider="OpenSim.Grid.AssetInventoryServer.Plugins.Simple.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.Simple.SimpleAssetStoragePlugin" /> | ||
12 | </Extension> | ||
13 | </Addin> | ||
diff --git a/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/SimpleAssetStoragePlugin.cs b/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/SimpleAssetStoragePlugin.cs new file mode 100644 index 0000000..fd198d9 --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/SimpleAssetStoragePlugin.cs | |||
@@ -0,0 +1,286 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008 Intel Corporation | ||
3 | * All rights reserved. | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * -- Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * -- Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * -- Neither the name of the Intel Corporation nor the names of its | ||
14 | * contributors may be used to endorse or promote products derived from | ||
15 | * this software without specific prior written permission. | ||
16 | * | ||
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
18 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
20 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR ITS | ||
21 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
23 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
24 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
25 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
26 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
28 | */ | ||
29 | |||
30 | using System; | ||
31 | using System.Collections.Generic; | ||
32 | using System.Net; | ||
33 | using System.IO; | ||
34 | using ExtensionLoader; | ||
35 | using OpenMetaverse; | ||
36 | using OpenMetaverse.StructuredData; | ||
37 | using OpenSim.Framework; | ||
38 | |||
39 | namespace OpenSim.Grid.AssetInventoryServer.Plugins.Simple | ||
40 | { | ||
41 | public class SimpleAssetStoragePlugin : IAssetStorageProvider | ||
42 | { | ||
43 | const string EXTENSION_NAME = "SimpleAssetStorage"; // Used in metrics reporting | ||
44 | const string DEFAULT_DATA_DIR = "SimpleAssets"; | ||
45 | const string TEMP_DATA_DIR = "SimpleAssetsTemp"; | ||
46 | |||
47 | AssetInventoryServer server; | ||
48 | Dictionary<UUID, Metadata> metadataStorage; | ||
49 | Dictionary<UUID, string> filenames; | ||
50 | |||
51 | public SimpleAssetStoragePlugin() | ||
52 | { | ||
53 | } | ||
54 | |||
55 | #region Required Interfaces | ||
56 | |||
57 | public BackendResponse TryFetchMetadata(UUID assetID, out Metadata metadata) | ||
58 | { | ||
59 | metadata = null; | ||
60 | BackendResponse ret; | ||
61 | |||
62 | if (metadataStorage.TryGetValue(assetID, out metadata)) | ||
63 | ret = BackendResponse.Success; | ||
64 | else | ||
65 | ret = BackendResponse.NotFound; | ||
66 | |||
67 | server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now); | ||
68 | return ret; | ||
69 | } | ||
70 | |||
71 | public BackendResponse TryFetchData(UUID assetID, out byte[] assetData) | ||
72 | { | ||
73 | assetData = null; | ||
74 | string filename; | ||
75 | BackendResponse ret; | ||
76 | |||
77 | if (filenames.TryGetValue(assetID, out filename)) | ||
78 | { | ||
79 | try | ||
80 | { | ||
81 | assetData = File.ReadAllBytes(filename); | ||
82 | ret = BackendResponse.Success; | ||
83 | } | ||
84 | catch (Exception ex) | ||
85 | { | ||
86 | Logger.Log.ErrorFormat("Failed reading data for asset {0} from {1}: {2}", assetID, filename, ex.Message); | ||
87 | ret = BackendResponse.Failure; | ||
88 | } | ||
89 | } | ||
90 | else | ||
91 | { | ||
92 | ret = BackendResponse.NotFound; | ||
93 | } | ||
94 | |||
95 | server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (assetData != null ? assetData.Length : 0), DateTime.Now); | ||
96 | return ret; | ||
97 | } | ||
98 | |||
99 | public BackendResponse TryFetchDataMetadata(UUID assetID, out Metadata metadata, out byte[] assetData) | ||
100 | { | ||
101 | metadata = null; | ||
102 | assetData = null; | ||
103 | string filename; | ||
104 | BackendResponse ret; | ||
105 | |||
106 | if (metadataStorage.TryGetValue(assetID, out metadata) && | ||
107 | filenames.TryGetValue(assetID, out filename)) | ||
108 | { | ||
109 | try | ||
110 | { | ||
111 | assetData = File.ReadAllBytes(filename); | ||
112 | ret = BackendResponse.Success; | ||
113 | } | ||
114 | catch (Exception ex) | ||
115 | { | ||
116 | Logger.Log.ErrorFormat("Failed reading data for asset {0} from {1}: {2}", assetID, filename, ex.Message); | ||
117 | ret = BackendResponse.Failure; | ||
118 | } | ||
119 | } | ||
120 | else | ||
121 | { | ||
122 | ret = BackendResponse.NotFound; | ||
123 | } | ||
124 | |||
125 | server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now); | ||
126 | server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (assetData != null ? assetData.Length : 0), DateTime.Now); | ||
127 | return ret; | ||
128 | } | ||
129 | |||
130 | public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData, out UUID assetID) | ||
131 | { | ||
132 | assetID = metadata.ID = UUID.Random(); | ||
133 | return TryCreateAsset(metadata, assetData); | ||
134 | } | ||
135 | |||
136 | public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData) | ||
137 | { | ||
138 | BackendResponse ret; | ||
139 | |||
140 | string path; | ||
141 | string filename = String.Format("{0}.{1}", metadata.ID, Utils.ContentTypeToExtension(metadata.ContentType)); | ||
142 | |||
143 | if (metadata.Temporary) | ||
144 | path = Path.Combine(TEMP_DATA_DIR, filename); | ||
145 | else | ||
146 | path = Path.Combine(DEFAULT_DATA_DIR, filename); | ||
147 | |||
148 | try | ||
149 | { | ||
150 | File.WriteAllBytes(path, assetData); | ||
151 | lock (filenames) filenames[metadata.ID] = path; | ||
152 | |||
153 | // Set the creation date to right now | ||
154 | metadata.CreationDate = DateTime.Now; | ||
155 | |||
156 | lock (metadataStorage) | ||
157 | metadataStorage[metadata.ID] = metadata; | ||
158 | |||
159 | ret = BackendResponse.Success; | ||
160 | } | ||
161 | catch (Exception ex) | ||
162 | { | ||
163 | Logger.Log.ErrorFormat("Failed writing data for asset {0} to {1}: {2}", metadata.ID, filename, ex.Message); | ||
164 | ret = BackendResponse.Failure; | ||
165 | } | ||
166 | |||
167 | server.MetricsProvider.LogAssetCreate(EXTENSION_NAME, ret, metadata.ID, assetData.Length, DateTime.Now); | ||
168 | return ret; | ||
169 | } | ||
170 | |||
171 | public int ForEach(Action<Metadata> action, int start, int count) | ||
172 | { | ||
173 | int rowCount = 0; | ||
174 | |||
175 | lock (metadataStorage) | ||
176 | { | ||
177 | foreach (Metadata metadata in metadataStorage.Values) | ||
178 | { | ||
179 | action(metadata); | ||
180 | ++rowCount; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | return rowCount; | ||
185 | } | ||
186 | |||
187 | #endregion Required Interfaces | ||
188 | |||
189 | #region IPlugin implementation | ||
190 | |||
191 | public void Initialise(AssetInventoryServer server) | ||
192 | { | ||
193 | this.server = server; | ||
194 | |||
195 | metadataStorage = new Dictionary<UUID, Metadata>(); | ||
196 | filenames = new Dictionary<UUID, string>(); | ||
197 | |||
198 | LoadFiles(DEFAULT_DATA_DIR, false); | ||
199 | LoadFiles(TEMP_DATA_DIR, true); | ||
200 | |||
201 | Logger.Log.InfoFormat("Initialized the store index with metadata for {0} assets", | ||
202 | metadataStorage.Count); | ||
203 | } | ||
204 | |||
205 | /// <summary> | ||
206 | /// <para>Initialises asset interface</para> | ||
207 | /// </summary> | ||
208 | public void Initialise() | ||
209 | { | ||
210 | Logger.Log.InfoFormat("[ASSET]: {0} cannot be default-initialized!", Name); | ||
211 | throw new PluginNotInitialisedException(Name); | ||
212 | } | ||
213 | |||
214 | public void Dispose() | ||
215 | { | ||
216 | WipeTemporary(); | ||
217 | } | ||
218 | |||
219 | public string Version | ||
220 | { | ||
221 | // TODO: this should be something meaningful and not hardcoded? | ||
222 | get { return "0.1"; } | ||
223 | } | ||
224 | |||
225 | public string Name | ||
226 | { | ||
227 | get { return "AssetInventoryServer Simple asset storage provider"; } | ||
228 | } | ||
229 | |||
230 | #endregion IPlugin implementation | ||
231 | |||
232 | public void WipeTemporary() | ||
233 | { | ||
234 | if (Directory.Exists(TEMP_DATA_DIR)) | ||
235 | { | ||
236 | try { Directory.Delete(TEMP_DATA_DIR); } | ||
237 | catch (Exception ex) { Logger.Log.Error(ex.Message); } | ||
238 | } | ||
239 | } | ||
240 | |||
241 | void LoadFiles(string folder, bool temporary) | ||
242 | { | ||
243 | // Try to create the directory if it doesn't already exist | ||
244 | if (!Directory.Exists(folder)) | ||
245 | { | ||
246 | try { Directory.CreateDirectory(folder); } | ||
247 | catch (Exception ex) | ||
248 | { | ||
249 | Logger.Log.Warn(ex.Message); | ||
250 | return; | ||
251 | } | ||
252 | } | ||
253 | |||
254 | lock (metadataStorage) | ||
255 | { | ||
256 | try | ||
257 | { | ||
258 | string[] assets = Directory.GetFiles(folder); | ||
259 | |||
260 | for (int i = 0; i < assets.Length; i++) | ||
261 | { | ||
262 | string filename = assets[i]; | ||
263 | byte[] data = File.ReadAllBytes(filename); | ||
264 | |||
265 | Metadata metadata = new Metadata(); | ||
266 | metadata.CreationDate = File.GetCreationTime(filename); | ||
267 | metadata.Description = String.Empty; | ||
268 | metadata.ID = SimpleUtils.ParseUUIDFromFilename(filename); | ||
269 | metadata.Name = SimpleUtils.ParseNameFromFilename(filename); | ||
270 | metadata.SHA1 = OpenMetaverse.Utils.SHA1(data); | ||
271 | metadata.Temporary = false; | ||
272 | metadata.ContentType = Utils.ExtensionToContentType(Path.GetExtension(filename).TrimStart('.')); | ||
273 | |||
274 | // Store the loaded data | ||
275 | metadataStorage[metadata.ID] = metadata; | ||
276 | filenames[metadata.ID] = filename; | ||
277 | } | ||
278 | } | ||
279 | catch (Exception ex) | ||
280 | { | ||
281 | Logger.Log.Warn(ex.Message); | ||
282 | } | ||
283 | } | ||
284 | } | ||
285 | } | ||
286 | } | ||
diff --git a/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/SimpleUtils.cs b/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/SimpleUtils.cs new file mode 100644 index 0000000..6a32718 --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/SimpleUtils.cs | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008 Intel Corporation | ||
3 | * All rights reserved. | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * -- Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * -- Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * -- Neither the name of the Intel Corporation nor the names of its | ||
14 | * contributors may be used to endorse or promote products derived from | ||
15 | * this software without specific prior written permission. | ||
16 | * | ||
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
18 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
20 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR ITS | ||
21 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
23 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
24 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
25 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
26 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
28 | */ | ||
29 | |||
30 | using System; | ||
31 | using System.IO; | ||
32 | using OpenMetaverse; | ||
33 | |||
34 | namespace OpenSim.Grid.AssetInventoryServer.Plugins.Simple | ||
35 | { | ||
36 | public static class SimpleUtils | ||
37 | { | ||
38 | public static string ParseNameFromFilename(string filename) | ||
39 | { | ||
40 | filename = Path.GetFileName(filename); | ||
41 | |||
42 | int dot = filename.LastIndexOf('.'); | ||
43 | int firstDash = filename.IndexOf('-'); | ||
44 | |||
45 | if (dot - 37 > 0 && firstDash > 0) | ||
46 | return filename.Substring(0, firstDash); | ||
47 | else | ||
48 | return String.Empty; | ||
49 | } | ||
50 | |||
51 | public static UUID ParseUUIDFromFilename(string filename) | ||
52 | { | ||
53 | int dot = filename.LastIndexOf('.'); | ||
54 | |||
55 | if (dot > 35) | ||
56 | { | ||
57 | // Grab the last 36 characters of the filename | ||
58 | string uuidString = filename.Substring(dot - 36, 36); | ||
59 | UUID uuid; | ||
60 | UUID.TryParse(uuidString, out uuid); | ||
61 | return uuid; | ||
62 | } | ||
63 | else | ||
64 | { | ||
65 | UUID uuid; | ||
66 | if (UUID.TryParse(Path.GetFileName(filename), out uuid)) | ||
67 | return uuid; | ||
68 | else | ||
69 | return UUID.Zero; | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | } | ||