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