aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Grid/AssetInventoryServer/Extensions
diff options
context:
space:
mode:
authorMike Mazur2009-02-16 02:25:44 +0000
committerMike Mazur2009-02-16 02:25:44 +0000
commit16fa7f516a484e9f21fac34262214b3d9d761823 (patch)
tree925c10831c04d053b707857ffa785482316d4dcb /OpenSim/Grid/AssetInventoryServer/Extensions
parentAdded OpenSim asset frontend plugin. (diff)
downloadopensim-SC-16fa7f516a484e9f21fac34262214b3d9d761823.zip
opensim-SC-16fa7f516a484e9f21fac34262214b3d9d761823.tar.gz
opensim-SC-16fa7f516a484e9f21fac34262214b3d9d761823.tar.bz2
opensim-SC-16fa7f516a484e9f21fac34262214b3d9d761823.tar.xz
Converted to Linux newlines.
Diffstat (limited to 'OpenSim/Grid/AssetInventoryServer/Extensions')
-rw-r--r--OpenSim/Grid/AssetInventoryServer/Extensions/AuthorizeAll.cs156
-rw-r--r--OpenSim/Grid/AssetInventoryServer/Extensions/BrowseFrontend.cs250
-rw-r--r--OpenSim/Grid/AssetInventoryServer/Extensions/DBConnString.cs156
-rw-r--r--OpenSim/Grid/AssetInventoryServer/Extensions/NullAuthentication.cs136
-rw-r--r--OpenSim/Grid/AssetInventoryServer/Extensions/NullMetrics.cs248
-rw-r--r--OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimFrontend.cs430
-rw-r--r--OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimInventoryFrontend.cs1272
-rw-r--r--OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLInventory.cs1608
-rw-r--r--OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLStorage.cs622
-rw-r--r--OpenSim/Grid/AssetInventoryServer/Extensions/ReferenceFrontend.cs478
-rw-r--r--OpenSim/Grid/AssetInventoryServer/Extensions/SimpleInventory.cs1204
-rw-r--r--OpenSim/Grid/AssetInventoryServer/Extensions/SimpleStorage.cs520
-rw-r--r--OpenSim/Grid/AssetInventoryServer/Extensions/SimpleUtils.cs88
13 files changed, 3584 insertions, 3584 deletions
diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/AuthorizeAll.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/AuthorizeAll.cs
index a4a2226..10f3bdc 100644
--- a/OpenSim/Grid/AssetInventoryServer/Extensions/AuthorizeAll.cs
+++ b/OpenSim/Grid/AssetInventoryServer/Extensions/AuthorizeAll.cs
@@ -1,78 +1,78 @@
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
30using System; 30using System;
31using ExtensionLoader; 31using ExtensionLoader;
32using OpenMetaverse; 32using OpenMetaverse;
33 33
34namespace OpenSim.Grid.AssetInventoryServer.Extensions 34namespace OpenSim.Grid.AssetInventoryServer.Extensions
35{ 35{
36 public class AuthorizeAll : IExtension<AssetInventoryServer>, IAuthorizationProvider 36 public class AuthorizeAll : IExtension<AssetInventoryServer>, IAuthorizationProvider
37 { 37 {
38 AssetInventoryServer server; 38 AssetInventoryServer server;
39 39
40 public AuthorizeAll() 40 public AuthorizeAll()
41 { 41 {
42 } 42 }
43 43
44 public void Start(AssetInventoryServer server) 44 public void Start(AssetInventoryServer server)
45 { 45 {
46 this.server = server; 46 this.server = server;
47 } 47 }
48 48
49 public void Stop() 49 public void Stop()
50 { 50 {
51 } 51 }
52 52
53 public bool IsMetadataAuthorized(UUID authToken, UUID assetID) 53 public bool IsMetadataAuthorized(UUID authToken, UUID assetID)
54 { 54 {
55 return true; 55 return true;
56 } 56 }
57 57
58 public bool IsDataAuthorized(UUID authToken, UUID assetID) 58 public bool IsDataAuthorized(UUID authToken, UUID assetID)
59 { 59 {
60 return true; 60 return true;
61 } 61 }
62 62
63 public bool IsCreateAuthorized(UUID authToken) 63 public bool IsCreateAuthorized(UUID authToken)
64 { 64 {
65 return true; 65 return true;
66 } 66 }
67 67
68 public bool IsInventoryReadAuthorized(UUID authToken, Uri owner) 68 public bool IsInventoryReadAuthorized(UUID authToken, Uri owner)
69 { 69 {
70 return true; 70 return true;
71 } 71 }
72 72
73 public bool IsInventoryWriteAuthorized(UUID authToken, Uri owner) 73 public bool IsInventoryWriteAuthorized(UUID authToken, Uri owner)
74 { 74 {
75 return true; 75 return true;
76 } 76 }
77 } 77 }
78} 78}
diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/BrowseFrontend.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/BrowseFrontend.cs
index ba4c4e2..8c70144 100644
--- a/OpenSim/Grid/AssetInventoryServer/Extensions/BrowseFrontend.cs
+++ b/OpenSim/Grid/AssetInventoryServer/Extensions/BrowseFrontend.cs
@@ -1,125 +1,125 @@
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
30using System; 30using System;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Collections.Specialized; 32using System.Collections.Specialized;
33using System.Net; 33using System.Net;
34using System.Text; 34using System.Text;
35using System.Web; 35using System.Web;
36using ExtensionLoader; 36using ExtensionLoader;
37using OpenMetaverse; 37using OpenMetaverse;
38using HttpServer; 38using HttpServer;
39 39
40namespace OpenSim.Grid.AssetInventoryServer.Extensions 40namespace OpenSim.Grid.AssetInventoryServer.Extensions
41{ 41{
42 public class BrowseFrontend : IExtension<AssetInventoryServer> 42 public class BrowseFrontend : IExtension<AssetInventoryServer>
43 { 43 {
44 AssetInventoryServer server; 44 AssetInventoryServer server;
45 45
46 public BrowseFrontend() 46 public BrowseFrontend()
47 { 47 {
48 } 48 }
49 49
50 public void Start(AssetInventoryServer server) 50 public void Start(AssetInventoryServer server)
51 { 51 {
52 this.server = server; 52 this.server = server;
53 53
54 // Request for / or /?... 54 // Request for / or /?...
55 server.HttpServer.AddHandler("get", null, @"(^/$)|(^/\?.*)", BrowseRequestHandler); 55 server.HttpServer.AddHandler("get", null, @"(^/$)|(^/\?.*)", BrowseRequestHandler);
56 } 56 }
57 57
58 public void Stop() 58 public void Stop()
59 { 59 {
60 } 60 }
61 61
62 bool BrowseRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) 62 bool BrowseRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
63 { 63 {
64 const int ASSETS_PER_PAGE = 25; 64 const int ASSETS_PER_PAGE = 25;
65 const string HEADER = "<html><head><title>Asset Server</title></head><body>"; 65 const string HEADER = "<html><head><title>Asset Server</title></head><body>";
66 const string TABLE_HEADER = 66 const string TABLE_HEADER =
67 "<table><tr><th>Name</th><th>Description</th><th>Type</th><th>ID</th><th>Temporary</th><th>SHA-1</th></tr>"; 67 "<table><tr><th>Name</th><th>Description</th><th>Type</th><th>ID</th><th>Temporary</th><th>SHA-1</th></tr>";
68 const string TABLE_FOOTER = "</table>"; 68 const string TABLE_FOOTER = "</table>";
69 const string FOOTER = "</body></html>"; 69 const string FOOTER = "</body></html>";
70 70
71 UUID authToken = Utils.GetAuthToken(request); 71 UUID authToken = Utils.GetAuthToken(request);
72 72
73 StringBuilder html = new StringBuilder(); 73 StringBuilder html = new StringBuilder();
74 int start = 0; 74 int start = 0;
75 uint page = 0; 75 uint page = 0;
76 76
77 if (!String.IsNullOrEmpty(request.Uri.Query)) 77 if (!String.IsNullOrEmpty(request.Uri.Query))
78 { 78 {
79 NameValueCollection query = HttpUtility.ParseQueryString(request.Uri.Query); 79 NameValueCollection query = HttpUtility.ParseQueryString(request.Uri.Query);
80 if (!String.IsNullOrEmpty(query["page"]) && UInt32.TryParse(query["page"], out page)) 80 if (!String.IsNullOrEmpty(query["page"]) && UInt32.TryParse(query["page"], out page))
81 start = (int)page * ASSETS_PER_PAGE; 81 start = (int)page * ASSETS_PER_PAGE;
82 } 82 }
83 83
84 html.AppendLine(HEADER); 84 html.AppendLine(HEADER);
85 85
86 html.AppendLine("<p>"); 86 html.AppendLine("<p>");
87 if (page > 0) 87 if (page > 0)
88 html.AppendFormat("<a href=\"{0}?page={1}\">&lt; Previous Page</a> | ", request.Uri.AbsolutePath, page - 1); 88 html.AppendFormat("<a href=\"{0}?page={1}\">&lt; Previous Page</a> | ", request.Uri.AbsolutePath, page - 1);
89 html.AppendFormat("<a href=\"{0}?page={1}\">Next Page &gt;</a>", request.Uri.AbsolutePath, page + 1); 89 html.AppendFormat("<a href=\"{0}?page={1}\">Next Page &gt;</a>", request.Uri.AbsolutePath, page + 1);
90 html.AppendLine("</p>"); 90 html.AppendLine("</p>");
91 91
92 html.AppendLine(TABLE_HEADER); 92 html.AppendLine(TABLE_HEADER);
93 93
94 server.StorageProvider.ForEach( 94 server.StorageProvider.ForEach(
95 delegate(Metadata data) 95 delegate(Metadata data)
96 { 96 {
97 if (server.AuthorizationProvider.IsMetadataAuthorized(authToken, data.ID)) 97 if (server.AuthorizationProvider.IsMetadataAuthorized(authToken, data.ID))
98 { 98 {
99 html.AppendLine(String.Format( 99 html.AppendLine(String.Format(
100 "<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td><td>{5}</td></tr>", 100 "<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td><td>{5}</td></tr>",
101 data.Name, data.Description, data.ContentType, data.ID, data.Temporary, 101 data.Name, data.Description, data.ContentType, data.ID, data.Temporary,
102 BitConverter.ToString(data.SHA1).Replace("-", String.Empty))); 102 BitConverter.ToString(data.SHA1).Replace("-", String.Empty)));
103 } 103 }
104 else 104 else
105 { 105 {
106 html.AppendLine(String.Format( 106 html.AppendLine(String.Format(
107 "<tr><td>[Protected Asset]</td><td>&nbsp;</td><td>&nbsp;</td><td>{0}</td><td>{1}</td><td>&nbsp;</td></tr>", 107 "<tr><td>[Protected Asset]</td><td>&nbsp;</td><td>&nbsp;</td><td>{0}</td><td>{1}</td><td>&nbsp;</td></tr>",
108 data.ID, data.Temporary)); 108 data.ID, data.Temporary));
109 } 109 }
110 }, start, ASSETS_PER_PAGE 110 }, start, ASSETS_PER_PAGE
111 ); 111 );
112 112
113 html.AppendLine(TABLE_FOOTER); 113 html.AppendLine(TABLE_FOOTER);
114 114
115 html.AppendLine(FOOTER); 115 html.AppendLine(FOOTER);
116 116
117 byte[] responseData = System.Text.Encoding.UTF8.GetBytes(html.ToString()); 117 byte[] responseData = System.Text.Encoding.UTF8.GetBytes(html.ToString());
118 118
119 response.Status = HttpStatusCode.OK; 119 response.Status = HttpStatusCode.OK;
120 response.Body.Write(responseData, 0, responseData.Length); 120 response.Body.Write(responseData, 0, responseData.Length);
121 response.Body.Flush(); 121 response.Body.Flush();
122 return true; 122 return true;
123 } 123 }
124 } 124 }
125} 125}
diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/DBConnString.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/DBConnString.cs
index 58054d6..78761be 100644
--- a/OpenSim/Grid/AssetInventoryServer/Extensions/DBConnString.cs
+++ b/OpenSim/Grid/AssetInventoryServer/Extensions/DBConnString.cs
@@ -1,78 +1,78 @@
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
30using System; 30using System;
31using System.Xml; 31using System.Xml;
32using ExtensionLoader.Config; 32using ExtensionLoader.Config;
33using MySql.Data.MySqlClient; 33using MySql.Data.MySqlClient;
34 34
35namespace OpenSim.Grid.AssetInventoryServer.Extensions 35namespace OpenSim.Grid.AssetInventoryServer.Extensions
36{ 36{
37 public static class DBConnString 37 public static class DBConnString
38 { 38 {
39 private static string connectionString; 39 private static string connectionString;
40 40
41 /// <summary> 41 /// <summary>
42 /// Parses the MySQL connection string out of either the asset server 42 /// Parses the MySQL connection string out of either the asset server
43 /// .ini or a OpenSim-style .xml file and caches the result for future 43 /// .ini or a OpenSim-style .xml file and caches the result for future
44 /// requests 44 /// requests
45 /// </summary> 45 /// </summary>
46 public static string GetConnectionString(IniConfigSource configFile) 46 public static string GetConnectionString(IniConfigSource configFile)
47 { 47 {
48 if (connectionString == null) 48 if (connectionString == null)
49 { 49 {
50 // Try parsing from the ini file 50 // Try parsing from the ini file
51 try 51 try
52 { 52 {
53 // Load the extension list (and ordering) from our config file 53 // Load the extension list (and ordering) from our config file
54 IConfig extensionConfig = configFile.Configs["MySQL"]; 54 IConfig extensionConfig = configFile.Configs["MySQL"];
55 connectionString = extensionConfig.GetString("database_connect", null); 55 connectionString = extensionConfig.GetString("database_connect", null);
56 } 56 }
57 catch (Exception) { } 57 catch (Exception) { }
58 58
59 if (connectionString != null) 59 if (connectionString != null)
60 { 60 {
61 // Force MySQL's broken connection pooling off 61 // Force MySQL's broken connection pooling off
62 MySqlConnectionStringBuilder builder = new MySqlConnectionStringBuilder(connectionString); 62 MySqlConnectionStringBuilder builder = new MySqlConnectionStringBuilder(connectionString);
63 builder.Pooling = false; 63 builder.Pooling = false;
64 if (String.IsNullOrEmpty(builder.Database)) 64 if (String.IsNullOrEmpty(builder.Database))
65 Logger.Log.Error("No database selected in the connectionString: " + connectionString); 65 Logger.Log.Error("No database selected in the connectionString: " + connectionString);
66 connectionString = builder.ToString(); 66 connectionString = builder.ToString();
67 } 67 }
68 else 68 else
69 { 69 {
70 Logger.Log.Error("Database connection string is missing, check that the database_connect line is " + 70 Logger.Log.Error("Database connection string is missing, check that the database_connect line is " +
71 "correct and uncommented in AssetInventoryServer.ini"); 71 "correct and uncommented in AssetInventoryServer.ini");
72 } 72 }
73 } 73 }
74 74
75 return connectionString; 75 return connectionString;
76 } 76 }
77 } 77 }
78} 78}
diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/NullAuthentication.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/NullAuthentication.cs
index 796d80c..96e210a 100644
--- a/OpenSim/Grid/AssetInventoryServer/Extensions/NullAuthentication.cs
+++ b/OpenSim/Grid/AssetInventoryServer/Extensions/NullAuthentication.cs
@@ -1,68 +1,68 @@
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
30using System; 30using System;
31using ExtensionLoader; 31using ExtensionLoader;
32using OpenMetaverse; 32using OpenMetaverse;
33 33
34namespace OpenSim.Grid.AssetInventoryServer.Extensions 34namespace OpenSim.Grid.AssetInventoryServer.Extensions
35{ 35{
36 public class NullAuthentication : IExtension<AssetInventoryServer>, IAuthenticationProvider 36 public class NullAuthentication : IExtension<AssetInventoryServer>, IAuthenticationProvider
37 { 37 {
38 AssetInventoryServer server; 38 AssetInventoryServer server;
39 39
40 public NullAuthentication() 40 public NullAuthentication()
41 { 41 {
42 } 42 }
43 43
44 public void Start(AssetInventoryServer server) 44 public void Start(AssetInventoryServer server)
45 { 45 {
46 this.server = server; 46 this.server = server;
47 } 47 }
48 48
49 public void Stop() 49 public void Stop()
50 { 50 {
51 } 51 }
52 52
53 public void AddIdentifier(UUID authToken, Uri identifier) 53 public void AddIdentifier(UUID authToken, Uri identifier)
54 { 54 {
55 } 55 }
56 56
57 public bool RemoveIdentifier(UUID authToken) 57 public bool RemoveIdentifier(UUID authToken)
58 { 58 {
59 return true; 59 return true;
60 } 60 }
61 61
62 public bool TryGetIdentifier(UUID authToken, out Uri identifier) 62 public bool TryGetIdentifier(UUID authToken, out Uri identifier)
63 { 63 {
64 identifier = null; 64 identifier = null;
65 return true; 65 return true;
66 } 66 }
67 } 67 }
68} 68}
diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/NullMetrics.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/NullMetrics.cs
index c00203b..ba190c1 100644
--- a/OpenSim/Grid/AssetInventoryServer/Extensions/NullMetrics.cs
+++ b/OpenSim/Grid/AssetInventoryServer/Extensions/NullMetrics.cs
@@ -1,124 +1,124 @@
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
30using System; 30using System;
31using ExtensionLoader; 31using ExtensionLoader;
32using OpenMetaverse; 32using OpenMetaverse;
33 33
34namespace OpenSim.Grid.AssetInventoryServer.Extensions 34namespace OpenSim.Grid.AssetInventoryServer.Extensions
35{ 35{
36 public class NullMetrics : IExtension<AssetInventoryServer>, IMetricsProvider 36 public class NullMetrics : IExtension<AssetInventoryServer>, IMetricsProvider
37 { 37 {
38 AssetInventoryServer server; 38 AssetInventoryServer server;
39 39
40 public NullMetrics() 40 public NullMetrics()
41 { 41 {
42 } 42 }
43 43
44 public void Start(AssetInventoryServer server) 44 public void Start(AssetInventoryServer server)
45 { 45 {
46 this.server = server; 46 this.server = server;
47 } 47 }
48 48
49 public void Stop() 49 public void Stop()
50 { 50 {
51 } 51 }
52 52
53 public void LogAssetMetadataFetch(string extension, BackendResponse response, UUID assetID, DateTime time) 53 public void LogAssetMetadataFetch(string extension, BackendResponse response, UUID assetID, DateTime time)
54 { 54 {
55 Logger.Log.DebugFormat("[{0}] AssetMetadataFetch(): AssetID: {1}, Response: {2}", extension, assetID, response); 55 Logger.Log.DebugFormat("[{0}] AssetMetadataFetch(): AssetID: {1}, Response: {2}", extension, assetID, response);
56 } 56 }
57 57
58 public void LogAssetDataFetch(string extension, BackendResponse response, UUID assetID, int dataSize, DateTime time) 58 public void LogAssetDataFetch(string extension, BackendResponse response, UUID assetID, int dataSize, DateTime time)
59 { 59 {
60 Logger.Log.DebugFormat("[{0}] AssetDataFetch(): AssetID: {1}, DataSize: {2}, Response: {3}", extension, assetID, 60 Logger.Log.DebugFormat("[{0}] AssetDataFetch(): AssetID: {1}, DataSize: {2}, Response: {3}", extension, assetID,
61 dataSize, response); 61 dataSize, response);
62 } 62 }
63 63
64 public void LogAssetCreate(string extension, BackendResponse response, UUID assetID, int dataSize, DateTime time) 64 public void LogAssetCreate(string extension, BackendResponse response, UUID assetID, int dataSize, DateTime time)
65 { 65 {
66 Logger.Log.DebugFormat("[{0}] AssetCreate(): AssetID: {1}, DataSize: {2}, Response: {3}", extension, assetID, 66 Logger.Log.DebugFormat("[{0}] AssetCreate(): AssetID: {1}, DataSize: {2}, Response: {3}", extension, assetID,
67 dataSize, response); 67 dataSize, response);
68 } 68 }
69 69
70 public void LogInventoryFetch(string extension, BackendResponse response, Uri owner, UUID objID, bool folder, DateTime time) 70 public void LogInventoryFetch(string extension, BackendResponse response, Uri owner, UUID objID, bool folder, DateTime time)
71 { 71 {
72 Logger.Log.DebugFormat("[{0}] InventoryFetch(): ObjID: {1}, Folder: {2}, OwnerID: {3}, Response: {4}", extension, 72 Logger.Log.DebugFormat("[{0}] InventoryFetch(): ObjID: {1}, Folder: {2}, OwnerID: {3}, Response: {4}", extension,
73 objID, folder, owner, response); 73 objID, folder, owner, response);
74 } 74 }
75 75
76 public void LogInventoryFetchFolderContents(string extension, BackendResponse response, Uri owner, UUID folderID, DateTime time) 76 public void LogInventoryFetchFolderContents(string extension, BackendResponse response, Uri owner, UUID folderID, DateTime time)
77 { 77 {
78 Logger.Log.DebugFormat("[{0}] InventoryFetchFolderContents(): FolderID: {1}, OwnerID: {2}, Response: {3}", extension, 78 Logger.Log.DebugFormat("[{0}] InventoryFetchFolderContents(): FolderID: {1}, OwnerID: {2}, Response: {3}", extension,
79 folderID, owner, response); 79 folderID, owner, response);
80 } 80 }
81 81
82 public void LogInventoryFetchFolderList(string extension, BackendResponse response, Uri owner, DateTime time) 82 public void LogInventoryFetchFolderList(string extension, BackendResponse response, Uri owner, DateTime time)
83 { 83 {
84 Logger.Log.DebugFormat("[{0}] InventoryFetchFolderList(): OwnerID: {1}, Response: {2}", extension, 84 Logger.Log.DebugFormat("[{0}] InventoryFetchFolderList(): OwnerID: {1}, Response: {2}", extension,
85 owner, response); 85 owner, response);
86 } 86 }
87 87
88 public void LogInventoryFetchInventory(string extension, BackendResponse response, Uri owner, DateTime time) 88 public void LogInventoryFetchInventory(string extension, BackendResponse response, Uri owner, DateTime time)
89 { 89 {
90 Logger.Log.DebugFormat("[{0}] InventoryFetchInventory(): OwnerID: {1}, Response: {2}", extension, 90 Logger.Log.DebugFormat("[{0}] InventoryFetchInventory(): OwnerID: {1}, Response: {2}", extension,
91 owner, response); 91 owner, response);
92 } 92 }
93 93
94 public void LogInventoryFetchActiveGestures(string extension, BackendResponse response, Uri owner, DateTime time) 94 public void LogInventoryFetchActiveGestures(string extension, BackendResponse response, Uri owner, DateTime time)
95 { 95 {
96 Logger.Log.DebugFormat("[{0}] InventoryFetchActiveGestures(): OwnerID: {1}, Response: {2}", extension, 96 Logger.Log.DebugFormat("[{0}] InventoryFetchActiveGestures(): OwnerID: {1}, Response: {2}", extension,
97 owner, response); 97 owner, response);
98 } 98 }
99 99
100 public void LogInventoryCreate(string extension, BackendResponse response, Uri owner, bool folder, DateTime time) 100 public void LogInventoryCreate(string extension, BackendResponse response, Uri owner, bool folder, DateTime time)
101 { 101 {
102 Logger.Log.DebugFormat("[{0}] InventoryCreate(): OwnerID: {1}, Response: {2}", extension, 102 Logger.Log.DebugFormat("[{0}] InventoryCreate(): OwnerID: {1}, Response: {2}", extension,
103 owner, response); 103 owner, response);
104 } 104 }
105 105
106 public void LogInventoryCreateInventory(string extension, BackendResponse response, DateTime time) 106 public void LogInventoryCreateInventory(string extension, BackendResponse response, DateTime time)
107 { 107 {
108 Logger.Log.DebugFormat("[{0}] InventoryCreateInventory(): Response: {1}", extension, 108 Logger.Log.DebugFormat("[{0}] InventoryCreateInventory(): Response: {1}", extension,
109 response); 109 response);
110 } 110 }
111 111
112 public void LogInventoryDelete(string extension, BackendResponse response, Uri owner, UUID objID, bool folder, DateTime time) 112 public void LogInventoryDelete(string extension, BackendResponse response, Uri owner, UUID objID, bool folder, DateTime time)
113 { 113 {
114 Logger.Log.DebugFormat("[{0}] InventoryDelete(): OwnerID: {1}, Folder: {2}, Response: {3}", extension, 114 Logger.Log.DebugFormat("[{0}] InventoryDelete(): OwnerID: {1}, Folder: {2}, Response: {3}", extension,
115 owner, folder, response); 115 owner, folder, response);
116 } 116 }
117 117
118 public void LogInventoryPurgeFolder(string extension, BackendResponse response, Uri owner, UUID folderID, DateTime time) 118 public void LogInventoryPurgeFolder(string extension, BackendResponse response, Uri owner, UUID folderID, DateTime time)
119 { 119 {
120 Logger.Log.DebugFormat("[{0}] InventoryPurgeFolder(): OwnerID: {1}, FolderID: {2}, Response: {3}", extension, 120 Logger.Log.DebugFormat("[{0}] InventoryPurgeFolder(): OwnerID: {1}, FolderID: {2}, Response: {3}", extension,
121 owner, response); 121 owner, response);
122 } 122 }
123 } 123 }
124} 124}
diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimFrontend.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimFrontend.cs
index 4fff5e9..e34a235 100644
--- a/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimFrontend.cs
+++ b/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimFrontend.cs
@@ -1,215 +1,215 @@
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
30using System; 30using System;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Net; 32using System.Net;
33using System.IO; 33using System.IO;
34using System.Xml; 34using System.Xml;
35using ExtensionLoader; 35using ExtensionLoader;
36using OpenMetaverse; 36using OpenMetaverse;
37using HttpServer; 37using HttpServer;
38 38
39namespace OpenSim.Grid.AssetInventoryServer.Extensions 39namespace OpenSim.Grid.AssetInventoryServer.Extensions
40{ 40{
41 public class OpenSimFrontend : IExtension<AssetInventoryServer> 41 public class OpenSimFrontend : IExtension<AssetInventoryServer>
42 { 42 {
43 AssetInventoryServer server; 43 AssetInventoryServer server;
44 44
45 public OpenSimFrontend() 45 public OpenSimFrontend()
46 { 46 {
47 } 47 }
48 48
49 public void Start(AssetInventoryServer server) 49 public void Start(AssetInventoryServer server)
50 { 50 {
51 this.server = server; 51 this.server = server;
52 52
53 // Asset request 53 // Asset request
54 server.HttpServer.AddHandler("get", null, @"^/assets/", AssetRequestHandler); 54 server.HttpServer.AddHandler("get", null, @"^/assets/", AssetRequestHandler);
55 55
56 // Asset creation 56 // Asset creation
57 server.HttpServer.AddHandler("post", null, @"^/assets/", AssetPostHandler); 57 server.HttpServer.AddHandler("post", null, @"^/assets/", AssetPostHandler);
58 } 58 }
59 59
60 public void Stop() 60 public void Stop()
61 { 61 {
62 } 62 }
63 63
64 bool AssetRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) 64 bool AssetRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
65 { 65 {
66 UUID assetID; 66 UUID assetID;
67 // Split the URL up to get the asset ID out 67 // Split the URL up to get the asset ID out
68 string[] rawUrl = request.Uri.PathAndQuery.Split('/'); 68 string[] rawUrl = request.Uri.PathAndQuery.Split('/');
69 69
70 if (rawUrl.Length >= 3 && rawUrl[2].Length >= 36 && UUID.TryParse(rawUrl[2].Substring(0, 36), out assetID)) 70 if (rawUrl.Length >= 3 && rawUrl[2].Length >= 36 && UUID.TryParse(rawUrl[2].Substring(0, 36), out assetID))
71 { 71 {
72 Metadata metadata; 72 Metadata metadata;
73 byte[] assetData; 73 byte[] assetData;
74 BackendResponse dataResponse; 74 BackendResponse dataResponse;
75 75
76 if ((dataResponse = server.StorageProvider.TryFetchDataMetadata(assetID, out metadata, out assetData)) == BackendResponse.Success) 76 if ((dataResponse = server.StorageProvider.TryFetchDataMetadata(assetID, out metadata, out assetData)) == BackendResponse.Success)
77 { 77 {
78 MemoryStream stream = new MemoryStream(); 78 MemoryStream stream = new MemoryStream();
79 79
80 XmlWriterSettings settings = new XmlWriterSettings(); 80 XmlWriterSettings settings = new XmlWriterSettings();
81 settings.Indent = true; 81 settings.Indent = true;
82 XmlWriter writer = XmlWriter.Create(stream, settings); 82 XmlWriter writer = XmlWriter.Create(stream, settings);
83 83
84 writer.WriteStartDocument(); 84 writer.WriteStartDocument();
85 writer.WriteStartElement("AssetBase"); 85 writer.WriteStartElement("AssetBase");
86 writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance"); 86 writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
87 writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema"); 87 writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema");
88 writer.WriteStartElement("FullID"); 88 writer.WriteStartElement("FullID");
89 writer.WriteStartElement("Guid"); 89 writer.WriteStartElement("Guid");
90 writer.WriteString(assetID.ToString()); 90 writer.WriteString(assetID.ToString());
91 writer.WriteEndElement(); 91 writer.WriteEndElement();
92 writer.WriteEndElement(); 92 writer.WriteEndElement();
93 writer.WriteStartElement("ID"); 93 writer.WriteStartElement("ID");
94 writer.WriteString(assetID.ToString()); 94 writer.WriteString(assetID.ToString());
95 writer.WriteEndElement(); 95 writer.WriteEndElement();
96 writer.WriteStartElement("Data"); 96 writer.WriteStartElement("Data");
97 writer.WriteBase64(assetData, 0, assetData.Length); 97 writer.WriteBase64(assetData, 0, assetData.Length);
98 writer.WriteEndElement(); 98 writer.WriteEndElement();
99 writer.WriteStartElement("Type"); 99 writer.WriteStartElement("Type");
100 writer.WriteValue(Utils.ContentTypeToSLAssetType(metadata.ContentType)); 100 writer.WriteValue(Utils.ContentTypeToSLAssetType(metadata.ContentType));
101 writer.WriteEndElement(); 101 writer.WriteEndElement();
102 writer.WriteStartElement("Name"); 102 writer.WriteStartElement("Name");
103 writer.WriteString(metadata.Name); 103 writer.WriteString(metadata.Name);
104 writer.WriteEndElement(); 104 writer.WriteEndElement();
105 writer.WriteStartElement("Description"); 105 writer.WriteStartElement("Description");
106 writer.WriteString(metadata.Description); 106 writer.WriteString(metadata.Description);
107 writer.WriteEndElement(); 107 writer.WriteEndElement();
108 writer.WriteStartElement("Local"); 108 writer.WriteStartElement("Local");
109 writer.WriteValue(false); 109 writer.WriteValue(false);
110 writer.WriteEndElement(); 110 writer.WriteEndElement();
111 writer.WriteStartElement("Temporary"); 111 writer.WriteStartElement("Temporary");
112 writer.WriteValue(metadata.Temporary); 112 writer.WriteValue(metadata.Temporary);
113 writer.WriteEndElement(); 113 writer.WriteEndElement();
114 writer.WriteEndElement(); 114 writer.WriteEndElement();
115 writer.WriteEndDocument(); 115 writer.WriteEndDocument();
116 116
117 writer.Flush(); 117 writer.Flush();
118 byte[] buffer = stream.GetBuffer(); 118 byte[] buffer = stream.GetBuffer();
119 119
120 response.Status = HttpStatusCode.OK; 120 response.Status = HttpStatusCode.OK;
121 response.ContentType = "application/xml"; 121 response.ContentType = "application/xml";
122 response.ContentLength = stream.Length; 122 response.ContentLength = stream.Length;
123 response.Body.Write(buffer, 0, (int)stream.Length); 123 response.Body.Write(buffer, 0, (int)stream.Length);
124 response.Body.Flush(); 124 response.Body.Flush();
125 } 125 }
126 else 126 else
127 { 127 {
128 Logger.Log.WarnFormat("Failed to fetch asset data or metadata for {0}: {1}", assetID, dataResponse); 128 Logger.Log.WarnFormat("Failed to fetch asset data or metadata for {0}: {1}", assetID, dataResponse);
129 response.Status = HttpStatusCode.NotFound; 129 response.Status = HttpStatusCode.NotFound;
130 } 130 }
131 } 131 }
132 else 132 else
133 { 133 {
134 Logger.Log.Warn("Unrecognized OpenSim asset request: " + request.Uri.PathAndQuery); 134 Logger.Log.Warn("Unrecognized OpenSim asset request: " + request.Uri.PathAndQuery);
135 } 135 }
136 136
137 return true; 137 return true;
138 } 138 }
139 139
140 bool AssetPostHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) 140 bool AssetPostHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
141 { 141 {
142 byte[] assetData = null; 142 byte[] assetData = null;
143 Metadata metadata = new Metadata(); 143 Metadata metadata = new Metadata();
144 144
145 Logger.Log.Debug("Handling OpenSim asset upload"); 145 Logger.Log.Debug("Handling OpenSim asset upload");
146 146
147 try 147 try
148 { 148 {
149 using (XmlReader reader = XmlReader.Create(request.Body)) 149 using (XmlReader reader = XmlReader.Create(request.Body))
150 { 150 {
151 reader.MoveToContent(); 151 reader.MoveToContent();
152 reader.ReadStartElement("AssetBase"); 152 reader.ReadStartElement("AssetBase");
153 153
154 reader.ReadStartElement("FullID"); 154 reader.ReadStartElement("FullID");
155 UUID.TryParse(reader.ReadElementContentAsString("Guid", String.Empty), out metadata.ID); 155 UUID.TryParse(reader.ReadElementContentAsString("Guid", String.Empty), out metadata.ID);
156 reader.ReadEndElement(); 156 reader.ReadEndElement();
157 reader.ReadStartElement("ID"); 157 reader.ReadStartElement("ID");
158 reader.Skip(); 158 reader.Skip();
159 reader.ReadEndElement(); 159 reader.ReadEndElement();
160 160
161 // HACK: Broken on Mono. https://bugzilla.novell.com/show_bug.cgi?id=464229 161 // HACK: Broken on Mono. https://bugzilla.novell.com/show_bug.cgi?id=464229
162 //int readBytes = 0; 162 //int readBytes = 0;
163 //byte[] buffer = new byte[1024]; 163 //byte[] buffer = new byte[1024];
164 //MemoryStream stream = new MemoryStream(); 164 //MemoryStream stream = new MemoryStream();
165 //BinaryWriter writer = new BinaryWriter(stream); 165 //BinaryWriter writer = new BinaryWriter(stream);
166 //while ((readBytes = reader.ReadElementContentAsBase64(buffer, 0, buffer.Length)) > 0) 166 //while ((readBytes = reader.ReadElementContentAsBase64(buffer, 0, buffer.Length)) > 0)
167 // writer.Write(buffer, 0, readBytes); 167 // writer.Write(buffer, 0, readBytes);
168 //writer.Flush(); 168 //writer.Flush();
169 //assetData = stream.GetBuffer(); 169 //assetData = stream.GetBuffer();
170 //Array.Resize<byte>(ref assetData, (int)stream.Length); 170 //Array.Resize<byte>(ref assetData, (int)stream.Length);
171 171
172 assetData = Convert.FromBase64String(reader.ReadElementContentAsString()); 172 assetData = Convert.FromBase64String(reader.ReadElementContentAsString());
173 173
174 int type; 174 int type;
175 Int32.TryParse(reader.ReadElementContentAsString("Type", String.Empty), out type); 175 Int32.TryParse(reader.ReadElementContentAsString("Type", String.Empty), out type);
176 metadata.ContentType = Utils.SLAssetTypeToContentType(type); 176 metadata.ContentType = Utils.SLAssetTypeToContentType(type);
177 metadata.Name = reader.ReadElementContentAsString("Name", String.Empty); 177 metadata.Name = reader.ReadElementContentAsString("Name", String.Empty);
178 metadata.Description = reader.ReadElementContentAsString("Description", String.Empty); 178 metadata.Description = reader.ReadElementContentAsString("Description", String.Empty);
179 Boolean.TryParse(reader.ReadElementContentAsString("Local", String.Empty), out metadata.Temporary); 179 Boolean.TryParse(reader.ReadElementContentAsString("Local", String.Empty), out metadata.Temporary);
180 Boolean.TryParse(reader.ReadElementContentAsString("Temporary", String.Empty), out metadata.Temporary); 180 Boolean.TryParse(reader.ReadElementContentAsString("Temporary", String.Empty), out metadata.Temporary);
181 181
182 reader.ReadEndElement(); 182 reader.ReadEndElement();
183 } 183 }
184 184
185 if (assetData != null && assetData.Length > 0) 185 if (assetData != null && assetData.Length > 0)
186 { 186 {
187 metadata.SHA1 = OpenMetaverse.Utils.SHA1(assetData); 187 metadata.SHA1 = OpenMetaverse.Utils.SHA1(assetData);
188 metadata.CreationDate = DateTime.Now; 188 metadata.CreationDate = DateTime.Now;
189 189
190 BackendResponse storageResponse = server.StorageProvider.TryCreateAsset(metadata, assetData); 190 BackendResponse storageResponse = server.StorageProvider.TryCreateAsset(metadata, assetData);
191 191
192 if (storageResponse == BackendResponse.Success) 192 if (storageResponse == BackendResponse.Success)
193 response.Status = HttpStatusCode.Created; 193 response.Status = HttpStatusCode.Created;
194 else if (storageResponse == BackendResponse.NotFound) 194 else if (storageResponse == BackendResponse.NotFound)
195 response.Status = HttpStatusCode.NotFound; 195 response.Status = HttpStatusCode.NotFound;
196 else 196 else
197 response.Status = HttpStatusCode.InternalServerError; 197 response.Status = HttpStatusCode.InternalServerError;
198 } 198 }
199 else 199 else
200 { 200 {
201 Logger.Log.Warn("AssetPostHandler called with no asset data"); 201 Logger.Log.Warn("AssetPostHandler called with no asset data");
202 response.Status = HttpStatusCode.BadRequest; 202 response.Status = HttpStatusCode.BadRequest;
203 } 203 }
204 } 204 }
205 catch (Exception ex) 205 catch (Exception ex)
206 { 206 {
207 Logger.Log.Warn("Failed to parse POST data (expecting AssetBase): " + ex.Message); 207 Logger.Log.Warn("Failed to parse POST data (expecting AssetBase): " + ex.Message);
208 response.Status = HttpStatusCode.BadRequest; 208 response.Status = HttpStatusCode.BadRequest;
209 } 209 }
210 210
211 Logger.Log.Debug("Finished handling OpenSim asset upload, Status: " + response.Status.ToString()); 211 Logger.Log.Debug("Finished handling OpenSim asset upload, Status: " + response.Status.ToString());
212 return true; 212 return true;
213 } 213 }
214 } 214 }
215} 215}
diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimInventoryFrontend.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimInventoryFrontend.cs
index a0ebba5..340e00c 100644
--- a/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimInventoryFrontend.cs
+++ b/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimInventoryFrontend.cs
@@ -1,636 +1,636 @@
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
30using System; 30using System;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Net; 32using System.Net;
33using System.IO; 33using System.IO;
34using System.Xml; 34using System.Xml;
35using ExtensionLoader; 35using ExtensionLoader;
36using OpenMetaverse; 36using OpenMetaverse;
37using OpenMetaverse.StructuredData; 37using OpenMetaverse.StructuredData;
38using HttpServer; 38using HttpServer;
39 39
40namespace OpenSim.Grid.AssetInventoryServer.Extensions 40namespace OpenSim.Grid.AssetInventoryServer.Extensions
41{ 41{
42 public class OpenSimInventoryFrontend : IExtension<AssetInventoryServer> 42 public class OpenSimInventoryFrontend : IExtension<AssetInventoryServer>
43 { 43 {
44 AssetInventoryServer server; 44 AssetInventoryServer server;
45 Utils.InventoryItemSerializer itemSerializer = new Utils.InventoryItemSerializer(); 45 Utils.InventoryItemSerializer itemSerializer = new Utils.InventoryItemSerializer();
46 Utils.InventoryFolderSerializer folderSerializer = new Utils.InventoryFolderSerializer(); 46 Utils.InventoryFolderSerializer folderSerializer = new Utils.InventoryFolderSerializer();
47 Utils.InventoryCollectionSerializer collectionSerializer = new Utils.InventoryCollectionSerializer(); 47 Utils.InventoryCollectionSerializer collectionSerializer = new Utils.InventoryCollectionSerializer();
48 48
49 public OpenSimInventoryFrontend() 49 public OpenSimInventoryFrontend()
50 { 50 {
51 } 51 }
52 52
53 public void Start(AssetInventoryServer server) 53 public void Start(AssetInventoryServer server)
54 { 54 {
55 this.server = server; 55 this.server = server;
56 56
57 server.HttpServer.AddHandler("post", null, @"^/GetInventory/", GetInventoryHandler); 57 server.HttpServer.AddHandler("post", null, @"^/GetInventory/", GetInventoryHandler);
58 server.HttpServer.AddHandler("post", null, @"^/CreateInventory/", CreateInventoryHandler); 58 server.HttpServer.AddHandler("post", null, @"^/CreateInventory/", CreateInventoryHandler);
59 server.HttpServer.AddHandler("post", null, @"^/NewFolder/", NewFolderHandler); 59 server.HttpServer.AddHandler("post", null, @"^/NewFolder/", NewFolderHandler);
60 server.HttpServer.AddHandler("post", null, @"^/UpdateFolder/", UpdateFolderHandler); 60 server.HttpServer.AddHandler("post", null, @"^/UpdateFolder/", UpdateFolderHandler);
61 server.HttpServer.AddHandler("post", null, @"^/MoveFolder/", MoveFolderHandler); 61 server.HttpServer.AddHandler("post", null, @"^/MoveFolder/", MoveFolderHandler);
62 server.HttpServer.AddHandler("post", null, @"^/PurgeFolder/", PurgeFolderHandler); 62 server.HttpServer.AddHandler("post", null, @"^/PurgeFolder/", PurgeFolderHandler);
63 server.HttpServer.AddHandler("post", null, @"^/NewItem/", NewItemHandler); 63 server.HttpServer.AddHandler("post", null, @"^/NewItem/", NewItemHandler);
64 server.HttpServer.AddHandler("post", null, @"^/DeleteItem/", DeleteItemHandler); 64 server.HttpServer.AddHandler("post", null, @"^/DeleteItem/", DeleteItemHandler);
65 server.HttpServer.AddHandler("post", null, @"^/RootFolders/", RootFoldersHandler); 65 server.HttpServer.AddHandler("post", null, @"^/RootFolders/", RootFoldersHandler);
66 server.HttpServer.AddHandler("post", null, @"^/ActiveGestures/", ActiveGesturesHandler); 66 server.HttpServer.AddHandler("post", null, @"^/ActiveGestures/", ActiveGesturesHandler);
67 } 67 }
68 68
69 public void Stop() 69 public void Stop()
70 { 70 {
71 } 71 }
72 72
73 bool GetInventoryHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) 73 bool GetInventoryHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
74 { 74 {
75 UUID sessionID, agentID; 75 UUID sessionID, agentID;
76 UUID ownerID = DeserializeUUID(request.Body, out agentID, out sessionID); 76 UUID ownerID = DeserializeUUID(request.Body, out agentID, out sessionID);
77 77
78 if (ownerID != UUID.Zero) 78 if (ownerID != UUID.Zero)
79 { 79 {
80 Logger.Log.Warn("GetInventory is not scalable on some inventory backends, avoid calling it wherever possible"); 80 Logger.Log.Warn("GetInventory is not scalable on some inventory backends, avoid calling it wherever possible");
81 81
82 Uri owner = Utils.GetOpenSimUri(ownerID); 82 Uri owner = Utils.GetOpenSimUri(ownerID);
83 InventoryCollection inventory; 83 InventoryCollection inventory;
84 BackendResponse storageResponse = server.InventoryProvider.TryFetchInventory(owner, out inventory); 84 BackendResponse storageResponse = server.InventoryProvider.TryFetchInventory(owner, out inventory);
85 85
86 if (storageResponse == BackendResponse.Success) 86 if (storageResponse == BackendResponse.Success)
87 { 87 {
88 collectionSerializer.Serialize(response.Body, inventory); 88 collectionSerializer.Serialize(response.Body, inventory);
89 response.Body.Flush(); 89 response.Body.Flush();
90 } 90 }
91 else if (storageResponse == BackendResponse.NotFound) 91 else if (storageResponse == BackendResponse.NotFound)
92 { 92 {
93 // Return an empty inventory set to mimic OpenSim.Grid.InventoryServer.exe 93 // Return an empty inventory set to mimic OpenSim.Grid.InventoryServer.exe
94 inventory = new InventoryCollection(); 94 inventory = new InventoryCollection();
95 inventory.UserID = ownerID; 95 inventory.UserID = ownerID;
96 inventory.Folders = new Dictionary<UUID, InventoryFolder>(); 96 inventory.Folders = new Dictionary<UUID, InventoryFolder>();
97 inventory.Items = new Dictionary<UUID, InventoryItem>(); 97 inventory.Items = new Dictionary<UUID, InventoryItem>();
98 collectionSerializer.Serialize(response.Body, inventory); 98 collectionSerializer.Serialize(response.Body, inventory);
99 response.Body.Flush(); 99 response.Body.Flush();
100 } 100 }
101 else 101 else
102 { 102 {
103 response.Status = HttpStatusCode.InternalServerError; 103 response.Status = HttpStatusCode.InternalServerError;
104 } 104 }
105 } 105 }
106 else 106 else
107 { 107 {
108 response.Status = HttpStatusCode.BadRequest; 108 response.Status = HttpStatusCode.BadRequest;
109 } 109 }
110 110
111 return true; 111 return true;
112 } 112 }
113 113
114 bool CreateInventoryHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) 114 bool CreateInventoryHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
115 { 115 {
116 UUID ownerID = DeserializeUUID(request.Body); 116 UUID ownerID = DeserializeUUID(request.Body);
117 117
118 if (ownerID != UUID.Zero) 118 if (ownerID != UUID.Zero)
119 { 119 {
120 Uri owner = Utils.GetOpenSimUri(ownerID); 120 Uri owner = Utils.GetOpenSimUri(ownerID);
121 Logger.Log.DebugFormat("Created URI {0} for inventory creation", owner); 121 Logger.Log.DebugFormat("Created URI {0} for inventory creation", owner);
122 122
123 InventoryFolder rootFolder = new InventoryFolder("My Inventory", ownerID, UUID.Zero, (short)AssetType.Folder); 123 InventoryFolder rootFolder = new InventoryFolder("My Inventory", ownerID, UUID.Zero, (short)AssetType.Folder);
124 BackendResponse storageResponse = server.InventoryProvider.TryCreateInventory(owner, rootFolder); 124 BackendResponse storageResponse = server.InventoryProvider.TryCreateInventory(owner, rootFolder);
125 if (storageResponse == BackendResponse.Success) 125 if (storageResponse == BackendResponse.Success)
126 { 126 {
127 CreateFolder("Animations", ownerID, rootFolder.ID, AssetType.Animation); 127 CreateFolder("Animations", ownerID, rootFolder.ID, AssetType.Animation);
128 CreateFolder("Body Parts", ownerID, rootFolder.ID, AssetType.Bodypart); 128 CreateFolder("Body Parts", ownerID, rootFolder.ID, AssetType.Bodypart);
129 CreateFolder("Calling Cards", ownerID, rootFolder.ID, AssetType.CallingCard); 129 CreateFolder("Calling Cards", ownerID, rootFolder.ID, AssetType.CallingCard);
130 CreateFolder("Clothing", ownerID, rootFolder.ID, AssetType.Clothing); 130 CreateFolder("Clothing", ownerID, rootFolder.ID, AssetType.Clothing);
131 CreateFolder("Gestures", ownerID, rootFolder.ID, AssetType.Gesture); 131 CreateFolder("Gestures", ownerID, rootFolder.ID, AssetType.Gesture);
132 CreateFolder("Landmarks", ownerID, rootFolder.ID, AssetType.Landmark); 132 CreateFolder("Landmarks", ownerID, rootFolder.ID, AssetType.Landmark);
133 CreateFolder("Lost and Found", ownerID, rootFolder.ID, AssetType.LostAndFoundFolder); 133 CreateFolder("Lost and Found", ownerID, rootFolder.ID, AssetType.LostAndFoundFolder);
134 CreateFolder("Notecards", ownerID, rootFolder.ID, AssetType.Notecard); 134 CreateFolder("Notecards", ownerID, rootFolder.ID, AssetType.Notecard);
135 CreateFolder("Objects", ownerID, rootFolder.ID, AssetType.Object); 135 CreateFolder("Objects", ownerID, rootFolder.ID, AssetType.Object);
136 CreateFolder("Photo Album", ownerID, rootFolder.ID, AssetType.SnapshotFolder); 136 CreateFolder("Photo Album", ownerID, rootFolder.ID, AssetType.SnapshotFolder);
137 CreateFolder("Scripts", ownerID, rootFolder.ID, AssetType.LSLText); 137 CreateFolder("Scripts", ownerID, rootFolder.ID, AssetType.LSLText);
138 CreateFolder("Sounds", ownerID, rootFolder.ID, AssetType.Sound); 138 CreateFolder("Sounds", ownerID, rootFolder.ID, AssetType.Sound);
139 CreateFolder("Textures", ownerID, rootFolder.ID, AssetType.Texture); 139 CreateFolder("Textures", ownerID, rootFolder.ID, AssetType.Texture);
140 CreateFolder("Trash", ownerID, rootFolder.ID, AssetType.TrashFolder); 140 CreateFolder("Trash", ownerID, rootFolder.ID, AssetType.TrashFolder);
141 141
142 SerializeBool(response.Body, true); 142 SerializeBool(response.Body, true);
143 return true; 143 return true;
144 } 144 }
145 } 145 }
146 146
147 SerializeBool(response.Body, false); 147 SerializeBool(response.Body, false);
148 return true; 148 return true;
149 } 149 }
150 150
151 bool NewFolderHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) 151 bool NewFolderHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
152 { 152 {
153 UUID agentID, sessionID; 153 UUID agentID, sessionID;
154 InventoryFolder folder = DeserializeFolder(request.Body, out agentID, out sessionID); 154 InventoryFolder folder = DeserializeFolder(request.Body, out agentID, out sessionID);
155 155
156 if (folder != null) 156 if (folder != null)
157 { 157 {
158 Uri owner = Utils.GetOpenSimUri(folder.Owner); 158 Uri owner = Utils.GetOpenSimUri(folder.Owner);
159 159
160 // Some calls that are moving or updating a folder instead of creating a new one 160 // Some calls that are moving or updating a folder instead of creating a new one
161 // will pass in an InventoryFolder without the name set. If this is the case we 161 // will pass in an InventoryFolder without the name set. If this is the case we
162 // need to look up the name first 162 // need to look up the name first
163 if (String.IsNullOrEmpty(folder.Name)) 163 if (String.IsNullOrEmpty(folder.Name))
164 { 164 {
165 InventoryFolder oldFolder; 165 InventoryFolder oldFolder;
166 if (server.InventoryProvider.TryFetchFolder(owner, folder.ID, out oldFolder) == BackendResponse.Success) 166 if (server.InventoryProvider.TryFetchFolder(owner, folder.ID, out oldFolder) == BackendResponse.Success)
167 folder.Name = oldFolder.Name; 167 folder.Name = oldFolder.Name;
168 } 168 }
169 169
170 BackendResponse storageResponse = server.InventoryProvider.TryCreateFolder(owner, folder); 170 BackendResponse storageResponse = server.InventoryProvider.TryCreateFolder(owner, folder);
171 171
172 if (storageResponse == BackendResponse.Success) 172 if (storageResponse == BackendResponse.Success)
173 { 173 {
174 SerializeBool(response.Body, true); 174 SerializeBool(response.Body, true);
175 return true; 175 return true;
176 } 176 }
177 } 177 }
178 178
179 SerializeBool(response.Body, false); 179 SerializeBool(response.Body, false);
180 return true; 180 return true;
181 } 181 }
182 182
183 bool UpdateFolderHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) 183 bool UpdateFolderHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
184 { 184 {
185 return NewFolderHandler(client, request, response); 185 return NewFolderHandler(client, request, response);
186 } 186 }
187 187
188 bool MoveFolderHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) 188 bool MoveFolderHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
189 { 189 {
190 return NewFolderHandler(client, request, response); 190 return NewFolderHandler(client, request, response);
191 } 191 }
192 192
193 bool PurgeFolderHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) 193 bool PurgeFolderHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
194 { 194 {
195 UUID agentID, sessionID; 195 UUID agentID, sessionID;
196 InventoryFolder folder = DeserializeFolder(request.Body, out agentID, out sessionID); 196 InventoryFolder folder = DeserializeFolder(request.Body, out agentID, out sessionID);
197 197
198 if (folder != null) 198 if (folder != null)
199 { 199 {
200 Uri owner = Utils.GetOpenSimUri(folder.Owner); 200 Uri owner = Utils.GetOpenSimUri(folder.Owner);
201 BackendResponse storageResponse = server.InventoryProvider.TryPurgeFolder(owner, folder.ID); 201 BackendResponse storageResponse = server.InventoryProvider.TryPurgeFolder(owner, folder.ID);
202 202
203 if (storageResponse == BackendResponse.Success) 203 if (storageResponse == BackendResponse.Success)
204 { 204 {
205 SerializeBool(response.Body, true); 205 SerializeBool(response.Body, true);
206 return true; 206 return true;
207 } 207 }
208 } 208 }
209 209
210 SerializeBool(response.Body, false); 210 SerializeBool(response.Body, false);
211 return true; 211 return true;
212 } 212 }
213 213
214 bool NewItemHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) 214 bool NewItemHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
215 { 215 {
216 UUID agentID, sessionID; 216 UUID agentID, sessionID;
217 InventoryItem item = DeserializeItem(request.Body, out agentID, out sessionID); 217 InventoryItem item = DeserializeItem(request.Body, out agentID, out sessionID);
218 218
219 if (item != null) 219 if (item != null)
220 { 220 {
221 Uri owner = Utils.GetOpenSimUri(agentID); 221 Uri owner = Utils.GetOpenSimUri(agentID);
222 BackendResponse storageResponse = server.InventoryProvider.TryCreateItem(owner, item); 222 BackendResponse storageResponse = server.InventoryProvider.TryCreateItem(owner, item);
223 223
224 if (storageResponse == BackendResponse.Success) 224 if (storageResponse == BackendResponse.Success)
225 { 225 {
226 SerializeBool(response.Body, true); 226 SerializeBool(response.Body, true);
227 return true; 227 return true;
228 } 228 }
229 } 229 }
230 230
231 SerializeBool(response.Body, false); 231 SerializeBool(response.Body, false);
232 return true; 232 return true;
233 } 233 }
234 234
235 bool DeleteItemHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) 235 bool DeleteItemHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
236 { 236 {
237 UUID agentID, sessionID; 237 UUID agentID, sessionID;
238 InventoryItem item = DeserializeItem(request.Body, out agentID, out sessionID); 238 InventoryItem item = DeserializeItem(request.Body, out agentID, out sessionID);
239 239
240 if (item != null) 240 if (item != null)
241 { 241 {
242 Uri owner = Utils.GetOpenSimUri(item.Owner); 242 Uri owner = Utils.GetOpenSimUri(item.Owner);
243 BackendResponse storageResponse = server.InventoryProvider.TryDeleteItem(owner, item.ID); 243 BackendResponse storageResponse = server.InventoryProvider.TryDeleteItem(owner, item.ID);
244 244
245 if (storageResponse == BackendResponse.Success) 245 if (storageResponse == BackendResponse.Success)
246 { 246 {
247 SerializeBool(response.Body, true); 247 SerializeBool(response.Body, true);
248 return true; 248 return true;
249 } 249 }
250 } 250 }
251 251
252 SerializeBool(response.Body, false); 252 SerializeBool(response.Body, false);
253 return true; 253 return true;
254 } 254 }
255 255
256 bool RootFoldersHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) 256 bool RootFoldersHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
257 { 257 {
258 UUID ownerID = DeserializeUUID(request.Body); 258 UUID ownerID = DeserializeUUID(request.Body);
259 259
260 if (ownerID != UUID.Zero) 260 if (ownerID != UUID.Zero)
261 { 261 {
262 Uri owner = Utils.GetOpenSimUri(ownerID); 262 Uri owner = Utils.GetOpenSimUri(ownerID);
263 List<InventoryFolder> skeleton; 263 List<InventoryFolder> skeleton;
264 BackendResponse storageResponse = server.InventoryProvider.TryFetchFolderList(owner, out skeleton); 264 BackendResponse storageResponse = server.InventoryProvider.TryFetchFolderList(owner, out skeleton);
265 265
266 if (storageResponse == BackendResponse.Success) 266 if (storageResponse == BackendResponse.Success)
267 { 267 {
268 SerializeFolderList(response.Body, skeleton); 268 SerializeFolderList(response.Body, skeleton);
269 } 269 }
270 else if (storageResponse == BackendResponse.NotFound) 270 else if (storageResponse == BackendResponse.NotFound)
271 { 271 {
272 // Return an empty set of inventory so the requester knows that 272 // Return an empty set of inventory so the requester knows that
273 // an inventory needs to be created for this agent 273 // an inventory needs to be created for this agent
274 SerializeFolderList(response.Body, new List<InventoryFolder>(0)); 274 SerializeFolderList(response.Body, new List<InventoryFolder>(0));
275 } 275 }
276 else 276 else
277 { 277 {
278 response.Status = HttpStatusCode.InternalServerError; 278 response.Status = HttpStatusCode.InternalServerError;
279 } 279 }
280 } 280 }
281 else 281 else
282 { 282 {
283 response.Status = HttpStatusCode.BadRequest; 283 response.Status = HttpStatusCode.BadRequest;
284 } 284 }
285 285
286 return true; 286 return true;
287 } 287 }
288 288
289 bool ActiveGesturesHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) 289 bool ActiveGesturesHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
290 { 290 {
291 UUID ownerID = DeserializeUUID(request.Body); 291 UUID ownerID = DeserializeUUID(request.Body);
292 292
293 if (ownerID != UUID.Zero) 293 if (ownerID != UUID.Zero)
294 { 294 {
295 Uri owner = Utils.GetOpenSimUri(ownerID); 295 Uri owner = Utils.GetOpenSimUri(ownerID);
296 List<InventoryItem> gestures; 296 List<InventoryItem> gestures;
297 BackendResponse storageResponse = server.InventoryProvider.TryFetchActiveGestures(owner, out gestures); 297 BackendResponse storageResponse = server.InventoryProvider.TryFetchActiveGestures(owner, out gestures);
298 298
299 if (storageResponse == BackendResponse.Success) 299 if (storageResponse == BackendResponse.Success)
300 { 300 {
301 SerializeItemList(response.Body, gestures); 301 SerializeItemList(response.Body, gestures);
302 } 302 }
303 else if (storageResponse == BackendResponse.NotFound) 303 else if (storageResponse == BackendResponse.NotFound)
304 { 304 {
305 // Return an empty set of gestures to match OpenSim.Grid.InventoryServer.exe behavior 305 // Return an empty set of gestures to match OpenSim.Grid.InventoryServer.exe behavior
306 SerializeItemList(response.Body, new List<InventoryItem>(0)); 306 SerializeItemList(response.Body, new List<InventoryItem>(0));
307 } 307 }
308 else 308 else
309 { 309 {
310 response.Status = HttpStatusCode.InternalServerError; 310 response.Status = HttpStatusCode.InternalServerError;
311 } 311 }
312 } 312 }
313 else 313 else
314 { 314 {
315 response.Status = HttpStatusCode.BadRequest; 315 response.Status = HttpStatusCode.BadRequest;
316 } 316 }
317 317
318 return true; 318 return true;
319 } 319 }
320 320
321 BackendResponse CreateFolder(string name, UUID ownerID, UUID parentID, AssetType assetType) 321 BackendResponse CreateFolder(string name, UUID ownerID, UUID parentID, AssetType assetType)
322 { 322 {
323 InventoryFolder folder = new InventoryFolder(name, ownerID, parentID, (short)assetType); 323 InventoryFolder folder = new InventoryFolder(name, ownerID, parentID, (short)assetType);
324 Uri owner = Utils.GetOpenSimUri(ownerID); 324 Uri owner = Utils.GetOpenSimUri(ownerID);
325 return server.InventoryProvider.TryCreateFolder(owner, folder); 325 return server.InventoryProvider.TryCreateFolder(owner, folder);
326 } 326 }
327 327
328 UUID DeserializeUUID(Stream stream) 328 UUID DeserializeUUID(Stream stream)
329 { 329 {
330 UUID id = UUID.Zero; 330 UUID id = UUID.Zero;
331 331
332 try 332 try
333 { 333 {
334 using (XmlReader reader = XmlReader.Create(stream)) 334 using (XmlReader reader = XmlReader.Create(stream))
335 { 335 {
336 reader.MoveToContent(); 336 reader.MoveToContent();
337 UUID.TryParse(reader.ReadElementContentAsString("guid", String.Empty), out id); 337 UUID.TryParse(reader.ReadElementContentAsString("guid", String.Empty), out id);
338 } 338 }
339 } 339 }
340 catch (Exception ex) 340 catch (Exception ex)
341 { 341 {
342 Logger.Log.Warn("Failed to parse POST data (expecting guid): " + ex.Message); 342 Logger.Log.Warn("Failed to parse POST data (expecting guid): " + ex.Message);
343 } 343 }
344 344
345 return id; 345 return id;
346 } 346 }
347 347
348 UUID DeserializeUUID(Stream stream, out UUID agentID, out UUID sessionID) 348 UUID DeserializeUUID(Stream stream, out UUID agentID, out UUID sessionID)
349 { 349 {
350 UUID id; 350 UUID id;
351 351
352 try 352 try
353 { 353 {
354 using (XmlReader reader = XmlReader.Create(stream)) 354 using (XmlReader reader = XmlReader.Create(stream))
355 { 355 {
356 reader.MoveToContent(); 356 reader.MoveToContent();
357 reader.ReadStartElement("RestSessionObjectOfGuid"); 357 reader.ReadStartElement("RestSessionObjectOfGuid");
358 UUID.TryParse(reader.ReadElementContentAsString("SessionID", String.Empty), out sessionID); 358 UUID.TryParse(reader.ReadElementContentAsString("SessionID", String.Empty), out sessionID);
359 UUID.TryParse(reader.ReadElementContentAsString("AvatarID", String.Empty), out agentID); 359 UUID.TryParse(reader.ReadElementContentAsString("AvatarID", String.Empty), out agentID);
360 UUID.TryParse(reader.ReadElementContentAsString("Body", String.Empty), out id); 360 UUID.TryParse(reader.ReadElementContentAsString("Body", String.Empty), out id);
361 reader.ReadEndElement(); 361 reader.ReadEndElement();
362 } 362 }
363 } 363 }
364 catch (Exception ex) 364 catch (Exception ex)
365 { 365 {
366 Logger.Log.Warn("Failed to parse GetInventory POST data: " + ex.Message); 366 Logger.Log.Warn("Failed to parse GetInventory POST data: " + ex.Message);
367 agentID = UUID.Zero; 367 agentID = UUID.Zero;
368 sessionID = UUID.Zero; 368 sessionID = UUID.Zero;
369 return UUID.Zero; 369 return UUID.Zero;
370 } 370 }
371 371
372 return id; 372 return id;
373 } 373 }
374 374
375 InventoryFolder DeserializeFolder(Stream stream, out UUID agentID, out UUID sessionID) 375 InventoryFolder DeserializeFolder(Stream stream, out UUID agentID, out UUID sessionID)
376 { 376 {
377 InventoryFolder folder = new InventoryFolder(); 377 InventoryFolder folder = new InventoryFolder();
378 378
379 try 379 try
380 { 380 {
381 using (XmlReader reader = XmlReader.Create(stream)) 381 using (XmlReader reader = XmlReader.Create(stream))
382 { 382 {
383 reader.MoveToContent(); 383 reader.MoveToContent();
384 reader.ReadStartElement("RestSessionObjectOfInventoryFolderBase"); 384 reader.ReadStartElement("RestSessionObjectOfInventoryFolderBase");
385 UUID.TryParse(reader.ReadElementContentAsString("SessionID", String.Empty), out sessionID); 385 UUID.TryParse(reader.ReadElementContentAsString("SessionID", String.Empty), out sessionID);
386 UUID.TryParse(reader.ReadElementContentAsString("AvatarID", String.Empty), out agentID); 386 UUID.TryParse(reader.ReadElementContentAsString("AvatarID", String.Empty), out agentID);
387 reader.ReadStartElement("Body"); 387 reader.ReadStartElement("Body");
388 if (reader.Name == "Name") 388 if (reader.Name == "Name")
389 folder.Name = reader.ReadElementContentAsString("Name", String.Empty); 389 folder.Name = reader.ReadElementContentAsString("Name", String.Empty);
390 else 390 else
391 folder.Name = String.Empty; 391 folder.Name = String.Empty;
392 ReadUUID(reader, "Owner", out folder.Owner); 392 ReadUUID(reader, "Owner", out folder.Owner);
393 ReadUUID(reader, "ParentID", out folder.ParentID); 393 ReadUUID(reader, "ParentID", out folder.ParentID);
394 ReadUUID(reader, "ID", out folder.ID); 394 ReadUUID(reader, "ID", out folder.ID);
395 Int16.TryParse(reader.ReadElementContentAsString("Type", String.Empty), out folder.Type); 395 Int16.TryParse(reader.ReadElementContentAsString("Type", String.Empty), out folder.Type);
396 UInt16.TryParse(reader.ReadElementContentAsString("Version", String.Empty), out folder.Version); 396 UInt16.TryParse(reader.ReadElementContentAsString("Version", String.Empty), out folder.Version);
397 reader.ReadEndElement(); 397 reader.ReadEndElement();
398 reader.ReadEndElement(); 398 reader.ReadEndElement();
399 } 399 }
400 } 400 }
401 catch (Exception ex) 401 catch (Exception ex)
402 { 402 {
403 Logger.Log.Warn("Failed to parse POST data (expecting InventoryFolderBase): " + ex.Message); 403 Logger.Log.Warn("Failed to parse POST data (expecting InventoryFolderBase): " + ex.Message);
404 agentID = UUID.Zero; 404 agentID = UUID.Zero;
405 sessionID = UUID.Zero; 405 sessionID = UUID.Zero;
406 return null; 406 return null;
407 } 407 }
408 408
409 return folder; 409 return folder;
410 } 410 }
411 411
412 InventoryItem DeserializeItem(Stream stream, out UUID agentID, out UUID sessionID) 412 InventoryItem DeserializeItem(Stream stream, out UUID agentID, out UUID sessionID)
413 { 413 {
414 InventoryItem item = new InventoryItem(); 414 InventoryItem item = new InventoryItem();
415 415
416 try 416 try
417 { 417 {
418 using (XmlReader reader = XmlReader.Create(stream)) 418 using (XmlReader reader = XmlReader.Create(stream))
419 { 419 {
420 reader.MoveToContent(); 420 reader.MoveToContent();
421 reader.ReadStartElement("RestSessionObjectOfInventoryItemBase"); 421 reader.ReadStartElement("RestSessionObjectOfInventoryItemBase");
422 UUID.TryParse(reader.ReadElementContentAsString("SessionID", String.Empty), out sessionID); 422 UUID.TryParse(reader.ReadElementContentAsString("SessionID", String.Empty), out sessionID);
423 UUID.TryParse(reader.ReadElementContentAsString("AvatarID", String.Empty), out agentID); 423 UUID.TryParse(reader.ReadElementContentAsString("AvatarID", String.Empty), out agentID);
424 reader.ReadStartElement("Body"); 424 reader.ReadStartElement("Body");
425 ReadUUID(reader, "ID", out item.ID); 425 ReadUUID(reader, "ID", out item.ID);
426 Int32.TryParse(reader.ReadElementContentAsString("InvType", String.Empty), out item.InvType); 426 Int32.TryParse(reader.ReadElementContentAsString("InvType", String.Empty), out item.InvType);
427 ReadUUID(reader, "Folder", out item.Folder); 427 ReadUUID(reader, "Folder", out item.Folder);
428 ReadUUID(reader, "Owner", out item.Owner); 428 ReadUUID(reader, "Owner", out item.Owner);
429 ReadUUID(reader, "Creator", out item.Creator); 429 ReadUUID(reader, "Creator", out item.Creator);
430 item.Name = reader.ReadElementContentAsString("Name", String.Empty); 430 item.Name = reader.ReadElementContentAsString("Name", String.Empty);
431 item.Description = reader.ReadElementContentAsString("Description", String.Empty); 431 item.Description = reader.ReadElementContentAsString("Description", String.Empty);
432 UInt32.TryParse(reader.ReadElementContentAsString("NextPermissions", String.Empty), out item.NextPermissions); 432 UInt32.TryParse(reader.ReadElementContentAsString("NextPermissions", String.Empty), out item.NextPermissions);
433 UInt32.TryParse(reader.ReadElementContentAsString("CurrentPermissions", String.Empty), out item.CurrentPermissions); 433 UInt32.TryParse(reader.ReadElementContentAsString("CurrentPermissions", String.Empty), out item.CurrentPermissions);
434 UInt32.TryParse(reader.ReadElementContentAsString("BasePermissions", String.Empty), out item.BasePermissions); 434 UInt32.TryParse(reader.ReadElementContentAsString("BasePermissions", String.Empty), out item.BasePermissions);
435 UInt32.TryParse(reader.ReadElementContentAsString("EveryOnePermissions", String.Empty), out item.EveryOnePermissions); 435 UInt32.TryParse(reader.ReadElementContentAsString("EveryOnePermissions", String.Empty), out item.EveryOnePermissions);
436 UInt32.TryParse(reader.ReadElementContentAsString("GroupPermissions", String.Empty), out item.GroupPermissions); 436 UInt32.TryParse(reader.ReadElementContentAsString("GroupPermissions", String.Empty), out item.GroupPermissions);
437 Int32.TryParse(reader.ReadElementContentAsString("AssetType", String.Empty), out item.AssetType); 437 Int32.TryParse(reader.ReadElementContentAsString("AssetType", String.Empty), out item.AssetType);
438 ReadUUID(reader, "AssetID", out item.AssetID); 438 ReadUUID(reader, "AssetID", out item.AssetID);
439 ReadUUID(reader, "GroupID", out item.GroupID); 439 ReadUUID(reader, "GroupID", out item.GroupID);
440 Boolean.TryParse(reader.ReadElementContentAsString("GroupOwned", String.Empty), out item.GroupOwned); 440 Boolean.TryParse(reader.ReadElementContentAsString("GroupOwned", String.Empty), out item.GroupOwned);
441 Int32.TryParse(reader.ReadElementContentAsString("SalePrice", String.Empty), out item.SalePrice); 441 Int32.TryParse(reader.ReadElementContentAsString("SalePrice", String.Empty), out item.SalePrice);
442 Byte.TryParse(reader.ReadElementContentAsString("SaleType", String.Empty), out item.SaleType); 442 Byte.TryParse(reader.ReadElementContentAsString("SaleType", String.Empty), out item.SaleType);
443 UInt32.TryParse(reader.ReadElementContentAsString("Flags", String.Empty), out item.Flags); 443 UInt32.TryParse(reader.ReadElementContentAsString("Flags", String.Empty), out item.Flags);
444 Int32.TryParse(reader.ReadElementContentAsString("CreationDate", String.Empty), out item.CreationDate); 444 Int32.TryParse(reader.ReadElementContentAsString("CreationDate", String.Empty), out item.CreationDate);
445 reader.ReadEndElement(); 445 reader.ReadEndElement();
446 reader.ReadEndElement(); 446 reader.ReadEndElement();
447 } 447 }
448 } 448 }
449 catch (Exception ex) 449 catch (Exception ex)
450 { 450 {
451 Logger.Log.Warn("Failed to parse POST data (expecting InventoryItemBase): " + ex.Message); 451 Logger.Log.Warn("Failed to parse POST data (expecting InventoryItemBase): " + ex.Message);
452 agentID = UUID.Zero; 452 agentID = UUID.Zero;
453 sessionID = UUID.Zero; 453 sessionID = UUID.Zero;
454 return null; 454 return null;
455 } 455 }
456 456
457 return item; 457 return item;
458 } 458 }
459 459
460 void SerializeBool(Stream stream, bool value) 460 void SerializeBool(Stream stream, bool value)
461 { 461 {
462 using (XmlWriter writer = XmlWriter.Create(stream)) 462 using (XmlWriter writer = XmlWriter.Create(stream))
463 { 463 {
464 writer.WriteStartDocument(); 464 writer.WriteStartDocument();
465 writer.WriteStartElement("boolean"); 465 writer.WriteStartElement("boolean");
466 writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance"); 466 writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
467 writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema"); 467 writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema");
468 writer.WriteString(value.ToString().ToLower()); 468 writer.WriteString(value.ToString().ToLower());
469 writer.WriteEndElement(); 469 writer.WriteEndElement();
470 writer.WriteEndDocument(); 470 writer.WriteEndDocument();
471 writer.Flush(); 471 writer.Flush();
472 } 472 }
473 473
474 stream.Flush(); 474 stream.Flush();
475 } 475 }
476 476
477 void SerializeFolderList(Stream stream, List<InventoryFolder> folders) 477 void SerializeFolderList(Stream stream, List<InventoryFolder> folders)
478 { 478 {
479 using (XmlWriter writer = XmlWriter.Create(stream)) 479 using (XmlWriter writer = XmlWriter.Create(stream))
480 { 480 {
481 writer.WriteStartDocument(); 481 writer.WriteStartDocument();
482 writer.WriteStartElement("ArrayOfInventoryFolderBase"); 482 writer.WriteStartElement("ArrayOfInventoryFolderBase");
483 writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance"); 483 writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
484 writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema"); 484 writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema");
485 485
486 if (folders != null) 486 if (folders != null)
487 { 487 {
488 foreach (InventoryFolder folder in folders) 488 foreach (InventoryFolder folder in folders)
489 { 489 {
490 writer.WriteStartElement("InventoryFolderBase"); 490 writer.WriteStartElement("InventoryFolderBase");
491 writer.WriteElementString("Name", folder.Name); 491 writer.WriteElementString("Name", folder.Name);
492 WriteUUID(writer, "Owner", folder.Owner); 492 WriteUUID(writer, "Owner", folder.Owner);
493 WriteUUID(writer, "ParentID", folder.ParentID); 493 WriteUUID(writer, "ParentID", folder.ParentID);
494 WriteUUID(writer, "ID", folder.ID); 494 WriteUUID(writer, "ID", folder.ID);
495 writer.WriteElementString("Type", XmlConvert.ToString(folder.Type)); 495 writer.WriteElementString("Type", XmlConvert.ToString(folder.Type));
496 writer.WriteElementString("Version", XmlConvert.ToString(folder.Version)); 496 writer.WriteElementString("Version", XmlConvert.ToString(folder.Version));
497 writer.WriteEndElement(); 497 writer.WriteEndElement();
498 } 498 }
499 } 499 }
500 500
501 writer.WriteEndElement(); 501 writer.WriteEndElement();
502 writer.WriteEndDocument(); 502 writer.WriteEndDocument();
503 503
504 writer.Flush(); 504 writer.Flush();
505 } 505 }
506 506
507 stream.Flush(); 507 stream.Flush();
508 } 508 }
509 509
510 void SerializeItemList(Stream stream, List<InventoryItem> items) 510 void SerializeItemList(Stream stream, List<InventoryItem> items)
511 { 511 {
512 using (XmlWriter writer = XmlWriter.Create(stream)) 512 using (XmlWriter writer = XmlWriter.Create(stream))
513 { 513 {
514 writer.WriteStartDocument(); 514 writer.WriteStartDocument();
515 writer.WriteStartElement("ArrayOfInventoryItemBase"); 515 writer.WriteStartElement("ArrayOfInventoryItemBase");
516 writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance"); 516 writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
517 writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema"); 517 writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema");
518 518
519 if (items != null) 519 if (items != null)
520 { 520 {
521 foreach (InventoryItem item in items) 521 foreach (InventoryItem item in items)
522 { 522 {
523 writer.WriteStartElement("InventoryItemBase"); 523 writer.WriteStartElement("InventoryItemBase");
524 WriteUUID(writer, "ID", item.ID); 524 WriteUUID(writer, "ID", item.ID);
525 writer.WriteElementString("InvType", XmlConvert.ToString(item.InvType)); 525 writer.WriteElementString("InvType", XmlConvert.ToString(item.InvType));
526 WriteUUID(writer, "Folder", item.Folder); 526 WriteUUID(writer, "Folder", item.Folder);
527 WriteUUID(writer, "Owner", item.Owner); 527 WriteUUID(writer, "Owner", item.Owner);
528 WriteUUID(writer, "Creator", item.Creator); 528 WriteUUID(writer, "Creator", item.Creator);
529 writer.WriteElementString("Name", item.Name); 529 writer.WriteElementString("Name", item.Name);
530 writer.WriteElementString("Description", item.Description); 530 writer.WriteElementString("Description", item.Description);
531 writer.WriteElementString("NextPermissions", XmlConvert.ToString(item.NextPermissions)); 531 writer.WriteElementString("NextPermissions", XmlConvert.ToString(item.NextPermissions));
532 writer.WriteElementString("CurrentPermissions", XmlConvert.ToString(item.CurrentPermissions)); 532 writer.WriteElementString("CurrentPermissions", XmlConvert.ToString(item.CurrentPermissions));
533 writer.WriteElementString("BasePermissions", XmlConvert.ToString(item.BasePermissions)); 533 writer.WriteElementString("BasePermissions", XmlConvert.ToString(item.BasePermissions));
534 writer.WriteElementString("EveryOnePermissions", XmlConvert.ToString(item.EveryOnePermissions)); 534 writer.WriteElementString("EveryOnePermissions", XmlConvert.ToString(item.EveryOnePermissions));
535 writer.WriteElementString("GroupPermissions", XmlConvert.ToString(item.GroupPermissions)); 535 writer.WriteElementString("GroupPermissions", XmlConvert.ToString(item.GroupPermissions));
536 writer.WriteElementString("AssetType", XmlConvert.ToString(item.AssetType)); 536 writer.WriteElementString("AssetType", XmlConvert.ToString(item.AssetType));
537 WriteUUID(writer, "AssetID", item.AssetID); 537 WriteUUID(writer, "AssetID", item.AssetID);
538 WriteUUID(writer, "GroupID", item.GroupID); 538 WriteUUID(writer, "GroupID", item.GroupID);
539 writer.WriteElementString("GroupOwned", XmlConvert.ToString(item.GroupOwned)); 539 writer.WriteElementString("GroupOwned", XmlConvert.ToString(item.GroupOwned));
540 writer.WriteElementString("SalePrice", XmlConvert.ToString(item.SalePrice)); 540 writer.WriteElementString("SalePrice", XmlConvert.ToString(item.SalePrice));
541 writer.WriteElementString("SaleType", XmlConvert.ToString(item.SaleType)); 541 writer.WriteElementString("SaleType", XmlConvert.ToString(item.SaleType));
542 writer.WriteElementString("Flags", XmlConvert.ToString(item.Flags)); 542 writer.WriteElementString("Flags", XmlConvert.ToString(item.Flags));
543 writer.WriteElementString("CreationDate", XmlConvert.ToString(item.CreationDate)); 543 writer.WriteElementString("CreationDate", XmlConvert.ToString(item.CreationDate));
544 writer.WriteEndElement(); 544 writer.WriteEndElement();
545 } 545 }
546 } 546 }
547 547
548 writer.WriteEndElement(); 548 writer.WriteEndElement();
549 writer.WriteEndDocument(); 549 writer.WriteEndDocument();
550 550
551 writer.Flush(); 551 writer.Flush();
552 } 552 }
553 553
554 stream.Flush(); 554 stream.Flush();
555 } 555 }
556 556
557 void WriteUUID(XmlWriter writer, string name, UUID id) 557 void WriteUUID(XmlWriter writer, string name, UUID id)
558 { 558 {
559 writer.WriteStartElement(name); 559 writer.WriteStartElement(name);
560 writer.WriteElementString("Guid", XmlConvert.ToString(id.Guid)); 560 writer.WriteElementString("Guid", XmlConvert.ToString(id.Guid));
561 writer.WriteEndElement(); 561 writer.WriteEndElement();
562 } 562 }
563 563
564 void ReadUUID(XmlReader reader, string name, out UUID id) 564 void ReadUUID(XmlReader reader, string name, out UUID id)
565 { 565 {
566 reader.ReadStartElement(name); 566 reader.ReadStartElement(name);
567 UUID.TryParse(reader.ReadElementContentAsString("Guid", String.Empty), out id); 567 UUID.TryParse(reader.ReadElementContentAsString("Guid", String.Empty), out id);
568 reader.ReadEndElement(); 568 reader.ReadEndElement();
569 } 569 }
570 } 570 }
571 571
572 #region OpenSim AssetType 572 #region OpenSim AssetType
573 573
574 /// <summary> 574 /// <summary>
575 /// The different types of grid assets 575 /// The different types of grid assets
576 /// </summary> 576 /// </summary>
577 public enum AssetType : sbyte 577 public enum AssetType : sbyte
578 { 578 {
579 /// <summary>Unknown asset type</summary> 579 /// <summary>Unknown asset type</summary>
580 Unknown = -1, 580 Unknown = -1,
581 /// <summary>Texture asset, stores in JPEG2000 J2C stream format</summary> 581 /// <summary>Texture asset, stores in JPEG2000 J2C stream format</summary>
582 Texture = 0, 582 Texture = 0,
583 /// <summary>Sound asset</summary> 583 /// <summary>Sound asset</summary>
584 Sound = 1, 584 Sound = 1,
585 /// <summary>Calling card for another avatar</summary> 585 /// <summary>Calling card for another avatar</summary>
586 CallingCard = 2, 586 CallingCard = 2,
587 /// <summary>Link to a location in world</summary> 587 /// <summary>Link to a location in world</summary>
588 Landmark = 3, 588 Landmark = 3,
589 // <summary>Legacy script asset, you should never see one of these</summary> 589 // <summary>Legacy script asset, you should never see one of these</summary>
590 //[Obsolete] 590 //[Obsolete]
591 //Script = 4, 591 //Script = 4,
592 /// <summary>Collection of textures and parameters that can be 592 /// <summary>Collection of textures and parameters that can be
593 /// worn by an avatar</summary> 593 /// worn by an avatar</summary>
594 Clothing = 5, 594 Clothing = 5,
595 /// <summary>Primitive that can contain textures, sounds, 595 /// <summary>Primitive that can contain textures, sounds,
596 /// scripts and more</summary> 596 /// scripts and more</summary>
597 Object = 6, 597 Object = 6,
598 /// <summary>Notecard asset</summary> 598 /// <summary>Notecard asset</summary>
599 Notecard = 7, 599 Notecard = 7,
600 /// <summary>Holds a collection of inventory items</summary> 600 /// <summary>Holds a collection of inventory items</summary>
601 Folder = 8, 601 Folder = 8,
602 /// <summary>Root inventory folder</summary> 602 /// <summary>Root inventory folder</summary>
603 RootFolder = 9, 603 RootFolder = 9,
604 /// <summary>Linden scripting language script</summary> 604 /// <summary>Linden scripting language script</summary>
605 LSLText = 10, 605 LSLText = 10,
606 /// <summary>LSO bytecode for a script</summary> 606 /// <summary>LSO bytecode for a script</summary>
607 LSLBytecode = 11, 607 LSLBytecode = 11,
608 /// <summary>Uncompressed TGA texture</summary> 608 /// <summary>Uncompressed TGA texture</summary>
609 TextureTGA = 12, 609 TextureTGA = 12,
610 /// <summary>Collection of textures and shape parameters that can 610 /// <summary>Collection of textures and shape parameters that can
611 /// be worn</summary> 611 /// be worn</summary>
612 Bodypart = 13, 612 Bodypart = 13,
613 /// <summary>Trash folder</summary> 613 /// <summary>Trash folder</summary>
614 TrashFolder = 14, 614 TrashFolder = 14,
615 /// <summary>Snapshot folder</summary> 615 /// <summary>Snapshot folder</summary>
616 SnapshotFolder = 15, 616 SnapshotFolder = 15,
617 /// <summary>Lost and found folder</summary> 617 /// <summary>Lost and found folder</summary>
618 LostAndFoundFolder = 16, 618 LostAndFoundFolder = 16,
619 /// <summary>Uncompressed sound</summary> 619 /// <summary>Uncompressed sound</summary>
620 SoundWAV = 17, 620 SoundWAV = 17,
621 /// <summary>Uncompressed TGA non-square image, not to be used as a 621 /// <summary>Uncompressed TGA non-square image, not to be used as a
622 /// texture</summary> 622 /// texture</summary>
623 ImageTGA = 18, 623 ImageTGA = 18,
624 /// <summary>Compressed JPEG non-square image, not to be used as a 624 /// <summary>Compressed JPEG non-square image, not to be used as a
625 /// texture</summary> 625 /// texture</summary>
626 ImageJPEG = 19, 626 ImageJPEG = 19,
627 /// <summary>Animation</summary> 627 /// <summary>Animation</summary>
628 Animation = 20, 628 Animation = 20,
629 /// <summary>Sequence of animations, sounds, chat, and pauses</summary> 629 /// <summary>Sequence of animations, sounds, chat, and pauses</summary>
630 Gesture = 21, 630 Gesture = 21,
631 /// <summary>Simstate file</summary> 631 /// <summary>Simstate file</summary>
632 Simstate = 22, 632 Simstate = 22,
633 } 633 }
634 634
635 #endregion OpenSim AssetType 635 #endregion OpenSim AssetType
636} 636}
diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLInventory.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLInventory.cs
index 7d6c0c2..07bf92f 100644
--- a/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLInventory.cs
+++ b/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLInventory.cs
@@ -1,804 +1,804 @@
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
30using System; 30using System;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Net; 32using System.Net;
33using System.Data; 33using System.Data;
34using MySql.Data.MySqlClient; 34using MySql.Data.MySqlClient;
35using ExtensionLoader; 35using ExtensionLoader;
36using ExtensionLoader.Config; 36using ExtensionLoader.Config;
37using OpenMetaverse; 37using OpenMetaverse;
38using OpenMetaverse.StructuredData; 38using OpenMetaverse.StructuredData;
39 39
40namespace OpenSim.Grid.AssetInventoryServer.Extensions 40namespace OpenSim.Grid.AssetInventoryServer.Extensions
41{ 41{
42 public class OpenSimMySQLInventory : IExtension<AssetInventoryServer>, IInventoryProvider 42 public class OpenSimMySQLInventory : IExtension<AssetInventoryServer>, IInventoryProvider
43 { 43 {
44 const string EXTENSION_NAME = "OpenSimMySQLInventory"; // Used in metrics reporting 44 const string EXTENSION_NAME = "OpenSimMySQLInventory"; // Used in metrics reporting
45 45
46 AssetInventoryServer server; 46 AssetInventoryServer server;
47 47
48 public OpenSimMySQLInventory() 48 public OpenSimMySQLInventory()
49 { 49 {
50 } 50 }
51 51
52 #region Required Interfaces 52 #region Required Interfaces
53 53
54 public void Start(AssetInventoryServer server) 54 public void Start(AssetInventoryServer server)
55 { 55 {
56 this.server = server; 56 this.server = server;
57 57
58 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) 58 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
59 { 59 {
60 try 60 try
61 { 61 {
62 dbConnection.Open(); 62 dbConnection.Open();
63 Logger.Log.Info("Connected to MySQL inventory backend: " + dbConnection.ServerVersion); 63 Logger.Log.Info("Connected to MySQL inventory backend: " + dbConnection.ServerVersion);
64 } 64 }
65 catch (MySqlException ex) 65 catch (MySqlException ex)
66 { 66 {
67 Logger.Log.Error("Connection to MySQL inventory backend failed: " + ex.Message); 67 Logger.Log.Error("Connection to MySQL inventory backend failed: " + ex.Message);
68 } 68 }
69 } 69 }
70 } 70 }
71 71
72 public void Stop() 72 public void Stop()
73 { 73 {
74 } 74 }
75 75
76 public BackendResponse TryFetchItem(Uri owner, UUID itemID, out InventoryItem item) 76 public BackendResponse TryFetchItem(Uri owner, UUID itemID, out InventoryItem item)
77 { 77 {
78 item = null; 78 item = null;
79 BackendResponse ret; 79 BackendResponse ret;
80 80
81 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) 81 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
82 { 82 {
83 IDataReader reader; 83 IDataReader reader;
84 84
85 try 85 try
86 { 86 {
87 dbConnection.Open(); 87 dbConnection.Open();
88 88
89 IDbCommand command = dbConnection.CreateCommand(); 89 IDbCommand command = dbConnection.CreateCommand();
90 command.CommandText = String.Format("SELECT assetID,assetType,inventoryName,inventoryDescription,inventoryNextPermissions," + 90 command.CommandText = String.Format("SELECT assetID,assetType,inventoryName,inventoryDescription,inventoryNextPermissions," +
91 "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," + 91 "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," +
92 "creationDate,groupID,groupOwned,flags,avatarID,parentFolderID,inventoryGroupPermissions FROM inventoryitems WHERE inventoryID='{0}'", 92 "creationDate,groupID,groupOwned,flags,avatarID,parentFolderID,inventoryGroupPermissions FROM inventoryitems WHERE inventoryID='{0}'",
93 itemID.ToString()); 93 itemID.ToString());
94 reader = command.ExecuteReader(); 94 reader = command.ExecuteReader();
95 95
96 if (reader.Read()) 96 if (reader.Read())
97 { 97 {
98 item = new InventoryItem(); 98 item = new InventoryItem();
99 item.ID = itemID; 99 item.ID = itemID;
100 item.AssetID = UUID.Parse(reader.GetString(0)); 100 item.AssetID = UUID.Parse(reader.GetString(0));
101 item.AssetType = reader.GetInt32(1); 101 item.AssetType = reader.GetInt32(1);
102 item.Name = reader.GetString(2); 102 item.Name = reader.GetString(2);
103 item.Description = reader.GetString(3); 103 item.Description = reader.GetString(3);
104 item.NextPermissions = (uint)reader.GetInt32(4); 104 item.NextPermissions = (uint)reader.GetInt32(4);
105 item.CurrentPermissions = (uint)reader.GetInt32(5); 105 item.CurrentPermissions = (uint)reader.GetInt32(5);
106 item.InvType = reader.GetInt32(6); 106 item.InvType = reader.GetInt32(6);
107 item.Creator = UUID.Parse(reader.GetString(7)); 107 item.Creator = UUID.Parse(reader.GetString(7));
108 item.BasePermissions = (uint)reader.GetInt32(8); 108 item.BasePermissions = (uint)reader.GetInt32(8);
109 item.EveryOnePermissions = (uint)reader.GetInt32(9); 109 item.EveryOnePermissions = (uint)reader.GetInt32(9);
110 item.SalePrice = reader.GetInt32(10); 110 item.SalePrice = reader.GetInt32(10);
111 item.SaleType = reader.GetByte(11); 111 item.SaleType = reader.GetByte(11);
112 item.CreationDate = reader.GetInt32(12); 112 item.CreationDate = reader.GetInt32(12);
113 item.GroupID = UUID.Parse(reader.GetString(13)); 113 item.GroupID = UUID.Parse(reader.GetString(13));
114 item.GroupOwned = reader.GetBoolean(14); 114 item.GroupOwned = reader.GetBoolean(14);
115 item.Flags = (uint)reader.GetInt32(15); 115 item.Flags = (uint)reader.GetInt32(15);
116 item.Owner = UUID.Parse(reader.GetString(16)); 116 item.Owner = UUID.Parse(reader.GetString(16));
117 item.Folder = UUID.Parse(reader.GetString(17)); 117 item.Folder = UUID.Parse(reader.GetString(17));
118 item.GroupPermissions = (uint)reader.GetInt32(18); 118 item.GroupPermissions = (uint)reader.GetInt32(18);
119 119
120 ret = BackendResponse.Success; 120 ret = BackendResponse.Success;
121 } 121 }
122 else 122 else
123 { 123 {
124 ret = BackendResponse.NotFound; 124 ret = BackendResponse.NotFound;
125 } 125 }
126 } 126 }
127 catch (MySqlException ex) 127 catch (MySqlException ex)
128 { 128 {
129 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); 129 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
130 ret = BackendResponse.Failure; 130 ret = BackendResponse.Failure;
131 } 131 }
132 } 132 }
133 133
134 server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now); 134 server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now);
135 return ret; 135 return ret;
136 } 136 }
137 137
138 public BackendResponse TryFetchFolder(Uri owner, UUID folderID, out InventoryFolder folder) 138 public BackendResponse TryFetchFolder(Uri owner, UUID folderID, out InventoryFolder folder)
139 { 139 {
140 folder = null; 140 folder = null;
141 BackendResponse ret; 141 BackendResponse ret;
142 142
143 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) 143 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
144 { 144 {
145 IDataReader reader; 145 IDataReader reader;
146 146
147 try 147 try
148 { 148 {
149 dbConnection.Open(); 149 dbConnection.Open();
150 150
151 IDbCommand command = dbConnection.CreateCommand(); 151 IDbCommand command = dbConnection.CreateCommand();
152 command.CommandText = String.Format("SELECT folderName,type,version,agentID,parentFolderID FROM inventoryfolders WHERE folderID='{0}'", 152 command.CommandText = String.Format("SELECT folderName,type,version,agentID,parentFolderID FROM inventoryfolders WHERE folderID='{0}'",
153 folderID.ToString()); 153 folderID.ToString());
154 reader = command.ExecuteReader(); 154 reader = command.ExecuteReader();
155 155
156 if (reader.Read()) 156 if (reader.Read())
157 { 157 {
158 folder = new InventoryFolder(); 158 folder = new InventoryFolder();
159 folder.Children = null; // This call only returns data for the folder itself, no children data 159 folder.Children = null; // This call only returns data for the folder itself, no children data
160 folder.ID = folderID; 160 folder.ID = folderID;
161 folder.Name = reader.GetString(0); 161 folder.Name = reader.GetString(0);
162 folder.Type = reader.GetInt16(1); 162 folder.Type = reader.GetInt16(1);
163 folder.Version = (ushort)reader.GetInt16(2); 163 folder.Version = (ushort)reader.GetInt16(2);
164 folder.Owner = UUID.Parse(reader.GetString(3)); 164 folder.Owner = UUID.Parse(reader.GetString(3));
165 folder.ParentID = UUID.Parse(reader.GetString(4)); 165 folder.ParentID = UUID.Parse(reader.GetString(4));
166 166
167 ret = BackendResponse.Success; 167 ret = BackendResponse.Success;
168 } 168 }
169 else 169 else
170 { 170 {
171 ret = BackendResponse.NotFound; 171 ret = BackendResponse.NotFound;
172 } 172 }
173 } 173 }
174 catch (MySqlException ex) 174 catch (MySqlException ex)
175 { 175 {
176 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); 176 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
177 ret = BackendResponse.Failure; 177 ret = BackendResponse.Failure;
178 } 178 }
179 } 179 }
180 180
181 server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now); 181 server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now);
182 return ret; 182 return ret;
183 } 183 }
184 184
185 public BackendResponse TryFetchFolderContents(Uri owner, UUID folderID, out InventoryCollection contents) 185 public BackendResponse TryFetchFolderContents(Uri owner, UUID folderID, out InventoryCollection contents)
186 { 186 {
187 contents = null; 187 contents = null;
188 BackendResponse ret; 188 BackendResponse ret;
189 189
190 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) 190 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
191 { 191 {
192 IDataReader reader; 192 IDataReader reader;
193 193
194 try 194 try
195 { 195 {
196 dbConnection.Open(); 196 dbConnection.Open();
197 197
198 contents = new InventoryCollection(); 198 contents = new InventoryCollection();
199 199
200 #region Folder retrieval 200 #region Folder retrieval
201 201
202 IDbCommand command = dbConnection.CreateCommand(); 202 IDbCommand command = dbConnection.CreateCommand();
203 command.CommandText = String.Format("SELECT folderName,type,version,agentID,folderID FROM inventoryfolders WHERE parentFolderID='{0}'", 203 command.CommandText = String.Format("SELECT folderName,type,version,agentID,folderID FROM inventoryfolders WHERE parentFolderID='{0}'",
204 folderID.ToString()); 204 folderID.ToString());
205 reader = command.ExecuteReader(); 205 reader = command.ExecuteReader();
206 206
207 contents.Folders = new Dictionary<UUID, InventoryFolder>(); 207 contents.Folders = new Dictionary<UUID, InventoryFolder>();
208 208
209 while (reader.Read()) 209 while (reader.Read())
210 { 210 {
211 InventoryFolder folder = new InventoryFolder(); 211 InventoryFolder folder = new InventoryFolder();
212 folder.ParentID = folderID; 212 folder.ParentID = folderID;
213 folder.Children = null; // This call doesn't do recursion 213 folder.Children = null; // This call doesn't do recursion
214 folder.Name = reader.GetString(0); 214 folder.Name = reader.GetString(0);
215 folder.Type = reader.GetInt16(1); 215 folder.Type = reader.GetInt16(1);
216 folder.Version = (ushort)reader.GetInt16(2); 216 folder.Version = (ushort)reader.GetInt16(2);
217 folder.Owner = UUID.Parse(reader.GetString(3)); 217 folder.Owner = UUID.Parse(reader.GetString(3));
218 folder.ID = UUID.Parse(reader.GetString(4)); 218 folder.ID = UUID.Parse(reader.GetString(4));
219 219
220 contents.Folders.Add(folder.ID, folder); 220 contents.Folders.Add(folder.ID, folder);
221 contents.UserID = folder.Owner; 221 contents.UserID = folder.Owner;
222 } 222 }
223 223
224 reader.Close(); 224 reader.Close();
225 225
226 #endregion Folder retrieval 226 #endregion Folder retrieval
227 227
228 #region Item retrieval 228 #region Item retrieval
229 229
230 command = dbConnection.CreateCommand(); 230 command = dbConnection.CreateCommand();
231 command.CommandText = String.Format("SELECT assetID,assetType,inventoryName,inventoryDescription,inventoryNextPermissions," + 231 command.CommandText = String.Format("SELECT assetID,assetType,inventoryName,inventoryDescription,inventoryNextPermissions," +
232 "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," + 232 "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," +
233 "creationDate,groupID,groupOwned,flags,avatarID,inventoryID,inventoryGroupPermissions FROM inventoryitems WHERE parentFolderID='{0}'", 233 "creationDate,groupID,groupOwned,flags,avatarID,inventoryID,inventoryGroupPermissions FROM inventoryitems WHERE parentFolderID='{0}'",
234 folderID.ToString()); 234 folderID.ToString());
235 reader = command.ExecuteReader(); 235 reader = command.ExecuteReader();
236 236
237 contents.Items = new Dictionary<UUID, InventoryItem>(); 237 contents.Items = new Dictionary<UUID, InventoryItem>();
238 238
239 while (reader.Read()) 239 while (reader.Read())
240 { 240 {
241 InventoryItem item = new InventoryItem(); 241 InventoryItem item = new InventoryItem();
242 item.Folder = folderID; 242 item.Folder = folderID;
243 item.AssetID = UUID.Parse(reader.GetString(0)); 243 item.AssetID = UUID.Parse(reader.GetString(0));
244 item.AssetType = reader.GetInt32(1); 244 item.AssetType = reader.GetInt32(1);
245 item.Name = reader.GetString(2); 245 item.Name = reader.GetString(2);
246 item.Description = reader.GetString(3); 246 item.Description = reader.GetString(3);
247 item.NextPermissions = (uint)reader.GetInt32(4); 247 item.NextPermissions = (uint)reader.GetInt32(4);
248 item.CurrentPermissions = (uint)reader.GetInt32(5); 248 item.CurrentPermissions = (uint)reader.GetInt32(5);
249 item.InvType = reader.GetInt32(6); 249 item.InvType = reader.GetInt32(6);
250 item.Creator = UUID.Parse(reader.GetString(7)); 250 item.Creator = UUID.Parse(reader.GetString(7));
251 item.BasePermissions = (uint)reader.GetInt32(8); 251 item.BasePermissions = (uint)reader.GetInt32(8);
252 item.EveryOnePermissions = (uint)reader.GetInt32(9); 252 item.EveryOnePermissions = (uint)reader.GetInt32(9);
253 item.SalePrice = reader.GetInt32(10); 253 item.SalePrice = reader.GetInt32(10);
254 item.SaleType = reader.GetByte(11); 254 item.SaleType = reader.GetByte(11);
255 item.CreationDate = reader.GetInt32(12); 255 item.CreationDate = reader.GetInt32(12);
256 item.GroupID = UUID.Parse(reader.GetString(13)); 256 item.GroupID = UUID.Parse(reader.GetString(13));
257 item.GroupOwned = reader.GetBoolean(14); 257 item.GroupOwned = reader.GetBoolean(14);
258 item.Flags = (uint)reader.GetInt32(15); 258 item.Flags = (uint)reader.GetInt32(15);
259 item.Owner = UUID.Parse(reader.GetString(16)); 259 item.Owner = UUID.Parse(reader.GetString(16));
260 item.ID = UUID.Parse(reader.GetString(17)); 260 item.ID = UUID.Parse(reader.GetString(17));
261 item.GroupPermissions = (uint)reader.GetInt32(18); 261 item.GroupPermissions = (uint)reader.GetInt32(18);
262 262
263 contents.Items.Add(item.ID, item); 263 contents.Items.Add(item.ID, item);
264 contents.UserID = item.Owner; 264 contents.UserID = item.Owner;
265 } 265 }
266 266
267 #endregion Item retrieval 267 #endregion Item retrieval
268 268
269 ret = BackendResponse.Success; 269 ret = BackendResponse.Success;
270 } 270 }
271 catch (MySqlException ex) 271 catch (MySqlException ex)
272 { 272 {
273 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); 273 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
274 ret = BackendResponse.Failure; 274 ret = BackendResponse.Failure;
275 } 275 }
276 } 276 }
277 277
278 server.MetricsProvider.LogInventoryFetchFolderContents(EXTENSION_NAME, ret, owner, folderID, DateTime.Now); 278 server.MetricsProvider.LogInventoryFetchFolderContents(EXTENSION_NAME, ret, owner, folderID, DateTime.Now);
279 return ret; 279 return ret;
280 } 280 }
281 281
282 public BackendResponse TryFetchFolderList(Uri owner, out List<InventoryFolder> folders) 282 public BackendResponse TryFetchFolderList(Uri owner, out List<InventoryFolder> folders)
283 { 283 {
284 folders = null; 284 folders = null;
285 BackendResponse ret; 285 BackendResponse ret;
286 UUID ownerID; 286 UUID ownerID;
287 287
288 if (Utils.TryGetOpenSimUUID(owner, out ownerID)) 288 if (Utils.TryGetOpenSimUUID(owner, out ownerID))
289 { 289 {
290 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) 290 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
291 { 291 {
292 IDataReader reader; 292 IDataReader reader;
293 293
294 try 294 try
295 { 295 {
296 dbConnection.Open(); 296 dbConnection.Open();
297 folders = new List<InventoryFolder>(); 297 folders = new List<InventoryFolder>();
298 298
299 IDbCommand command = dbConnection.CreateCommand(); 299 IDbCommand command = dbConnection.CreateCommand();
300 command.CommandText = String.Format("SELECT folderName,type,version,folderID,parentFolderID FROM inventoryfolders WHERE agentID='{0}'", 300 command.CommandText = String.Format("SELECT folderName,type,version,folderID,parentFolderID FROM inventoryfolders WHERE agentID='{0}'",
301 ownerID.ToString()); 301 ownerID.ToString());
302 reader = command.ExecuteReader(); 302 reader = command.ExecuteReader();
303 303
304 while (reader.Read()) 304 while (reader.Read())
305 { 305 {
306 InventoryFolder folder = new InventoryFolder(); 306 InventoryFolder folder = new InventoryFolder();
307 folder.Owner = ownerID; 307 folder.Owner = ownerID;
308 folder.Children = null; // This call does not create a folder hierarchy 308 folder.Children = null; // This call does not create a folder hierarchy
309 folder.Name = reader.GetString(0); 309 folder.Name = reader.GetString(0);
310 folder.Type = reader.GetInt16(1); 310 folder.Type = reader.GetInt16(1);
311 folder.Version = (ushort)reader.GetInt16(2); 311 folder.Version = (ushort)reader.GetInt16(2);
312 folder.ID = UUID.Parse(reader.GetString(3)); 312 folder.ID = UUID.Parse(reader.GetString(3));
313 folder.ParentID = UUID.Parse(reader.GetString(4)); 313 folder.ParentID = UUID.Parse(reader.GetString(4));
314 314
315 folders.Add(folder); 315 folders.Add(folder);
316 } 316 }
317 317
318 ret = BackendResponse.Success; 318 ret = BackendResponse.Success;
319 } 319 }
320 catch (MySqlException ex) 320 catch (MySqlException ex)
321 { 321 {
322 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); 322 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
323 ret = BackendResponse.Failure; 323 ret = BackendResponse.Failure;
324 } 324 }
325 } 325 }
326 } 326 }
327 else 327 else
328 { 328 {
329 ret = BackendResponse.NotFound; 329 ret = BackendResponse.NotFound;
330 } 330 }
331 331
332 server.MetricsProvider.LogInventoryFetchFolderList(EXTENSION_NAME, ret, owner, DateTime.Now); 332 server.MetricsProvider.LogInventoryFetchFolderList(EXTENSION_NAME, ret, owner, DateTime.Now);
333 return ret; 333 return ret;
334 } 334 }
335 335
336 public BackendResponse TryFetchInventory(Uri owner, out InventoryCollection inventory) 336 public BackendResponse TryFetchInventory(Uri owner, out InventoryCollection inventory)
337 { 337 {
338 inventory = null; 338 inventory = null;
339 BackendResponse ret; 339 BackendResponse ret;
340 List<InventoryFolder> folders; 340 List<InventoryFolder> folders;
341 UUID ownerID; 341 UUID ownerID;
342 342
343 ret = TryFetchFolderList(owner, out folders); 343 ret = TryFetchFolderList(owner, out folders);
344 344
345 if (ret == BackendResponse.Success) 345 if (ret == BackendResponse.Success)
346 { 346 {
347 // Add the retrieved folders to the inventory collection 347 // Add the retrieved folders to the inventory collection
348 inventory = new InventoryCollection(); 348 inventory = new InventoryCollection();
349 inventory.Folders = new Dictionary<UUID, InventoryFolder>(folders.Count); 349 inventory.Folders = new Dictionary<UUID, InventoryFolder>(folders.Count);
350 foreach (InventoryFolder folder in folders) 350 foreach (InventoryFolder folder in folders)
351 inventory.Folders[folder.ID] = folder; 351 inventory.Folders[folder.ID] = folder;
352 352
353 // Fetch inventory items 353 // Fetch inventory items
354 if (Utils.TryGetOpenSimUUID(owner, out ownerID)) 354 if (Utils.TryGetOpenSimUUID(owner, out ownerID))
355 { 355 {
356 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) 356 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
357 { 357 {
358 IDataReader reader; 358 IDataReader reader;
359 359
360 try 360 try
361 { 361 {
362 dbConnection.Open(); 362 dbConnection.Open();
363 363
364 IDbCommand command = dbConnection.CreateCommand(); 364 IDbCommand command = dbConnection.CreateCommand();
365 command.CommandText = String.Format("SELECT assetID,assetType,inventoryName,inventoryDescription,inventoryNextPermissions," + 365 command.CommandText = String.Format("SELECT assetID,assetType,inventoryName,inventoryDescription,inventoryNextPermissions," +
366 "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," + 366 "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," +
367 "creationDate,groupID,groupOwned,flags,inventoryID,parentFolderID,inventoryGroupPermissions FROM inventoryitems WHERE " + 367 "creationDate,groupID,groupOwned,flags,inventoryID,parentFolderID,inventoryGroupPermissions FROM inventoryitems WHERE " +
368 "avatarID='{0}'", ownerID.ToString()); 368 "avatarID='{0}'", ownerID.ToString());
369 reader = command.ExecuteReader(); 369 reader = command.ExecuteReader();
370 370
371 inventory.UserID = ownerID; 371 inventory.UserID = ownerID;
372 inventory.Items = new Dictionary<UUID, InventoryItem>(); 372 inventory.Items = new Dictionary<UUID, InventoryItem>();
373 373
374 while (reader.Read()) 374 while (reader.Read())
375 { 375 {
376 InventoryItem item = new InventoryItem(); 376 InventoryItem item = new InventoryItem();
377 item.Owner = ownerID; 377 item.Owner = ownerID;
378 item.AssetID = UUID.Parse(reader.GetString(0)); 378 item.AssetID = UUID.Parse(reader.GetString(0));
379 item.AssetType = reader.GetInt32(1); 379 item.AssetType = reader.GetInt32(1);
380 item.Name = reader.GetString(2); 380 item.Name = reader.GetString(2);
381 item.Description = reader.GetString(3); 381 item.Description = reader.GetString(3);
382 item.NextPermissions = (uint)reader.GetInt32(4); 382 item.NextPermissions = (uint)reader.GetInt32(4);
383 item.CurrentPermissions = (uint)reader.GetInt32(5); 383 item.CurrentPermissions = (uint)reader.GetInt32(5);
384 item.InvType = reader.GetInt32(6); 384 item.InvType = reader.GetInt32(6);
385 item.Creator = UUID.Parse(reader.GetString(7)); 385 item.Creator = UUID.Parse(reader.GetString(7));
386 item.BasePermissions = (uint)reader.GetInt32(8); 386 item.BasePermissions = (uint)reader.GetInt32(8);
387 item.EveryOnePermissions = (uint)reader.GetInt32(9); 387 item.EveryOnePermissions = (uint)reader.GetInt32(9);
388 item.SalePrice = reader.GetInt32(10); 388 item.SalePrice = reader.GetInt32(10);
389 item.SaleType = reader.GetByte(11); 389 item.SaleType = reader.GetByte(11);
390 item.CreationDate = reader.GetInt32(12); 390 item.CreationDate = reader.GetInt32(12);
391 item.GroupID = UUID.Parse(reader.GetString(13)); 391 item.GroupID = UUID.Parse(reader.GetString(13));
392 item.GroupOwned = reader.GetBoolean(14); 392 item.GroupOwned = reader.GetBoolean(14);
393 item.Flags = (uint)reader.GetInt32(15); 393 item.Flags = (uint)reader.GetInt32(15);
394 item.ID = UUID.Parse(reader.GetString(16)); 394 item.ID = UUID.Parse(reader.GetString(16));
395 item.Folder = UUID.Parse(reader.GetString(17)); 395 item.Folder = UUID.Parse(reader.GetString(17));
396 item.GroupPermissions = (uint)reader.GetInt32(18); 396 item.GroupPermissions = (uint)reader.GetInt32(18);
397 397
398 inventory.Items.Add(item.ID, item); 398 inventory.Items.Add(item.ID, item);
399 } 399 }
400 400
401 ret = BackendResponse.Success; 401 ret = BackendResponse.Success;
402 } 402 }
403 catch (MySqlException ex) 403 catch (MySqlException ex)
404 { 404 {
405 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); 405 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
406 ret = BackendResponse.Failure; 406 ret = BackendResponse.Failure;
407 } 407 }
408 } 408 }
409 } 409 }
410 else 410 else
411 { 411 {
412 ret = BackendResponse.NotFound; 412 ret = BackendResponse.NotFound;
413 } 413 }
414 } 414 }
415 415
416 server.MetricsProvider.LogInventoryFetchInventory(EXTENSION_NAME, ret, owner, DateTime.Now); 416 server.MetricsProvider.LogInventoryFetchInventory(EXTENSION_NAME, ret, owner, DateTime.Now);
417 return ret; 417 return ret;
418 } 418 }
419 419
420 public BackendResponse TryFetchActiveGestures(Uri owner, out List<InventoryItem> gestures) 420 public BackendResponse TryFetchActiveGestures(Uri owner, out List<InventoryItem> gestures)
421 { 421 {
422 gestures = null; 422 gestures = null;
423 BackendResponse ret; 423 BackendResponse ret;
424 UUID ownerID; 424 UUID ownerID;
425 425
426 if (Utils.TryGetOpenSimUUID(owner, out ownerID)) 426 if (Utils.TryGetOpenSimUUID(owner, out ownerID))
427 { 427 {
428 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) 428 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
429 { 429 {
430 IDataReader reader; 430 IDataReader reader;
431 431
432 try 432 try
433 { 433 {
434 dbConnection.Open(); 434 dbConnection.Open();
435 435
436 MySqlCommand command = new MySqlCommand("SELECT assetID,inventoryName,inventoryDescription,inventoryNextPermissions," + 436 MySqlCommand command = new MySqlCommand("SELECT assetID,inventoryName,inventoryDescription,inventoryNextPermissions," +
437 "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," + 437 "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," +
438 "creationDate,groupID,groupOwned,inventoryID,parentFolderID,inventoryGroupPermissions FROM inventoryitems WHERE " + 438 "creationDate,groupID,groupOwned,inventoryID,parentFolderID,inventoryGroupPermissions FROM inventoryitems WHERE " +
439 "avatarId=?uuid AND assetType=?type AND flags=1", dbConnection); 439 "avatarId=?uuid AND assetType=?type AND flags=1", dbConnection);
440 command.Parameters.AddWithValue("?uuid", ownerID.ToString()); 440 command.Parameters.AddWithValue("?uuid", ownerID.ToString());
441 command.Parameters.AddWithValue("?type", (int)AssetType.Gesture); 441 command.Parameters.AddWithValue("?type", (int)AssetType.Gesture);
442 reader = command.ExecuteReader(); 442 reader = command.ExecuteReader();
443 443
444 while (reader.Read()) 444 while (reader.Read())
445 { 445 {
446 InventoryItem item = new InventoryItem(); 446 InventoryItem item = new InventoryItem();
447 item.Owner = ownerID; 447 item.Owner = ownerID;
448 item.AssetType = (int)AssetType.Gesture; 448 item.AssetType = (int)AssetType.Gesture;
449 item.Flags = (uint)1; 449 item.Flags = (uint)1;
450 item.AssetID = UUID.Parse(reader.GetString(0)); 450 item.AssetID = UUID.Parse(reader.GetString(0));
451 item.Name = reader.GetString(1); 451 item.Name = reader.GetString(1);
452 item.Description = reader.GetString(2); 452 item.Description = reader.GetString(2);
453 item.NextPermissions = (uint)reader.GetInt32(3); 453 item.NextPermissions = (uint)reader.GetInt32(3);
454 item.CurrentPermissions = (uint)reader.GetInt32(4); 454 item.CurrentPermissions = (uint)reader.GetInt32(4);
455 item.InvType = reader.GetInt32(5); 455 item.InvType = reader.GetInt32(5);
456 item.Creator = UUID.Parse(reader.GetString(6)); 456 item.Creator = UUID.Parse(reader.GetString(6));
457 item.BasePermissions = (uint)reader.GetInt32(7); 457 item.BasePermissions = (uint)reader.GetInt32(7);
458 item.EveryOnePermissions = (uint)reader.GetInt32(8); 458 item.EveryOnePermissions = (uint)reader.GetInt32(8);
459 item.SalePrice = reader.GetInt32(9); 459 item.SalePrice = reader.GetInt32(9);
460 item.SaleType = reader.GetByte(10); 460 item.SaleType = reader.GetByte(10);
461 item.CreationDate = reader.GetInt32(11); 461 item.CreationDate = reader.GetInt32(11);
462 item.GroupID = UUID.Parse(reader.GetString(12)); 462 item.GroupID = UUID.Parse(reader.GetString(12));
463 item.GroupOwned = reader.GetBoolean(13); 463 item.GroupOwned = reader.GetBoolean(13);
464 item.ID = UUID.Parse(reader.GetString(14)); 464 item.ID = UUID.Parse(reader.GetString(14));
465 item.Folder = UUID.Parse(reader.GetString(15)); 465 item.Folder = UUID.Parse(reader.GetString(15));
466 item.GroupPermissions = (uint)reader.GetInt32(16); 466 item.GroupPermissions = (uint)reader.GetInt32(16);
467 467
468 gestures.Add(item); 468 gestures.Add(item);
469 } 469 }
470 470
471 ret = BackendResponse.Success; 471 ret = BackendResponse.Success;
472 } 472 }
473 catch (MySqlException ex) 473 catch (MySqlException ex)
474 { 474 {
475 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); 475 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
476 ret = BackendResponse.Failure; 476 ret = BackendResponse.Failure;
477 } 477 }
478 } 478 }
479 } 479 }
480 else 480 else
481 { 481 {
482 ret = BackendResponse.NotFound; 482 ret = BackendResponse.NotFound;
483 } 483 }
484 484
485 server.MetricsProvider.LogInventoryFetchActiveGestures(EXTENSION_NAME, ret, owner, DateTime.Now); 485 server.MetricsProvider.LogInventoryFetchActiveGestures(EXTENSION_NAME, ret, owner, DateTime.Now);
486 return ret; 486 return ret;
487 } 487 }
488 488
489 public BackendResponse TryCreateItem(Uri owner, InventoryItem item) 489 public BackendResponse TryCreateItem(Uri owner, InventoryItem item)
490 { 490 {
491 BackendResponse ret; 491 BackendResponse ret;
492 492
493 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) 493 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
494 { 494 {
495 try 495 try
496 { 496 {
497 dbConnection.Open(); 497 dbConnection.Open();
498 498
499 MySqlCommand command = new MySqlCommand( 499 MySqlCommand command = new MySqlCommand(
500 "REPLACE INTO inventoryitems (assetID,assetType,inventoryName,inventoryDescription,inventoryNextPermissions," + 500 "REPLACE INTO inventoryitems (assetID,assetType,inventoryName,inventoryDescription,inventoryNextPermissions," +
501 "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," + 501 "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," +
502 "creationDate,groupID,groupOwned,flags,inventoryID,avatarID,parentFolderID,inventoryGroupPermissions) VALUES " + 502 "creationDate,groupID,groupOwned,flags,inventoryID,avatarID,parentFolderID,inventoryGroupPermissions) VALUES " +
503 503
504 "(?assetID,?assetType,?inventoryName,?inventoryDescription,?inventoryNextPermissions,?inventoryCurrentPermissions,?invType," + 504 "(?assetID,?assetType,?inventoryName,?inventoryDescription,?inventoryNextPermissions,?inventoryCurrentPermissions,?invType," +
505 "?creatorID,?inventoryBasePermissions,?inventoryEveryOnePermissions,?salePrice,?saleType,?creationDate,?groupID,?groupOwned," + 505 "?creatorID,?inventoryBasePermissions,?inventoryEveryOnePermissions,?salePrice,?saleType,?creationDate,?groupID,?groupOwned," +
506 "?flags,?inventoryID,?avatarID,?parentFolderID,?inventoryGroupPermissions)", dbConnection); 506 "?flags,?inventoryID,?avatarID,?parentFolderID,?inventoryGroupPermissions)", dbConnection);
507 507
508 command.Parameters.AddWithValue("?assetID", item.AssetID.ToString()); 508 command.Parameters.AddWithValue("?assetID", item.AssetID.ToString());
509 command.Parameters.AddWithValue("?assetType", item.AssetType); 509 command.Parameters.AddWithValue("?assetType", item.AssetType);
510 command.Parameters.AddWithValue("?inventoryName", item.Name); 510 command.Parameters.AddWithValue("?inventoryName", item.Name);
511 command.Parameters.AddWithValue("?inventoryDescription", item.Description); 511 command.Parameters.AddWithValue("?inventoryDescription", item.Description);
512 command.Parameters.AddWithValue("?inventoryNextPermissions", item.NextPermissions); 512 command.Parameters.AddWithValue("?inventoryNextPermissions", item.NextPermissions);
513 command.Parameters.AddWithValue("?inventoryCurrentPermissions", item.CurrentPermissions); 513 command.Parameters.AddWithValue("?inventoryCurrentPermissions", item.CurrentPermissions);
514 command.Parameters.AddWithValue("?invType", item.InvType); 514 command.Parameters.AddWithValue("?invType", item.InvType);
515 command.Parameters.AddWithValue("?creatorID", item.Creator.ToString()); 515 command.Parameters.AddWithValue("?creatorID", item.Creator.ToString());
516 command.Parameters.AddWithValue("?inventoryBasePermissions", item.BasePermissions); 516 command.Parameters.AddWithValue("?inventoryBasePermissions", item.BasePermissions);
517 command.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.EveryOnePermissions); 517 command.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.EveryOnePermissions);
518 command.Parameters.AddWithValue("?salePrice", item.SalePrice); 518 command.Parameters.AddWithValue("?salePrice", item.SalePrice);
519 command.Parameters.AddWithValue("?saleType", item.SaleType); 519 command.Parameters.AddWithValue("?saleType", item.SaleType);
520 command.Parameters.AddWithValue("?creationDate", item.CreationDate); 520 command.Parameters.AddWithValue("?creationDate", item.CreationDate);
521 command.Parameters.AddWithValue("?groupID", item.GroupID.ToString()); 521 command.Parameters.AddWithValue("?groupID", item.GroupID.ToString());
522 command.Parameters.AddWithValue("?groupOwned", item.GroupOwned); 522 command.Parameters.AddWithValue("?groupOwned", item.GroupOwned);
523 command.Parameters.AddWithValue("?flags", item.Flags); 523 command.Parameters.AddWithValue("?flags", item.Flags);
524 command.Parameters.AddWithValue("?inventoryID", item.ID); 524 command.Parameters.AddWithValue("?inventoryID", item.ID);
525 command.Parameters.AddWithValue("?avatarID", item.Owner); 525 command.Parameters.AddWithValue("?avatarID", item.Owner);
526 command.Parameters.AddWithValue("?parentFolderID", item.Folder); 526 command.Parameters.AddWithValue("?parentFolderID", item.Folder);
527 command.Parameters.AddWithValue("?inventoryGroupPermissions", item.GroupPermissions); 527 command.Parameters.AddWithValue("?inventoryGroupPermissions", item.GroupPermissions);
528 528
529 int rowsAffected = command.ExecuteNonQuery(); 529 int rowsAffected = command.ExecuteNonQuery();
530 if (rowsAffected == 1) 530 if (rowsAffected == 1)
531 { 531 {
532 ret = BackendResponse.Success; 532 ret = BackendResponse.Success;
533 } 533 }
534 else if (rowsAffected == 2) 534 else if (rowsAffected == 2)
535 { 535 {
536 Logger.Log.Info("Replaced inventory item " + item.ID.ToString()); 536 Logger.Log.Info("Replaced inventory item " + item.ID.ToString());
537 ret = BackendResponse.Success; 537 ret = BackendResponse.Success;
538 } 538 }
539 else 539 else
540 { 540 {
541 Logger.Log.ErrorFormat("MySQL REPLACE query affected {0} rows", rowsAffected); 541 Logger.Log.ErrorFormat("MySQL REPLACE query affected {0} rows", rowsAffected);
542 ret = BackendResponse.Failure; 542 ret = BackendResponse.Failure;
543 } 543 }
544 } 544 }
545 catch (MySqlException ex) 545 catch (MySqlException ex)
546 { 546 {
547 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); 547 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
548 ret = BackendResponse.Failure; 548 ret = BackendResponse.Failure;
549 } 549 }
550 } 550 }
551 551
552 server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, false, DateTime.Now); 552 server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, false, DateTime.Now);
553 return ret; 553 return ret;
554 } 554 }
555 555
556 public BackendResponse TryCreateFolder(Uri owner, InventoryFolder folder) 556 public BackendResponse TryCreateFolder(Uri owner, InventoryFolder folder)
557 { 557 {
558 BackendResponse ret; 558 BackendResponse ret;
559 559
560 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) 560 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
561 { 561 {
562 try 562 try
563 { 563 {
564 dbConnection.Open(); 564 dbConnection.Open();
565 565
566 MySqlCommand command = new MySqlCommand( 566 MySqlCommand command = new MySqlCommand(
567 "REPLACE INTO inventoryfolders (folderName,type,version,folderID,agentID,parentFolderID) VALUES " + 567 "REPLACE INTO inventoryfolders (folderName,type,version,folderID,agentID,parentFolderID) VALUES " +
568 "(?folderName,?type,?version,?folderID,?agentID,?parentFolderID)", dbConnection); 568 "(?folderName,?type,?version,?folderID,?agentID,?parentFolderID)", dbConnection);
569 569
570 command.Parameters.AddWithValue("?folderName", folder.Name); 570 command.Parameters.AddWithValue("?folderName", folder.Name);
571 command.Parameters.AddWithValue("?type", folder.Type); 571 command.Parameters.AddWithValue("?type", folder.Type);
572 command.Parameters.AddWithValue("?version", folder.Version); 572 command.Parameters.AddWithValue("?version", folder.Version);
573 command.Parameters.AddWithValue("?folderID", folder.ID); 573 command.Parameters.AddWithValue("?folderID", folder.ID);
574 command.Parameters.AddWithValue("?agentID", folder.Owner); 574 command.Parameters.AddWithValue("?agentID", folder.Owner);
575 command.Parameters.AddWithValue("?parentFolderID", folder.ParentID); 575 command.Parameters.AddWithValue("?parentFolderID", folder.ParentID);
576 576
577 int rowsAffected = command.ExecuteNonQuery(); 577 int rowsAffected = command.ExecuteNonQuery();
578 if (rowsAffected == 1) 578 if (rowsAffected == 1)
579 { 579 {
580 ret = BackendResponse.Success; 580 ret = BackendResponse.Success;
581 } 581 }
582 else if (rowsAffected == 2) 582 else if (rowsAffected == 2)
583 { 583 {
584 Logger.Log.Info("Replaced inventory folder " + folder.ID.ToString()); 584 Logger.Log.Info("Replaced inventory folder " + folder.ID.ToString());
585 ret = BackendResponse.Success; 585 ret = BackendResponse.Success;
586 } 586 }
587 else 587 else
588 { 588 {
589 Logger.Log.ErrorFormat("MySQL REPLACE query affected {0} rows", rowsAffected); 589 Logger.Log.ErrorFormat("MySQL REPLACE query affected {0} rows", rowsAffected);
590 ret = BackendResponse.Failure; 590 ret = BackendResponse.Failure;
591 } 591 }
592 } 592 }
593 catch (MySqlException ex) 593 catch (MySqlException ex)
594 { 594 {
595 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); 595 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
596 ret = BackendResponse.Failure; 596 ret = BackendResponse.Failure;
597 } 597 }
598 } 598 }
599 599
600 server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, true, DateTime.Now); 600 server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, true, DateTime.Now);
601 return ret; 601 return ret;
602 } 602 }
603 603
604 public BackendResponse TryCreateInventory(Uri owner, InventoryFolder rootFolder) 604 public BackendResponse TryCreateInventory(Uri owner, InventoryFolder rootFolder)
605 { 605 {
606 return TryCreateFolder(owner, rootFolder); 606 return TryCreateFolder(owner, rootFolder);
607 } 607 }
608 608
609 public BackendResponse TryDeleteItem(Uri owner, UUID itemID) 609 public BackendResponse TryDeleteItem(Uri owner, UUID itemID)
610 { 610 {
611 BackendResponse ret; 611 BackendResponse ret;
612 UUID ownerID; 612 UUID ownerID;
613 613
614 if (Utils.TryGetOpenSimUUID(owner, out ownerID)) 614 if (Utils.TryGetOpenSimUUID(owner, out ownerID))
615 { 615 {
616 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) 616 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
617 { 617 {
618 try 618 try
619 { 619 {
620 dbConnection.Open(); 620 dbConnection.Open();
621 621
622 MySqlCommand command = new MySqlCommand( 622 MySqlCommand command = new MySqlCommand(
623 "DELETE FROM inventoryitems WHERE inventoryID=?inventoryID AND avatarID=?avatarID", dbConnection); 623 "DELETE FROM inventoryitems WHERE inventoryID=?inventoryID AND avatarID=?avatarID", dbConnection);
624 624
625 command.Parameters.AddWithValue("?inventoryID", itemID.ToString()); 625 command.Parameters.AddWithValue("?inventoryID", itemID.ToString());
626 command.Parameters.AddWithValue("?avatarID", ownerID.ToString()); 626 command.Parameters.AddWithValue("?avatarID", ownerID.ToString());
627 627
628 int rowsAffected = command.ExecuteNonQuery(); 628 int rowsAffected = command.ExecuteNonQuery();
629 if (rowsAffected == 1) 629 if (rowsAffected == 1)
630 { 630 {
631 ret = BackendResponse.Success; 631 ret = BackendResponse.Success;
632 } 632 }
633 else 633 else
634 { 634 {
635 Logger.Log.ErrorFormat("MySQL DELETE query affected {0} rows", rowsAffected); 635 Logger.Log.ErrorFormat("MySQL DELETE query affected {0} rows", rowsAffected);
636 ret = BackendResponse.NotFound; 636 ret = BackendResponse.NotFound;
637 } 637 }
638 } 638 }
639 catch (MySqlException ex) 639 catch (MySqlException ex)
640 { 640 {
641 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); 641 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
642 ret = BackendResponse.Failure; 642 ret = BackendResponse.Failure;
643 } 643 }
644 } 644 }
645 } 645 }
646 else 646 else
647 { 647 {
648 ret = BackendResponse.NotFound; 648 ret = BackendResponse.NotFound;
649 } 649 }
650 650
651 server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now); 651 server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now);
652 return ret; 652 return ret;
653 } 653 }
654 654
655 public BackendResponse TryDeleteFolder(Uri owner, UUID folderID) 655 public BackendResponse TryDeleteFolder(Uri owner, UUID folderID)
656 { 656 {
657 BackendResponse ret; 657 BackendResponse ret;
658 UUID ownerID; 658 UUID ownerID;
659 659
660 if (Utils.TryGetOpenSimUUID(owner, out ownerID)) 660 if (Utils.TryGetOpenSimUUID(owner, out ownerID))
661 { 661 {
662 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) 662 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
663 { 663 {
664 try 664 try
665 { 665 {
666 dbConnection.Open(); 666 dbConnection.Open();
667 667
668 MySqlCommand command = new MySqlCommand( 668 MySqlCommand command = new MySqlCommand(
669 "DELETE FROM inventoryfolders WHERE folderID=?folderID AND agentID=?agentID", dbConnection); 669 "DELETE FROM inventoryfolders WHERE folderID=?folderID AND agentID=?agentID", dbConnection);
670 670
671 command.Parameters.AddWithValue("?folderID", folderID.ToString()); 671 command.Parameters.AddWithValue("?folderID", folderID.ToString());
672 command.Parameters.AddWithValue("?agentID", ownerID.ToString()); 672 command.Parameters.AddWithValue("?agentID", ownerID.ToString());
673 673
674 int rowsAffected = command.ExecuteNonQuery(); 674 int rowsAffected = command.ExecuteNonQuery();
675 if (rowsAffected == 1) 675 if (rowsAffected == 1)
676 { 676 {
677 ret = BackendResponse.Success; 677 ret = BackendResponse.Success;
678 } 678 }
679 else 679 else
680 { 680 {
681 Logger.Log.ErrorFormat("MySQL DELETE query affected {0} rows", rowsAffected); 681 Logger.Log.ErrorFormat("MySQL DELETE query affected {0} rows", rowsAffected);
682 ret = BackendResponse.NotFound; 682 ret = BackendResponse.NotFound;
683 } 683 }
684 } 684 }
685 catch (MySqlException ex) 685 catch (MySqlException ex)
686 { 686 {
687 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); 687 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
688 ret = BackendResponse.Failure; 688 ret = BackendResponse.Failure;
689 } 689 }
690 } 690 }
691 } 691 }
692 else 692 else
693 { 693 {
694 ret = BackendResponse.NotFound; 694 ret = BackendResponse.NotFound;
695 } 695 }
696 696
697 server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now); 697 server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now);
698 return ret; 698 return ret;
699 } 699 }
700 700
701 public BackendResponse TryPurgeFolder(Uri owner, UUID folderID) 701 public BackendResponse TryPurgeFolder(Uri owner, UUID folderID)
702 { 702 {
703 BackendResponse ret; 703 BackendResponse ret;
704 UUID ownerID; 704 UUID ownerID;
705 705
706 if (Utils.TryGetOpenSimUUID(owner, out ownerID)) 706 if (Utils.TryGetOpenSimUUID(owner, out ownerID))
707 { 707 {
708 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) 708 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
709 { 709 {
710 try 710 try
711 { 711 {
712 dbConnection.Open(); 712 dbConnection.Open();
713 713
714 #region Delete items 714 #region Delete items
715 715
716 MySqlCommand command = new MySqlCommand( 716 MySqlCommand command = new MySqlCommand(
717 "DELETE FROM inventoryitems WHERE parentFolderID=?parentFolderID AND avatarID=?avatarID", dbConnection); 717 "DELETE FROM inventoryitems WHERE parentFolderID=?parentFolderID AND avatarID=?avatarID", dbConnection);
718 718
719 command.Parameters.AddWithValue("?parentFolderID", folderID.ToString()); 719 command.Parameters.AddWithValue("?parentFolderID", folderID.ToString());
720 command.Parameters.AddWithValue("?avatarID", ownerID.ToString()); 720 command.Parameters.AddWithValue("?avatarID", ownerID.ToString());
721 721
722 int rowsAffected = command.ExecuteNonQuery(); 722 int rowsAffected = command.ExecuteNonQuery();
723 723
724 #endregion Delete items 724 #endregion Delete items
725 725
726 #region Delete folders 726 #region Delete folders
727 727
728 command = new MySqlCommand( 728 command = new MySqlCommand(
729 "DELETE FROM inventoryfolders WHERE parentFolderID=?parentFolderID AND agentID=?agentID", dbConnection); 729 "DELETE FROM inventoryfolders WHERE parentFolderID=?parentFolderID AND agentID=?agentID", dbConnection);
730 730
731 command.Parameters.AddWithValue("?parentFolderID", folderID.ToString()); 731 command.Parameters.AddWithValue("?parentFolderID", folderID.ToString());
732 command.Parameters.AddWithValue("?agentID", ownerID.ToString()); 732 command.Parameters.AddWithValue("?agentID", ownerID.ToString());
733 733
734 rowsAffected += command.ExecuteNonQuery(); 734 rowsAffected += command.ExecuteNonQuery();
735 735
736 #endregion Delete folders 736 #endregion Delete folders
737 737
738 Logger.Log.DebugFormat("Deleted {0} inventory objects from MySQL in a folder purge", rowsAffected); 738 Logger.Log.DebugFormat("Deleted {0} inventory objects from MySQL in a folder purge", rowsAffected);
739 739
740 ret = BackendResponse.Success; 740 ret = BackendResponse.Success;
741 } 741 }
742 catch (MySqlException ex) 742 catch (MySqlException ex)
743 { 743 {
744 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); 744 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
745 ret = BackendResponse.Failure; 745 ret = BackendResponse.Failure;
746 } 746 }
747 } 747 }
748 } 748 }
749 else 749 else
750 { 750 {
751 ret = BackendResponse.NotFound; 751 ret = BackendResponse.NotFound;
752 } 752 }
753 753
754 server.MetricsProvider.LogInventoryPurgeFolder(EXTENSION_NAME, ret, owner, folderID, DateTime.Now); 754 server.MetricsProvider.LogInventoryPurgeFolder(EXTENSION_NAME, ret, owner, folderID, DateTime.Now);
755 return ret; 755 return ret;
756 } 756 }
757 757
758 public int ForEach(Action<Metadata> action, int start, int count) 758 public int ForEach(Action<Metadata> action, int start, int count)
759 { 759 {
760 int rowCount = 0; 760 int rowCount = 0;
761 761
762 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) 762 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
763 { 763 {
764 MySqlDataReader reader; 764 MySqlDataReader reader;
765 765
766 try 766 try
767 { 767 {
768 dbConnection.Open(); 768 dbConnection.Open();
769 769
770 MySqlCommand command = dbConnection.CreateCommand(); 770 MySqlCommand command = dbConnection.CreateCommand();
771 command.CommandText = String.Format("SELECT name,description,assetType,temporary,data,id FROM assets LIMIT {0}, {1}", 771 command.CommandText = String.Format("SELECT name,description,assetType,temporary,data,id FROM assets LIMIT {0}, {1}",
772 start, count); 772 start, count);
773 reader = command.ExecuteReader(); 773 reader = command.ExecuteReader();
774 } 774 }
775 catch (MySqlException ex) 775 catch (MySqlException ex)
776 { 776 {
777 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); 777 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
778 return 0; 778 return 0;
779 } 779 }
780 780
781 while (reader.Read()) 781 while (reader.Read())
782 { 782 {
783 Metadata metadata = new Metadata(); 783 Metadata metadata = new Metadata();
784 metadata.CreationDate = OpenMetaverse.Utils.Epoch; 784 metadata.CreationDate = OpenMetaverse.Utils.Epoch;
785 metadata.Description = reader.GetString(1); 785 metadata.Description = reader.GetString(1);
786 metadata.ID = UUID.Parse(reader.GetString(5)); 786 metadata.ID = UUID.Parse(reader.GetString(5));
787 metadata.Name = reader.GetString(0); 787 metadata.Name = reader.GetString(0);
788 metadata.SHA1 = OpenMetaverse.Utils.SHA1((byte[])reader.GetValue(4)); 788 metadata.SHA1 = OpenMetaverse.Utils.SHA1((byte[])reader.GetValue(4));
789 metadata.Temporary = reader.GetBoolean(3); 789 metadata.Temporary = reader.GetBoolean(3);
790 metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2)); 790 metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2));
791 791
792 action(metadata); 792 action(metadata);
793 ++rowCount; 793 ++rowCount;
794 } 794 }
795 795
796 reader.Close(); 796 reader.Close();
797 } 797 }
798 798
799 return rowCount; 799 return rowCount;
800 } 800 }
801 801
802 #endregion Required Interfaces 802 #endregion Required Interfaces
803 } 803 }
804} 804}
diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLStorage.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLStorage.cs
index 36528b0..48fa25b 100644
--- a/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLStorage.cs
+++ b/OpenSim/Grid/AssetInventoryServer/Extensions/OpenSimMySQLStorage.cs
@@ -1,311 +1,311 @@
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
30using System; 30using System;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Net; 32using System.Net;
33using System.Data; 33using System.Data;
34using MySql.Data.MySqlClient; 34using MySql.Data.MySqlClient;
35using ExtensionLoader; 35using ExtensionLoader;
36using ExtensionLoader.Config; 36using ExtensionLoader.Config;
37using OpenMetaverse; 37using OpenMetaverse;
38using OpenMetaverse.StructuredData; 38using OpenMetaverse.StructuredData;
39 39
40namespace OpenSim.Grid.AssetInventoryServer.Extensions 40namespace OpenSim.Grid.AssetInventoryServer.Extensions
41{ 41{
42 public class OpenSimMySQLStorage : IExtension<AssetInventoryServer>, IStorageProvider 42 public class OpenSimMySQLStorage : IExtension<AssetInventoryServer>, IStorageProvider
43 { 43 {
44 const string EXTENSION_NAME = "OpenSimMySQLStorage"; // Used in metrics reporting 44 const string EXTENSION_NAME = "OpenSimMySQLStorage"; // Used in metrics reporting
45 45
46 AssetInventoryServer server; 46 AssetInventoryServer server;
47 47
48 public OpenSimMySQLStorage() 48 public OpenSimMySQLStorage()
49 { 49 {
50 } 50 }
51 51
52 #region Required Interfaces 52 #region Required Interfaces
53 53
54 public void Start(AssetInventoryServer server) 54 public void Start(AssetInventoryServer server)
55 { 55 {
56 this.server = server; 56 this.server = server;
57 57
58 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) 58 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
59 { 59 {
60 try 60 try
61 { 61 {
62 dbConnection.Open(); 62 dbConnection.Open();
63 Logger.Log.Info("Connected to MySQL storage backend: " + dbConnection.ServerVersion); 63 Logger.Log.Info("Connected to MySQL storage backend: " + dbConnection.ServerVersion);
64 } 64 }
65 catch (MySqlException ex) 65 catch (MySqlException ex)
66 { 66 {
67 Logger.Log.Error("Connection to MySQL storage backend failed: " + ex.Message); 67 Logger.Log.Error("Connection to MySQL storage backend failed: " + ex.Message);
68 } 68 }
69 } 69 }
70 } 70 }
71 71
72 public void Stop() 72 public void Stop()
73 { 73 {
74 } 74 }
75 75
76 public BackendResponse TryFetchMetadata(UUID assetID, out Metadata metadata) 76 public BackendResponse TryFetchMetadata(UUID assetID, out Metadata metadata)
77 { 77 {
78 metadata = null; 78 metadata = null;
79 BackendResponse ret; 79 BackendResponse ret;
80 80
81 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) 81 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
82 { 82 {
83 IDataReader reader; 83 IDataReader reader;
84 84
85 try 85 try
86 { 86 {
87 dbConnection.Open(); 87 dbConnection.Open();
88 88
89 IDbCommand command = dbConnection.CreateCommand(); 89 IDbCommand command = dbConnection.CreateCommand();
90 command.CommandText = String.Format("SELECT name,description,assetType,temporary FROM assets WHERE id='{0}'", assetID.ToString()); 90 command.CommandText = String.Format("SELECT name,description,assetType,temporary FROM assets WHERE id='{0}'", assetID.ToString());
91 reader = command.ExecuteReader(); 91 reader = command.ExecuteReader();
92 92
93 if (reader.Read()) 93 if (reader.Read())
94 { 94 {
95 metadata = new Metadata(); 95 metadata = new Metadata();
96 metadata.CreationDate = OpenMetaverse.Utils.Epoch; 96 metadata.CreationDate = OpenMetaverse.Utils.Epoch;
97 metadata.SHA1 = null; 97 metadata.SHA1 = null;
98 metadata.ID = assetID; 98 metadata.ID = assetID;
99 metadata.Name = reader.GetString(0); 99 metadata.Name = reader.GetString(0);
100 metadata.Description = reader.GetString(1); 100 metadata.Description = reader.GetString(1);
101 metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2)); 101 metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2));
102 metadata.Temporary = reader.GetBoolean(3); 102 metadata.Temporary = reader.GetBoolean(3);
103 103
104 ret = BackendResponse.Success; 104 ret = BackendResponse.Success;
105 } 105 }
106 else 106 else
107 { 107 {
108 ret = BackendResponse.NotFound; 108 ret = BackendResponse.NotFound;
109 } 109 }
110 } 110 }
111 catch (MySqlException ex) 111 catch (MySqlException ex)
112 { 112 {
113 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); 113 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
114 ret = BackendResponse.Failure; 114 ret = BackendResponse.Failure;
115 } 115 }
116 } 116 }
117 117
118 server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now); 118 server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now);
119 return ret; 119 return ret;
120 } 120 }
121 121
122 public BackendResponse TryFetchData(UUID assetID, out byte[] assetData) 122 public BackendResponse TryFetchData(UUID assetID, out byte[] assetData)
123 { 123 {
124 assetData = null; 124 assetData = null;
125 BackendResponse ret; 125 BackendResponse ret;
126 126
127 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) 127 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
128 { 128 {
129 IDataReader reader; 129 IDataReader reader;
130 130
131 try 131 try
132 { 132 {
133 dbConnection.Open(); 133 dbConnection.Open();
134 134
135 IDbCommand command = dbConnection.CreateCommand(); 135 IDbCommand command = dbConnection.CreateCommand();
136 command.CommandText = String.Format("SELECT data FROM assets WHERE id='{0}'", assetID.ToString()); 136 command.CommandText = String.Format("SELECT data FROM assets WHERE id='{0}'", assetID.ToString());
137 reader = command.ExecuteReader(); 137 reader = command.ExecuteReader();
138 138
139 if (reader.Read()) 139 if (reader.Read())
140 { 140 {
141 assetData = (byte[])reader.GetValue(0); 141 assetData = (byte[])reader.GetValue(0);
142 ret = BackendResponse.Success; 142 ret = BackendResponse.Success;
143 } 143 }
144 else 144 else
145 { 145 {
146 ret = BackendResponse.NotFound; 146 ret = BackendResponse.NotFound;
147 } 147 }
148 } 148 }
149 catch (MySqlException ex) 149 catch (MySqlException ex)
150 { 150 {
151 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); 151 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
152 ret = BackendResponse.Failure; 152 ret = BackendResponse.Failure;
153 } 153 }
154 } 154 }
155 155
156 server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (assetData != null ? assetData.Length : 0), DateTime.Now); 156 server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (assetData != null ? assetData.Length : 0), DateTime.Now);
157 return ret; 157 return ret;
158 } 158 }
159 159
160 public BackendResponse TryFetchDataMetadata(UUID assetID, out Metadata metadata, out byte[] assetData) 160 public BackendResponse TryFetchDataMetadata(UUID assetID, out Metadata metadata, out byte[] assetData)
161 { 161 {
162 metadata = null; 162 metadata = null;
163 assetData = null; 163 assetData = null;
164 BackendResponse ret; 164 BackendResponse ret;
165 165
166 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) 166 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
167 { 167 {
168 IDataReader reader; 168 IDataReader reader;
169 169
170 try 170 try
171 { 171 {
172 dbConnection.Open(); 172 dbConnection.Open();
173 173
174 IDbCommand command = dbConnection.CreateCommand(); 174 IDbCommand command = dbConnection.CreateCommand();
175 command.CommandText = String.Format("SELECT name,description,assetType,temporary,data FROM assets WHERE id='{0}'", assetID.ToString()); 175 command.CommandText = String.Format("SELECT name,description,assetType,temporary,data FROM assets WHERE id='{0}'", assetID.ToString());
176 reader = command.ExecuteReader(); 176 reader = command.ExecuteReader();
177 177
178 if (reader.Read()) 178 if (reader.Read())
179 { 179 {
180 metadata = new Metadata(); 180 metadata = new Metadata();
181 metadata.CreationDate = OpenMetaverse.Utils.Epoch; 181 metadata.CreationDate = OpenMetaverse.Utils.Epoch;
182 metadata.SHA1 = null; 182 metadata.SHA1 = null;
183 metadata.ID = assetID; 183 metadata.ID = assetID;
184 metadata.Name = reader.GetString(0); 184 metadata.Name = reader.GetString(0);
185 metadata.Description = reader.GetString(1); 185 metadata.Description = reader.GetString(1);
186 metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2)); 186 metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2));
187 metadata.Temporary = reader.GetBoolean(3); 187 metadata.Temporary = reader.GetBoolean(3);
188 188
189 assetData = (byte[])reader.GetValue(4); 189 assetData = (byte[])reader.GetValue(4);
190 190
191 ret = BackendResponse.Success; 191 ret = BackendResponse.Success;
192 } 192 }
193 else 193 else
194 { 194 {
195 ret = BackendResponse.NotFound; 195 ret = BackendResponse.NotFound;
196 } 196 }
197 } 197 }
198 catch (MySqlException ex) 198 catch (MySqlException ex)
199 { 199 {
200 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); 200 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
201 ret = BackendResponse.Failure; 201 ret = BackendResponse.Failure;
202 } 202 }
203 } 203 }
204 204
205 server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now); 205 server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now);
206 server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (assetData != null ? assetData.Length : 0), DateTime.Now); 206 server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (assetData != null ? assetData.Length : 0), DateTime.Now);
207 return ret; 207 return ret;
208 } 208 }
209 209
210 public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData, out UUID assetID) 210 public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData, out UUID assetID)
211 { 211 {
212 assetID = metadata.ID = UUID.Random(); 212 assetID = metadata.ID = UUID.Random();
213 return TryCreateAsset(metadata, assetData); 213 return TryCreateAsset(metadata, assetData);
214 } 214 }
215 215
216 public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData) 216 public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData)
217 { 217 {
218 BackendResponse ret; 218 BackendResponse ret;
219 219
220 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) 220 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
221 { 221 {
222 try 222 try
223 { 223 {
224 dbConnection.Open(); 224 dbConnection.Open();
225 225
226 MySqlCommand command = new MySqlCommand( 226 MySqlCommand command = new MySqlCommand(
227 "REPLACE INTO assets (name,description,assetType,local,temporary,data,id) VALUES " + 227 "REPLACE INTO assets (name,description,assetType,local,temporary,data,id) VALUES " +
228 "(?name,?description,?assetType,?local,?temporary,?data,?id)", dbConnection); 228 "(?name,?description,?assetType,?local,?temporary,?data,?id)", dbConnection);
229 229
230 command.Parameters.AddWithValue("?name", metadata.Name); 230 command.Parameters.AddWithValue("?name", metadata.Name);
231 command.Parameters.AddWithValue("?description", metadata.Description); 231 command.Parameters.AddWithValue("?description", metadata.Description);
232 command.Parameters.AddWithValue("?assetType", Utils.ContentTypeToSLAssetType(metadata.ContentType)); 232 command.Parameters.AddWithValue("?assetType", Utils.ContentTypeToSLAssetType(metadata.ContentType));
233 command.Parameters.AddWithValue("?local", 0); 233 command.Parameters.AddWithValue("?local", 0);
234 command.Parameters.AddWithValue("?temporary", metadata.Temporary); 234 command.Parameters.AddWithValue("?temporary", metadata.Temporary);
235 command.Parameters.AddWithValue("?data", assetData); 235 command.Parameters.AddWithValue("?data", assetData);
236 command.Parameters.AddWithValue("?id", metadata.ID.ToString()); 236 command.Parameters.AddWithValue("?id", metadata.ID.ToString());
237 237
238 int rowsAffected = command.ExecuteNonQuery(); 238 int rowsAffected = command.ExecuteNonQuery();
239 if (rowsAffected == 1) 239 if (rowsAffected == 1)
240 { 240 {
241 ret = BackendResponse.Success; 241 ret = BackendResponse.Success;
242 } 242 }
243 else if (rowsAffected == 2) 243 else if (rowsAffected == 2)
244 { 244 {
245 Logger.Log.Info("Replaced asset " + metadata.ID.ToString()); 245 Logger.Log.Info("Replaced asset " + metadata.ID.ToString());
246 ret = BackendResponse.Success; 246 ret = BackendResponse.Success;
247 } 247 }
248 else 248 else
249 { 249 {
250 Logger.Log.ErrorFormat("MySQL REPLACE query affected {0} rows", rowsAffected); 250 Logger.Log.ErrorFormat("MySQL REPLACE query affected {0} rows", rowsAffected);
251 ret = BackendResponse.Failure; 251 ret = BackendResponse.Failure;
252 } 252 }
253 } 253 }
254 catch (MySqlException ex) 254 catch (MySqlException ex)
255 { 255 {
256 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); 256 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
257 ret = BackendResponse.Failure; 257 ret = BackendResponse.Failure;
258 } 258 }
259 } 259 }
260 260
261 server.MetricsProvider.LogAssetCreate(EXTENSION_NAME, ret, metadata.ID, assetData.Length, DateTime.Now); 261 server.MetricsProvider.LogAssetCreate(EXTENSION_NAME, ret, metadata.ID, assetData.Length, DateTime.Now);
262 return ret; 262 return ret;
263 } 263 }
264 264
265 public int ForEach(Action<Metadata> action, int start, int count) 265 public int ForEach(Action<Metadata> action, int start, int count)
266 { 266 {
267 int rowCount = 0; 267 int rowCount = 0;
268 268
269 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) 269 using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile)))
270 { 270 {
271 MySqlDataReader reader; 271 MySqlDataReader reader;
272 272
273 try 273 try
274 { 274 {
275 dbConnection.Open(); 275 dbConnection.Open();
276 276
277 MySqlCommand command = dbConnection.CreateCommand(); 277 MySqlCommand command = dbConnection.CreateCommand();
278 command.CommandText = String.Format("SELECT name,description,assetType,temporary,data,id FROM assets LIMIT {0}, {1}", 278 command.CommandText = String.Format("SELECT name,description,assetType,temporary,data,id FROM assets LIMIT {0}, {1}",
279 start, count); 279 start, count);
280 reader = command.ExecuteReader(); 280 reader = command.ExecuteReader();
281 } 281 }
282 catch (MySqlException ex) 282 catch (MySqlException ex)
283 { 283 {
284 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); 284 Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message);
285 return 0; 285 return 0;
286 } 286 }
287 287
288 while (reader.Read()) 288 while (reader.Read())
289 { 289 {
290 Metadata metadata = new Metadata(); 290 Metadata metadata = new Metadata();
291 metadata.CreationDate = OpenMetaverse.Utils.Epoch; 291 metadata.CreationDate = OpenMetaverse.Utils.Epoch;
292 metadata.Description = reader.GetString(1); 292 metadata.Description = reader.GetString(1);
293 metadata.ID = UUID.Parse(reader.GetString(5)); 293 metadata.ID = UUID.Parse(reader.GetString(5));
294 metadata.Name = reader.GetString(0); 294 metadata.Name = reader.GetString(0);
295 metadata.SHA1 = OpenMetaverse.Utils.SHA1((byte[])reader.GetValue(4)); 295 metadata.SHA1 = OpenMetaverse.Utils.SHA1((byte[])reader.GetValue(4));
296 metadata.Temporary = reader.GetBoolean(3); 296 metadata.Temporary = reader.GetBoolean(3);
297 metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2)); 297 metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2));
298 298
299 action(metadata); 299 action(metadata);
300 ++rowCount; 300 ++rowCount;
301 } 301 }
302 302
303 reader.Close(); 303 reader.Close();
304 } 304 }
305 305
306 return rowCount; 306 return rowCount;
307 } 307 }
308 308
309 #endregion Required Interfaces 309 #endregion Required Interfaces
310 } 310 }
311} 311}
diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/ReferenceFrontend.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/ReferenceFrontend.cs
index 454984e..df6bd95 100644
--- a/OpenSim/Grid/AssetInventoryServer/Extensions/ReferenceFrontend.cs
+++ b/OpenSim/Grid/AssetInventoryServer/Extensions/ReferenceFrontend.cs
@@ -1,239 +1,239 @@
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
30using System; 30using System;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Net; 32using System.Net;
33using System.Xml; 33using System.Xml;
34using ExtensionLoader; 34using ExtensionLoader;
35using OpenMetaverse; 35using OpenMetaverse;
36using OpenMetaverse.StructuredData; 36using OpenMetaverse.StructuredData;
37using HttpServer; 37using HttpServer;
38 38
39namespace OpenSim.Grid.AssetInventoryServer.Extensions 39namespace OpenSim.Grid.AssetInventoryServer.Extensions
40{ 40{
41 public class ReferenceFrontend : IExtension<AssetInventoryServer> 41 public class ReferenceFrontend : IExtension<AssetInventoryServer>
42 { 42 {
43 AssetInventoryServer server; 43 AssetInventoryServer server;
44 44
45 public ReferenceFrontend() 45 public ReferenceFrontend()
46 { 46 {
47 } 47 }
48 48
49 public void Start(AssetInventoryServer server) 49 public void Start(AssetInventoryServer server)
50 { 50 {
51 this.server = server; 51 this.server = server;
52 52
53 // Asset metadata request 53 // Asset metadata request
54 server.HttpServer.AddHandler("get", null, @"^/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/metadata", 54 server.HttpServer.AddHandler("get", null, @"^/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/metadata",
55 MetadataRequestHandler); 55 MetadataRequestHandler);
56 56
57 // Asset data request 57 // Asset data request
58 server.HttpServer.AddHandler("get", null, @"^/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/data", 58 server.HttpServer.AddHandler("get", null, @"^/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/data",
59 DataRequestHandler); 59 DataRequestHandler);
60 60
61 // Asset creation 61 // Asset creation
62 server.HttpServer.AddHandler("post", null, "^/createasset", CreateRequestHandler); 62 server.HttpServer.AddHandler("post", null, "^/createasset", CreateRequestHandler);
63 } 63 }
64 64
65 public void Stop() 65 public void Stop()
66 { 66 {
67 } 67 }
68 68
69 bool MetadataRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) 69 bool MetadataRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
70 { 70 {
71 UUID assetID; 71 UUID assetID;
72 // Split the URL up into an AssetID and a method 72 // Split the URL up into an AssetID and a method
73 string[] rawUrl = request.Uri.PathAndQuery.Split('/'); 73 string[] rawUrl = request.Uri.PathAndQuery.Split('/');
74 74
75 if (rawUrl.Length >= 3 && UUID.TryParse(rawUrl[1], out assetID)) 75 if (rawUrl.Length >= 3 && UUID.TryParse(rawUrl[1], out assetID))
76 { 76 {
77 UUID authToken = Utils.GetAuthToken(request); 77 UUID authToken = Utils.GetAuthToken(request);
78 78
79 if (server.AuthorizationProvider.IsMetadataAuthorized(authToken, assetID)) 79 if (server.AuthorizationProvider.IsMetadataAuthorized(authToken, assetID))
80 { 80 {
81 Metadata metadata; 81 Metadata metadata;
82 BackendResponse storageResponse = server.StorageProvider.TryFetchMetadata(assetID, out metadata); 82 BackendResponse storageResponse = server.StorageProvider.TryFetchMetadata(assetID, out metadata);
83 83
84 if (storageResponse == BackendResponse.Success) 84 if (storageResponse == BackendResponse.Success)
85 { 85 {
86 // If the asset data location wasn't specified in the metadata, specify it 86 // If the asset data location wasn't specified in the metadata, specify it
87 // manually here by pointing back to this asset server 87 // manually here by pointing back to this asset server
88 if (!metadata.Methods.ContainsKey("data")) 88 if (!metadata.Methods.ContainsKey("data"))
89 { 89 {
90 metadata.Methods["data"] = new Uri(String.Format("{0}://{1}/{2}/data", 90 metadata.Methods["data"] = new Uri(String.Format("{0}://{1}/{2}/data",
91 request.Uri.Scheme, request.Uri.Authority, assetID)); 91 request.Uri.Scheme, request.Uri.Authority, assetID));
92 } 92 }
93 93
94 byte[] serializedData = metadata.SerializeToBytes(); 94 byte[] serializedData = metadata.SerializeToBytes();
95 95
96 response.Status = HttpStatusCode.OK; 96 response.Status = HttpStatusCode.OK;
97 response.ContentType = "application/json"; 97 response.ContentType = "application/json";
98 response.ContentLength = serializedData.Length; 98 response.ContentLength = serializedData.Length;
99 response.Body.Write(serializedData, 0, serializedData.Length); 99 response.Body.Write(serializedData, 0, serializedData.Length);
100 100
101 } 101 }
102 else if (storageResponse == BackendResponse.NotFound) 102 else if (storageResponse == BackendResponse.NotFound)
103 { 103 {
104 Logger.Log.Warn("Could not find metadata for asset " + assetID.ToString()); 104 Logger.Log.Warn("Could not find metadata for asset " + assetID.ToString());
105 response.Status = HttpStatusCode.NotFound; 105 response.Status = HttpStatusCode.NotFound;
106 } 106 }
107 else 107 else
108 { 108 {
109 response.Status = HttpStatusCode.InternalServerError; 109 response.Status = HttpStatusCode.InternalServerError;
110 } 110 }
111 } 111 }
112 else 112 else
113 { 113 {
114 response.Status = HttpStatusCode.Forbidden; 114 response.Status = HttpStatusCode.Forbidden;
115 } 115 }
116 116
117 return true; 117 return true;
118 } 118 }
119 119
120 response.Status = HttpStatusCode.NotFound; 120 response.Status = HttpStatusCode.NotFound;
121 return true; 121 return true;
122 } 122 }
123 123
124 bool DataRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) 124 bool DataRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
125 { 125 {
126 UUID assetID; 126 UUID assetID;
127 // Split the URL up into an AssetID and a method 127 // Split the URL up into an AssetID and a method
128 string[] rawUrl = request.Uri.PathAndQuery.Split('/'); 128 string[] rawUrl = request.Uri.PathAndQuery.Split('/');
129 129
130 if (rawUrl.Length >= 3 && UUID.TryParse(rawUrl[1], out assetID)) 130 if (rawUrl.Length >= 3 && UUID.TryParse(rawUrl[1], out assetID))
131 { 131 {
132 UUID authToken = Utils.GetAuthToken(request); 132 UUID authToken = Utils.GetAuthToken(request);
133 133
134 if (server.AuthorizationProvider.IsDataAuthorized(authToken, assetID)) 134 if (server.AuthorizationProvider.IsDataAuthorized(authToken, assetID))
135 { 135 {
136 byte[] assetData; 136 byte[] assetData;
137 BackendResponse storageResponse = server.StorageProvider.TryFetchData(assetID, out assetData); 137 BackendResponse storageResponse = server.StorageProvider.TryFetchData(assetID, out assetData);
138 138
139 if (storageResponse == BackendResponse.Success) 139 if (storageResponse == BackendResponse.Success)
140 { 140 {
141 response.Status = HttpStatusCode.OK; 141 response.Status = HttpStatusCode.OK;
142 response.Status = HttpStatusCode.OK; 142 response.Status = HttpStatusCode.OK;
143 response.ContentType = "application/octet-stream"; 143 response.ContentType = "application/octet-stream";
144 response.AddHeader("Content-Disposition", "attachment; filename=" + assetID.ToString()); 144 response.AddHeader("Content-Disposition", "attachment; filename=" + assetID.ToString());
145 response.ContentLength = assetData.Length; 145 response.ContentLength = assetData.Length;
146 response.Body.Write(assetData, 0, assetData.Length); 146 response.Body.Write(assetData, 0, assetData.Length);
147 } 147 }
148 else if (storageResponse == BackendResponse.NotFound) 148 else if (storageResponse == BackendResponse.NotFound)
149 { 149 {
150 response.Status = HttpStatusCode.NotFound; 150 response.Status = HttpStatusCode.NotFound;
151 } 151 }
152 else 152 else
153 { 153 {
154 response.Status = HttpStatusCode.InternalServerError; 154 response.Status = HttpStatusCode.InternalServerError;
155 } 155 }
156 } 156 }
157 else 157 else
158 { 158 {
159 response.Status = HttpStatusCode.Forbidden; 159 response.Status = HttpStatusCode.Forbidden;
160 } 160 }
161 161
162 return true; 162 return true;
163 } 163 }
164 164
165 response.Status = HttpStatusCode.BadRequest; 165 response.Status = HttpStatusCode.BadRequest;
166 return true; 166 return true;
167 } 167 }
168 168
169 bool CreateRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) 169 bool CreateRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
170 { 170 {
171 UUID authToken = Utils.GetAuthToken(request); 171 UUID authToken = Utils.GetAuthToken(request);
172 172
173 if (server.AuthorizationProvider.IsCreateAuthorized(authToken)) 173 if (server.AuthorizationProvider.IsCreateAuthorized(authToken))
174 { 174 {
175 try 175 try
176 { 176 {
177 OSD osdata = OSDParser.DeserializeJson(request.Body); 177 OSD osdata = OSDParser.DeserializeJson(request.Body);
178 178
179 if (osdata.Type == OSDType.Map) 179 if (osdata.Type == OSDType.Map)
180 { 180 {
181 OSDMap map = (OSDMap)osdata; 181 OSDMap map = (OSDMap)osdata;
182 Metadata metadata = new Metadata(); 182 Metadata metadata = new Metadata();
183 metadata.Deserialize(map); 183 metadata.Deserialize(map);
184 184
185 byte[] assetData = map["data"].AsBinary(); 185 byte[] assetData = map["data"].AsBinary();
186 186
187 if (assetData != null && assetData.Length > 0) 187 if (assetData != null && assetData.Length > 0)
188 { 188 {
189 BackendResponse storageResponse; 189 BackendResponse storageResponse;
190 190
191 if (metadata.ID != UUID.Zero) 191 if (metadata.ID != UUID.Zero)
192 storageResponse = server.StorageProvider.TryCreateAsset(metadata, assetData); 192 storageResponse = server.StorageProvider.TryCreateAsset(metadata, assetData);
193 else 193 else
194 storageResponse = server.StorageProvider.TryCreateAsset(metadata, assetData, out metadata.ID); 194 storageResponse = server.StorageProvider.TryCreateAsset(metadata, assetData, out metadata.ID);
195 195
196 if (storageResponse == BackendResponse.Success) 196 if (storageResponse == BackendResponse.Success)
197 { 197 {
198 response.Status = HttpStatusCode.Created; 198 response.Status = HttpStatusCode.Created;
199 OSDMap responseMap = new OSDMap(1); 199 OSDMap responseMap = new OSDMap(1);
200 responseMap["id"] = OSD.FromUUID(metadata.ID); 200 responseMap["id"] = OSD.FromUUID(metadata.ID);
201 LitJson.JsonData jsonData = OSDParser.SerializeJson(responseMap); 201 LitJson.JsonData jsonData = OSDParser.SerializeJson(responseMap);
202 byte[] responseData = System.Text.Encoding.UTF8.GetBytes(jsonData.ToJson()); 202 byte[] responseData = System.Text.Encoding.UTF8.GetBytes(jsonData.ToJson());
203 response.Body.Write(responseData, 0, responseData.Length); 203 response.Body.Write(responseData, 0, responseData.Length);
204 response.Body.Flush(); 204 response.Body.Flush();
205 } 205 }
206 else if (storageResponse == BackendResponse.NotFound) 206 else if (storageResponse == BackendResponse.NotFound)
207 { 207 {
208 response.Status = HttpStatusCode.NotFound; 208 response.Status = HttpStatusCode.NotFound;
209 } 209 }
210 else 210 else
211 { 211 {
212 response.Status = HttpStatusCode.InternalServerError; 212 response.Status = HttpStatusCode.InternalServerError;
213 } 213 }
214 } 214 }
215 else 215 else
216 { 216 {
217 response.Status = HttpStatusCode.BadRequest; 217 response.Status = HttpStatusCode.BadRequest;
218 } 218 }
219 } 219 }
220 else 220 else
221 { 221 {
222 response.Status = HttpStatusCode.BadRequest; 222 response.Status = HttpStatusCode.BadRequest;
223 } 223 }
224 } 224 }
225 catch (Exception ex) 225 catch (Exception ex)
226 { 226 {
227 response.Status = HttpStatusCode.InternalServerError; 227 response.Status = HttpStatusCode.InternalServerError;
228 response.Reason = ex.Message; 228 response.Reason = ex.Message;
229 } 229 }
230 } 230 }
231 else 231 else
232 { 232 {
233 response.Status = HttpStatusCode.Forbidden; 233 response.Status = HttpStatusCode.Forbidden;
234 } 234 }
235 235
236 return true; 236 return true;
237 } 237 }
238 } 238 }
239} 239}
diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleInventory.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleInventory.cs
index f8acdea..c140965 100644
--- a/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleInventory.cs
+++ b/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleInventory.cs
@@ -1,602 +1,602 @@
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
30using System; 30using System;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Net; 32using System.Net;
33using System.IO; 33using System.IO;
34using System.Text; 34using System.Text;
35using ExtensionLoader; 35using ExtensionLoader;
36using OpenMetaverse; 36using OpenMetaverse;
37using OpenMetaverse.StructuredData; 37using OpenMetaverse.StructuredData;
38 38
39namespace OpenSim.Grid.AssetInventoryServer.Extensions 39namespace OpenSim.Grid.AssetInventoryServer.Extensions
40{ 40{
41 public class SimpleInventory : IExtension<AssetInventoryServer>, IInventoryProvider 41 public class SimpleInventory : IExtension<AssetInventoryServer>, IInventoryProvider
42 { 42 {
43 const string EXTENSION_NAME = "SimpleInventory"; // Used for metrics reporting 43 const string EXTENSION_NAME = "SimpleInventory"; // Used for metrics reporting
44 const string DEFAULT_INVENTORY_DIR = "SimpleInventory"; 44 const string DEFAULT_INVENTORY_DIR = "SimpleInventory";
45 45
46 AssetInventoryServer server; 46 AssetInventoryServer server;
47 Dictionary<Uri, InventoryCollection> inventories = new Dictionary<Uri, InventoryCollection>(); 47 Dictionary<Uri, InventoryCollection> inventories = new Dictionary<Uri, InventoryCollection>();
48 Dictionary<Uri, List<InventoryItem>> activeGestures = new Dictionary<Uri, List<InventoryItem>>(); 48 Dictionary<Uri, List<InventoryItem>> activeGestures = new Dictionary<Uri, List<InventoryItem>>();
49 Utils.InventoryItemSerializer itemSerializer = new Utils.InventoryItemSerializer(); 49 Utils.InventoryItemSerializer itemSerializer = new Utils.InventoryItemSerializer();
50 Utils.InventoryFolderSerializer folderSerializer = new Utils.InventoryFolderSerializer(); 50 Utils.InventoryFolderSerializer folderSerializer = new Utils.InventoryFolderSerializer();
51 51
52 public SimpleInventory() 52 public SimpleInventory()
53 { 53 {
54 } 54 }
55 55
56 #region Required Interfaces 56 #region Required Interfaces
57 57
58 public void Start(AssetInventoryServer server) 58 public void Start(AssetInventoryServer server)
59 { 59 {
60 this.server = server; 60 this.server = server;
61 61
62 LoadFiles(DEFAULT_INVENTORY_DIR); 62 LoadFiles(DEFAULT_INVENTORY_DIR);
63 63
64 Logger.Log.InfoFormat("Initialized the inventory index with data for {0} avatars", 64 Logger.Log.InfoFormat("Initialized the inventory index with data for {0} avatars",
65 inventories.Count); 65 inventories.Count);
66 } 66 }
67 67
68 public void Stop() 68 public void Stop()
69 { 69 {
70 } 70 }
71 71
72 public BackendResponse TryFetchItem(Uri owner, UUID itemID, out InventoryItem item) 72 public BackendResponse TryFetchItem(Uri owner, UUID itemID, out InventoryItem item)
73 { 73 {
74 item = null; 74 item = null;
75 BackendResponse ret; 75 BackendResponse ret;
76 76
77 InventoryCollection collection; 77 InventoryCollection collection;
78 if (inventories.TryGetValue(owner, out collection) && collection.Items.TryGetValue(itemID, out item)) 78 if (inventories.TryGetValue(owner, out collection) && collection.Items.TryGetValue(itemID, out item))
79 ret = BackendResponse.Success; 79 ret = BackendResponse.Success;
80 else 80 else
81 ret = BackendResponse.NotFound; 81 ret = BackendResponse.NotFound;
82 82
83 server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now); 83 server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now);
84 return ret; 84 return ret;
85 } 85 }
86 86
87 public BackendResponse TryFetchFolder(Uri owner, UUID folderID, out InventoryFolder folder) 87 public BackendResponse TryFetchFolder(Uri owner, UUID folderID, out InventoryFolder folder)
88 { 88 {
89 folder = null; 89 folder = null;
90 BackendResponse ret; 90 BackendResponse ret;
91 91
92 InventoryCollection collection; 92 InventoryCollection collection;
93 if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder)) 93 if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder))
94 ret = BackendResponse.Success; 94 ret = BackendResponse.Success;
95 else 95 else
96 ret = BackendResponse.NotFound; 96 ret = BackendResponse.NotFound;
97 97
98 server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now); 98 server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now);
99 return ret; 99 return ret;
100 } 100 }
101 101
102 public BackendResponse TryFetchFolderContents(Uri owner, UUID folderID, out InventoryCollection contents) 102 public BackendResponse TryFetchFolderContents(Uri owner, UUID folderID, out InventoryCollection contents)
103 { 103 {
104 contents = null; 104 contents = null;
105 BackendResponse ret; 105 BackendResponse ret;
106 106
107 InventoryCollection collection; 107 InventoryCollection collection;
108 InventoryFolder folder; 108 InventoryFolder folder;
109 109
110 if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder)) 110 if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder))
111 { 111 {
112 contents = new InventoryCollection(); 112 contents = new InventoryCollection();
113 contents.UserID = collection.UserID; 113 contents.UserID = collection.UserID;
114 contents.Folders = new Dictionary<UUID, InventoryFolder>(); 114 contents.Folders = new Dictionary<UUID, InventoryFolder>();
115 contents.Items = new Dictionary<UUID, InventoryItem>(); 115 contents.Items = new Dictionary<UUID, InventoryItem>();
116 116
117 foreach (InventoryBase invBase in folder.Children.Values) 117 foreach (InventoryBase invBase in folder.Children.Values)
118 { 118 {
119 if (invBase is InventoryItem) 119 if (invBase is InventoryItem)
120 { 120 {
121 InventoryItem invItem = invBase as InventoryItem; 121 InventoryItem invItem = invBase as InventoryItem;
122 contents.Items.Add(invItem.ID, invItem); 122 contents.Items.Add(invItem.ID, invItem);
123 } 123 }
124 else 124 else
125 { 125 {
126 InventoryFolder invFolder = invBase as InventoryFolder; 126 InventoryFolder invFolder = invBase as InventoryFolder;
127 contents.Folders.Add(invFolder.ID, invFolder); 127 contents.Folders.Add(invFolder.ID, invFolder);
128 } 128 }
129 } 129 }
130 130
131 ret = BackendResponse.Success; 131 ret = BackendResponse.Success;
132 } 132 }
133 else 133 else
134 { 134 {
135 ret = BackendResponse.NotFound; 135 ret = BackendResponse.NotFound;
136 } 136 }
137 137
138 server.MetricsProvider.LogInventoryFetchFolderContents(EXTENSION_NAME, ret, owner, folderID, DateTime.Now); 138 server.MetricsProvider.LogInventoryFetchFolderContents(EXTENSION_NAME, ret, owner, folderID, DateTime.Now);
139 return ret; 139 return ret;
140 } 140 }
141 141
142 public BackendResponse TryFetchFolderList(Uri owner, out List<InventoryFolder> folders) 142 public BackendResponse TryFetchFolderList(Uri owner, out List<InventoryFolder> folders)
143 { 143 {
144 folders = null; 144 folders = null;
145 BackendResponse ret; 145 BackendResponse ret;
146 146
147 InventoryCollection collection; 147 InventoryCollection collection;
148 if (inventories.TryGetValue(owner, out collection)) 148 if (inventories.TryGetValue(owner, out collection))
149 { 149 {
150 folders = new List<InventoryFolder>(collection.Folders.Values); 150 folders = new List<InventoryFolder>(collection.Folders.Values);
151 return BackendResponse.Success; 151 return BackendResponse.Success;
152 } 152 }
153 else 153 else
154 { 154 {
155 ret = BackendResponse.NotFound; 155 ret = BackendResponse.NotFound;
156 } 156 }
157 157
158 server.MetricsProvider.LogInventoryFetchFolderList(EXTENSION_NAME, ret, owner, DateTime.Now); 158 server.MetricsProvider.LogInventoryFetchFolderList(EXTENSION_NAME, ret, owner, DateTime.Now);
159 return ret; 159 return ret;
160 } 160 }
161 161
162 public BackendResponse TryFetchInventory(Uri owner, out InventoryCollection inventory) 162 public BackendResponse TryFetchInventory(Uri owner, out InventoryCollection inventory)
163 { 163 {
164 inventory = null; 164 inventory = null;
165 BackendResponse ret; 165 BackendResponse ret;
166 166
167 if (inventories.TryGetValue(owner, out inventory)) 167 if (inventories.TryGetValue(owner, out inventory))
168 ret = BackendResponse.Success; 168 ret = BackendResponse.Success;
169 else 169 else
170 ret = BackendResponse.NotFound; 170 ret = BackendResponse.NotFound;
171 171
172 server.MetricsProvider.LogInventoryFetchInventory(EXTENSION_NAME, ret, owner, DateTime.Now); 172 server.MetricsProvider.LogInventoryFetchInventory(EXTENSION_NAME, ret, owner, DateTime.Now);
173 return ret; 173 return ret;
174 } 174 }
175 175
176 public BackendResponse TryFetchActiveGestures(Uri owner, out List<InventoryItem> gestures) 176 public BackendResponse TryFetchActiveGestures(Uri owner, out List<InventoryItem> gestures)
177 { 177 {
178 gestures = null; 178 gestures = null;
179 BackendResponse ret; 179 BackendResponse ret;
180 180
181 if (activeGestures.TryGetValue(owner, out gestures)) 181 if (activeGestures.TryGetValue(owner, out gestures))
182 ret = BackendResponse.Success; 182 ret = BackendResponse.Success;
183 else 183 else
184 ret = BackendResponse.NotFound; 184 ret = BackendResponse.NotFound;
185 185
186 server.MetricsProvider.LogInventoryFetchActiveGestures(EXTENSION_NAME, ret, owner, DateTime.Now); 186 server.MetricsProvider.LogInventoryFetchActiveGestures(EXTENSION_NAME, ret, owner, DateTime.Now);
187 return ret; 187 return ret;
188 } 188 }
189 189
190 public BackendResponse TryCreateItem(Uri owner, InventoryItem item) 190 public BackendResponse TryCreateItem(Uri owner, InventoryItem item)
191 { 191 {
192 BackendResponse ret; 192 BackendResponse ret;
193 193
194 InventoryCollection collection; 194 InventoryCollection collection;
195 if (inventories.TryGetValue(owner, out collection)) 195 if (inventories.TryGetValue(owner, out collection))
196 { 196 {
197 // Delete this item first if it already exists 197 // Delete this item first if it already exists
198 InventoryItem oldItem; 198 InventoryItem oldItem;
199 if (collection.Items.TryGetValue(item.ID, out oldItem)) 199 if (collection.Items.TryGetValue(item.ID, out oldItem))
200 TryDeleteItem(owner, item.ID); 200 TryDeleteItem(owner, item.ID);
201 201
202 try 202 try
203 { 203 {
204 // Create the file 204 // Create the file
205 SaveItem(item); 205 SaveItem(item);
206 206
207 // Add the item to the collection 207 // Add the item to the collection
208 lock (collection) collection.Items[item.ID] = item; 208 lock (collection) collection.Items[item.ID] = item;
209 209
210 // Add the item to its parent folder 210 // Add the item to its parent folder
211 InventoryFolder parent; 211 InventoryFolder parent;
212 if (collection.Folders.TryGetValue(item.Folder, out parent)) 212 if (collection.Folders.TryGetValue(item.Folder, out parent))
213 lock (parent.Children) parent.Children.Add(item.ID, item); 213 lock (parent.Children) parent.Children.Add(item.ID, item);
214 214
215 // Add active gestures to our list 215 // Add active gestures to our list
216 if (item.InvType == (int)InventoryType.Gesture && item.Flags == 1) 216 if (item.InvType == (int)InventoryType.Gesture && item.Flags == 1)
217 { 217 {
218 lock (activeGestures) 218 lock (activeGestures)
219 activeGestures[owner].Add(item); 219 activeGestures[owner].Add(item);
220 } 220 }
221 221
222 ret = BackendResponse.Success; 222 ret = BackendResponse.Success;
223 } 223 }
224 catch (Exception ex) 224 catch (Exception ex)
225 { 225 {
226 Logger.Log.Error(ex.Message); 226 Logger.Log.Error(ex.Message);
227 ret = BackendResponse.Failure; 227 ret = BackendResponse.Failure;
228 } 228 }
229 } 229 }
230 else 230 else
231 { 231 {
232 return BackendResponse.NotFound; 232 return BackendResponse.NotFound;
233 } 233 }
234 234
235 server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, false, DateTime.Now); 235 server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, false, DateTime.Now);
236 return ret; 236 return ret;
237 } 237 }
238 238
239 public BackendResponse TryCreateFolder(Uri owner, InventoryFolder folder) 239 public BackendResponse TryCreateFolder(Uri owner, InventoryFolder folder)
240 { 240 {
241 BackendResponse ret; 241 BackendResponse ret;
242 242
243 InventoryCollection collection; 243 InventoryCollection collection;
244 if (inventories.TryGetValue(owner, out collection)) 244 if (inventories.TryGetValue(owner, out collection))
245 { 245 {
246 // Delete this folder first if it already exists 246 // Delete this folder first if it already exists
247 InventoryFolder oldFolder; 247 InventoryFolder oldFolder;
248 if (collection.Folders.TryGetValue(folder.ID, out oldFolder)) 248 if (collection.Folders.TryGetValue(folder.ID, out oldFolder))
249 TryDeleteFolder(owner, folder.ID); 249 TryDeleteFolder(owner, folder.ID);
250 250
251 try 251 try
252 { 252 {
253 // Create the file 253 // Create the file
254 SaveFolder(folder); 254 SaveFolder(folder);
255 255
256 // Add the folder to the collection 256 // Add the folder to the collection
257 lock (collection) collection.Folders[folder.ID] = folder; 257 lock (collection) collection.Folders[folder.ID] = folder;
258 258
259 // Add the folder to its parent folder 259 // Add the folder to its parent folder
260 InventoryFolder parent; 260 InventoryFolder parent;
261 if (collection.Folders.TryGetValue(folder.ParentID, out parent)) 261 if (collection.Folders.TryGetValue(folder.ParentID, out parent))
262 lock (parent.Children) parent.Children.Add(folder.ID, folder); 262 lock (parent.Children) parent.Children.Add(folder.ID, folder);
263 263
264 ret = BackendResponse.Success; 264 ret = BackendResponse.Success;
265 } 265 }
266 catch (Exception ex) 266 catch (Exception ex)
267 { 267 {
268 Logger.Log.Error(ex.Message); 268 Logger.Log.Error(ex.Message);
269 ret = BackendResponse.Failure; 269 ret = BackendResponse.Failure;
270 } 270 }
271 } 271 }
272 else 272 else
273 { 273 {
274 ret = BackendResponse.NotFound; 274 ret = BackendResponse.NotFound;
275 } 275 }
276 276
277 server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, true, DateTime.Now); 277 server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, true, DateTime.Now);
278 return ret; 278 return ret;
279 } 279 }
280 280
281 public BackendResponse TryCreateInventory(Uri owner, InventoryFolder rootFolder) 281 public BackendResponse TryCreateInventory(Uri owner, InventoryFolder rootFolder)
282 { 282 {
283 BackendResponse ret; 283 BackendResponse ret;
284 284
285 lock (inventories) 285 lock (inventories)
286 { 286 {
287 if (!inventories.ContainsKey(owner)) 287 if (!inventories.ContainsKey(owner))
288 { 288 {
289 InventoryCollection collection = new InventoryCollection(); 289 InventoryCollection collection = new InventoryCollection();
290 collection.UserID = rootFolder.Owner; 290 collection.UserID = rootFolder.Owner;
291 collection.Folders = new Dictionary<UUID, InventoryFolder>(); 291 collection.Folders = new Dictionary<UUID, InventoryFolder>();
292 collection.Folders.Add(rootFolder.ID, rootFolder); 292 collection.Folders.Add(rootFolder.ID, rootFolder);
293 collection.Items = new Dictionary<UUID, InventoryItem>(); 293 collection.Items = new Dictionary<UUID, InventoryItem>();
294 294
295 inventories.Add(owner, collection); 295 inventories.Add(owner, collection);
296 296
297 ret = BackendResponse.Success; 297 ret = BackendResponse.Success;
298 } 298 }
299 else 299 else
300 { 300 {
301 ret = BackendResponse.Failure; 301 ret = BackendResponse.Failure;
302 } 302 }
303 } 303 }
304 304
305 if (ret == BackendResponse.Success) 305 if (ret == BackendResponse.Success)
306 { 306 {
307 string path = Path.Combine(DEFAULT_INVENTORY_DIR, rootFolder.Owner.ToString()); 307 string path = Path.Combine(DEFAULT_INVENTORY_DIR, rootFolder.Owner.ToString());
308 try 308 try
309 { 309 {
310 // Create the directory for this agent 310 // Create the directory for this agent
311 Directory.CreateDirectory(path); 311 Directory.CreateDirectory(path);
312 312
313 // Create an index.txt containing the UUID and URI for this agent 313 // Create an index.txt containing the UUID and URI for this agent
314 string[] index = new string[] { rootFolder.Owner.ToString(), owner.ToString() }; 314 string[] index = new string[] { rootFolder.Owner.ToString(), owner.ToString() };
315 File.WriteAllLines(Path.Combine(path, "index.txt"), index); 315 File.WriteAllLines(Path.Combine(path, "index.txt"), index);
316 316
317 // Create the root folder file 317 // Create the root folder file
318 SaveFolder(rootFolder); 318 SaveFolder(rootFolder);
319 } 319 }
320 catch (Exception ex) 320 catch (Exception ex)
321 { 321 {
322 Logger.Log.Error(ex.Message); 322 Logger.Log.Error(ex.Message);
323 ret = BackendResponse.Failure; 323 ret = BackendResponse.Failure;
324 } 324 }
325 } 325 }
326 326
327 server.MetricsProvider.LogInventoryCreateInventory(EXTENSION_NAME, ret, DateTime.Now); 327 server.MetricsProvider.LogInventoryCreateInventory(EXTENSION_NAME, ret, DateTime.Now);
328 return ret; 328 return ret;
329 } 329 }
330 330
331 public BackendResponse TryDeleteItem(Uri owner, UUID itemID) 331 public BackendResponse TryDeleteItem(Uri owner, UUID itemID)
332 { 332 {
333 BackendResponse ret; 333 BackendResponse ret;
334 334
335 InventoryCollection collection; 335 InventoryCollection collection;
336 InventoryItem item; 336 InventoryItem item;
337 if (inventories.TryGetValue(owner, out collection) && collection.Items.TryGetValue(itemID, out item)) 337 if (inventories.TryGetValue(owner, out collection) && collection.Items.TryGetValue(itemID, out item))
338 { 338 {
339 // Remove the item from its parent folder 339 // Remove the item from its parent folder
340 InventoryFolder parent; 340 InventoryFolder parent;
341 if (collection.Folders.TryGetValue(item.Folder, out parent)) 341 if (collection.Folders.TryGetValue(item.Folder, out parent))
342 lock (parent.Children) parent.Children.Remove(itemID); 342 lock (parent.Children) parent.Children.Remove(itemID);
343 343
344 // Remove the item from the collection 344 // Remove the item from the collection
345 lock (collection) collection.Items.Remove(itemID); 345 lock (collection) collection.Items.Remove(itemID);
346 346
347 // Remove from the active gestures list if applicable 347 // Remove from the active gestures list if applicable
348 if (item.InvType == (int)InventoryType.Gesture) 348 if (item.InvType == (int)InventoryType.Gesture)
349 { 349 {
350 lock (activeGestures) 350 lock (activeGestures)
351 { 351 {
352 for (int i = 0; i < activeGestures[owner].Count; i++) 352 for (int i = 0; i < activeGestures[owner].Count; i++)
353 { 353 {
354 if (activeGestures[owner][i].ID == itemID) 354 if (activeGestures[owner][i].ID == itemID)
355 { 355 {
356 activeGestures[owner].RemoveAt(i); 356 activeGestures[owner].RemoveAt(i);
357 break; 357 break;
358 } 358 }
359 } 359 }
360 } 360 }
361 } 361 }
362 362
363 // Delete the file. We don't know exactly what the file name is, 363 // Delete the file. We don't know exactly what the file name is,
364 // so search for it 364 // so search for it
365 string path = PathFromURI(owner); 365 string path = PathFromURI(owner);
366 string[] matches = Directory.GetFiles(path, String.Format("*{0}.item", itemID), SearchOption.TopDirectoryOnly); 366 string[] matches = Directory.GetFiles(path, String.Format("*{0}.item", itemID), SearchOption.TopDirectoryOnly);
367 foreach (string match in matches) 367 foreach (string match in matches)
368 { 368 {
369 try { File.Delete(match); } 369 try { File.Delete(match); }
370 catch (Exception ex) { Logger.Log.ErrorFormat("Failed to delete file {0}: {1}", match, ex.Message); } 370 catch (Exception ex) { Logger.Log.ErrorFormat("Failed to delete file {0}: {1}", match, ex.Message); }
371 } 371 }
372 372
373 ret = BackendResponse.Success; 373 ret = BackendResponse.Success;
374 } 374 }
375 else 375 else
376 { 376 {
377 ret = BackendResponse.NotFound; 377 ret = BackendResponse.NotFound;
378 } 378 }
379 379
380 server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now); 380 server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now);
381 return ret; 381 return ret;
382 } 382 }
383 383
384 public BackendResponse TryDeleteFolder(Uri owner, UUID folderID) 384 public BackendResponse TryDeleteFolder(Uri owner, UUID folderID)
385 { 385 {
386 BackendResponse ret; 386 BackendResponse ret;
387 387
388 InventoryCollection collection; 388 InventoryCollection collection;
389 InventoryFolder folder; 389 InventoryFolder folder;
390 if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder)) 390 if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder))
391 { 391 {
392 // Remove the folder from its parent folder 392 // Remove the folder from its parent folder
393 InventoryFolder parent; 393 InventoryFolder parent;
394 if (collection.Folders.TryGetValue(folder.ParentID, out parent)) 394 if (collection.Folders.TryGetValue(folder.ParentID, out parent))
395 lock (parent.Children) parent.Children.Remove(folderID); 395 lock (parent.Children) parent.Children.Remove(folderID);
396 396
397 // Remove the folder from the collection 397 // Remove the folder from the collection
398 lock (collection) collection.Items.Remove(folderID); 398 lock (collection) collection.Items.Remove(folderID);
399 399
400 // Delete the folder file. We don't know exactly what the file name is, 400 // Delete the folder file. We don't know exactly what the file name is,
401 // so search for it 401 // so search for it
402 string path = PathFromURI(owner); 402 string path = PathFromURI(owner);
403 string[] matches = Directory.GetFiles(path, String.Format("*{0}.folder", folderID), SearchOption.TopDirectoryOnly); 403 string[] matches = Directory.GetFiles(path, String.Format("*{0}.folder", folderID), SearchOption.TopDirectoryOnly);
404 foreach (string match in matches) 404 foreach (string match in matches)
405 { 405 {
406 try { File.Delete(match); } 406 try { File.Delete(match); }
407 catch (Exception ex) { Logger.Log.ErrorFormat("Failed to delete folder file {0}: {1}", match, ex.Message); } 407 catch (Exception ex) { Logger.Log.ErrorFormat("Failed to delete folder file {0}: {1}", match, ex.Message); }
408 } 408 }
409 409
410 ret = BackendResponse.Success; 410 ret = BackendResponse.Success;
411 } 411 }
412 else 412 else
413 { 413 {
414 ret = BackendResponse.NotFound; 414 ret = BackendResponse.NotFound;
415 } 415 }
416 416
417 server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now); 417 server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now);
418 return ret; 418 return ret;
419 } 419 }
420 420
421 public BackendResponse TryPurgeFolder(Uri owner, UUID folderID) 421 public BackendResponse TryPurgeFolder(Uri owner, UUID folderID)
422 { 422 {
423 BackendResponse ret; 423 BackendResponse ret;
424 424
425 InventoryCollection collection; 425 InventoryCollection collection;
426 InventoryFolder folder; 426 InventoryFolder folder;
427 if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder)) 427 if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder))
428 { 428 {
429 // Delete all of the folder children 429 // Delete all of the folder children
430 foreach (InventoryBase obj in new List<InventoryBase>(folder.Children.Values)) 430 foreach (InventoryBase obj in new List<InventoryBase>(folder.Children.Values))
431 { 431 {
432 if (obj is InventoryItem) 432 if (obj is InventoryItem)
433 { 433 {
434 TryDeleteItem(owner, (obj as InventoryItem).ID); 434 TryDeleteItem(owner, (obj as InventoryItem).ID);
435 } 435 }
436 else 436 else
437 { 437 {
438 InventoryFolder childFolder = obj as InventoryFolder; 438 InventoryFolder childFolder = obj as InventoryFolder;
439 TryPurgeFolder(owner, childFolder.ID); 439 TryPurgeFolder(owner, childFolder.ID);
440 TryDeleteFolder(owner, childFolder.ID); 440 TryDeleteFolder(owner, childFolder.ID);
441 } 441 }
442 } 442 }
443 443
444 ret = BackendResponse.Success; 444 ret = BackendResponse.Success;
445 } 445 }
446 else 446 else
447 { 447 {
448 ret = BackendResponse.NotFound; 448 ret = BackendResponse.NotFound;
449 } 449 }
450 450
451 server.MetricsProvider.LogInventoryPurgeFolder(EXTENSION_NAME, ret, owner, folderID, DateTime.Now); 451 server.MetricsProvider.LogInventoryPurgeFolder(EXTENSION_NAME, ret, owner, folderID, DateTime.Now);
452 return ret; 452 return ret;
453 } 453 }
454 454
455 #endregion Required Interfaces 455 #endregion Required Interfaces
456 456
457 void SaveItem(InventoryItem item) 457 void SaveItem(InventoryItem item)
458 { 458 {
459 string filename = String.Format("{0}-{1}.item", SanitizeFilename(item.Name), item.ID); 459 string filename = String.Format("{0}-{1}.item", SanitizeFilename(item.Name), item.ID);
460 460
461 string path = Path.Combine(DEFAULT_INVENTORY_DIR, item.Owner.ToString()); 461 string path = Path.Combine(DEFAULT_INVENTORY_DIR, item.Owner.ToString());
462 path = Path.Combine(path, filename); 462 path = Path.Combine(path, filename);
463 463
464 using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write)) 464 using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write))
465 { 465 {
466 itemSerializer.Serialize(stream, item); 466 itemSerializer.Serialize(stream, item);
467 stream.Flush(); 467 stream.Flush();
468 } 468 }
469 } 469 }
470 470
471 void SaveFolder(InventoryFolder folder) 471 void SaveFolder(InventoryFolder folder)
472 { 472 {
473 string filename = String.Format("{0}-{1}.folder", SanitizeFilename(folder.Name), folder.ID); 473 string filename = String.Format("{0}-{1}.folder", SanitizeFilename(folder.Name), folder.ID);
474 474
475 string path = Path.Combine(DEFAULT_INVENTORY_DIR, folder.Owner.ToString()); 475 string path = Path.Combine(DEFAULT_INVENTORY_DIR, folder.Owner.ToString());
476 path = Path.Combine(path, filename); 476 path = Path.Combine(path, filename);
477 477
478 using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write)) 478 using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write))
479 { 479 {
480 folderSerializer.Serialize(stream, folder); 480 folderSerializer.Serialize(stream, folder);
481 stream.Flush(); 481 stream.Flush();
482 } 482 }
483 } 483 }
484 484
485 string SanitizeFilename(string filename) 485 string SanitizeFilename(string filename)
486 { 486 {
487 string output = filename; 487 string output = filename;
488 488
489 if (output.Length > 64) 489 if (output.Length > 64)
490 output = output.Substring(0, 64); 490 output = output.Substring(0, 64);
491 491
492 foreach (char i in Path.GetInvalidFileNameChars()) 492 foreach (char i in Path.GetInvalidFileNameChars())
493 output = output.Replace(i, '_'); 493 output = output.Replace(i, '_');
494 494
495 return output; 495 return output;
496 } 496 }
497 497
498 static string PathFromURI(Uri uri) 498 static string PathFromURI(Uri uri)
499 { 499 {
500 byte[] hash = OpenMetaverse.Utils.SHA1(Encoding.UTF8.GetBytes(uri.ToString())); 500 byte[] hash = OpenMetaverse.Utils.SHA1(Encoding.UTF8.GetBytes(uri.ToString()));
501 StringBuilder digest = new StringBuilder(40); 501 StringBuilder digest = new StringBuilder(40);
502 502
503 // Convert the hash to a hex string 503 // Convert the hash to a hex string
504 foreach (byte b in hash) 504 foreach (byte b in hash)
505 digest.AppendFormat(OpenMetaverse.Utils.EnUsCulture, "{0:x2}", b); 505 digest.AppendFormat(OpenMetaverse.Utils.EnUsCulture, "{0:x2}", b);
506 506
507 return Path.Combine(DEFAULT_INVENTORY_DIR, digest.ToString()); 507 return Path.Combine(DEFAULT_INVENTORY_DIR, digest.ToString());
508 } 508 }
509 509
510 void LoadFiles(string folder) 510 void LoadFiles(string folder)
511 { 511 {
512 // Try to create the directory if it doesn't already exist 512 // Try to create the directory if it doesn't already exist
513 if (!Directory.Exists(folder)) 513 if (!Directory.Exists(folder))
514 { 514 {
515 try { Directory.CreateDirectory(folder); } 515 try { Directory.CreateDirectory(folder); }
516 catch (Exception ex) 516 catch (Exception ex)
517 { 517 {
518 Logger.Log.Warn(ex.Message); 518 Logger.Log.Warn(ex.Message);
519 return; 519 return;
520 } 520 }
521 } 521 }
522 522
523 try 523 try
524 { 524 {
525 string[] agentFolders = Directory.GetDirectories(DEFAULT_INVENTORY_DIR); 525 string[] agentFolders = Directory.GetDirectories(DEFAULT_INVENTORY_DIR);
526 526
527 for (int i = 0; i < agentFolders.Length; i++) 527 for (int i = 0; i < agentFolders.Length; i++)
528 { 528 {
529 string foldername = agentFolders[i]; 529 string foldername = agentFolders[i];
530 string indexPath = Path.Combine(foldername, "index.txt"); 530 string indexPath = Path.Combine(foldername, "index.txt");
531 UUID ownerID = UUID.Zero; 531 UUID ownerID = UUID.Zero;
532 Uri owner = null; 532 Uri owner = null;
533 533
534 try 534 try
535 { 535 {
536 string[] index = File.ReadAllLines(indexPath); 536 string[] index = File.ReadAllLines(indexPath);
537 ownerID = UUID.Parse(index[0]); 537 ownerID = UUID.Parse(index[0]);
538 owner = new Uri(index[1]); 538 owner = new Uri(index[1]);
539 } 539 }
540 catch (Exception ex) 540 catch (Exception ex)
541 { 541 {
542 Logger.Log.WarnFormat("Failed loading the index file {0}: {1}", indexPath, ex.Message); 542 Logger.Log.WarnFormat("Failed loading the index file {0}: {1}", indexPath, ex.Message);
543 } 543 }
544 544
545 if (ownerID != UUID.Zero && owner != null) 545 if (ownerID != UUID.Zero && owner != null)
546 { 546 {
547 // Initialize the active gestures list for this agent 547 // Initialize the active gestures list for this agent
548 activeGestures.Add(owner, new List<InventoryItem>()); 548 activeGestures.Add(owner, new List<InventoryItem>());
549 549
550 InventoryCollection collection = new InventoryCollection(); 550 InventoryCollection collection = new InventoryCollection();
551 collection.UserID = ownerID; 551 collection.UserID = ownerID;
552 552
553 // Load all of the folders for this agent 553 // Load all of the folders for this agent
554 string[] folders = Directory.GetFiles(foldername, "*.folder", SearchOption.TopDirectoryOnly); 554 string[] folders = Directory.GetFiles(foldername, "*.folder", SearchOption.TopDirectoryOnly);
555 collection.Folders = new Dictionary<UUID,InventoryFolder>(folders.Length); 555 collection.Folders = new Dictionary<UUID,InventoryFolder>(folders.Length);
556 556
557 for (int j = 0; j < folders.Length; j++) 557 for (int j = 0; j < folders.Length; j++)
558 { 558 {
559 InventoryFolder invFolder = (InventoryFolder)folderSerializer.Deserialize( 559 InventoryFolder invFolder = (InventoryFolder)folderSerializer.Deserialize(
560 new FileStream(folders[j], FileMode.Open, FileAccess.Read)); 560 new FileStream(folders[j], FileMode.Open, FileAccess.Read));
561 collection.Folders[invFolder.ID] = invFolder; 561 collection.Folders[invFolder.ID] = invFolder;
562 } 562 }
563 563
564 // Iterate over the folders collection, adding children to their parents 564 // Iterate over the folders collection, adding children to their parents
565 foreach (InventoryFolder invFolder in collection.Folders.Values) 565 foreach (InventoryFolder invFolder in collection.Folders.Values)
566 { 566 {
567 InventoryFolder parent; 567 InventoryFolder parent;
568 if (collection.Folders.TryGetValue(invFolder.ParentID, out parent)) 568 if (collection.Folders.TryGetValue(invFolder.ParentID, out parent))
569 parent.Children[invFolder.ID] = invFolder; 569 parent.Children[invFolder.ID] = invFolder;
570 } 570 }
571 571
572 // Load all of the items for this agent 572 // Load all of the items for this agent
573 string[] files = Directory.GetFiles(foldername, "*.item", SearchOption.TopDirectoryOnly); 573 string[] files = Directory.GetFiles(foldername, "*.item", SearchOption.TopDirectoryOnly);
574 collection.Items = new Dictionary<UUID, InventoryItem>(files.Length); 574 collection.Items = new Dictionary<UUID, InventoryItem>(files.Length);
575 575
576 for (int j = 0; j < files.Length; j++) 576 for (int j = 0; j < files.Length; j++)
577 { 577 {
578 InventoryItem invItem = (InventoryItem)itemSerializer.Deserialize( 578 InventoryItem invItem = (InventoryItem)itemSerializer.Deserialize(
579 new FileStream(files[j], FileMode.Open, FileAccess.Read)); 579 new FileStream(files[j], FileMode.Open, FileAccess.Read));
580 collection.Items[invItem.ID] = invItem; 580 collection.Items[invItem.ID] = invItem;
581 581
582 // Add items to their parent folders 582 // Add items to their parent folders
583 InventoryFolder parent; 583 InventoryFolder parent;
584 if (collection.Folders.TryGetValue(invItem.Folder, out parent)) 584 if (collection.Folders.TryGetValue(invItem.Folder, out parent))
585 parent.Children[invItem.ID] = invItem; 585 parent.Children[invItem.ID] = invItem;
586 586
587 // Add active gestures to our list 587 // Add active gestures to our list
588 if (invItem.InvType == (int)InventoryType.Gesture && invItem.Flags != 0) 588 if (invItem.InvType == (int)InventoryType.Gesture && invItem.Flags != 0)
589 activeGestures[owner].Add(invItem); 589 activeGestures[owner].Add(invItem);
590 } 590 }
591 591
592 inventories.Add(owner, collection); 592 inventories.Add(owner, collection);
593 } 593 }
594 } 594 }
595 } 595 }
596 catch (Exception ex) 596 catch (Exception ex)
597 { 597 {
598 Logger.Log.ErrorFormat("Failed loading inventory from {0}: {1}", folder, ex.Message); 598 Logger.Log.ErrorFormat("Failed loading inventory from {0}: {1}", folder, ex.Message);
599 } 599 }
600 } 600 }
601 } 601 }
602} 602}
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
30using System; 30using System;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Net; 32using System.Net;
33using System.IO; 33using System.IO;
34using ExtensionLoader; 34using ExtensionLoader;
35using OpenMetaverse; 35using OpenMetaverse;
36using OpenMetaverse.StructuredData; 36using OpenMetaverse.StructuredData;
37 37
38namespace OpenSim.Grid.AssetInventoryServer.Extensions 38namespace 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}
diff --git a/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleUtils.cs b/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleUtils.cs
index fe6491e..b3edf59 100644
--- a/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleUtils.cs
+++ b/OpenSim/Grid/AssetInventoryServer/Extensions/SimpleUtils.cs
@@ -1,44 +1,44 @@
1using System; 1using System;
2using System.IO; 2using System.IO;
3using OpenMetaverse; 3using OpenMetaverse;
4 4
5namespace OpenSim.Grid.AssetInventoryServer.Extensions 5namespace OpenSim.Grid.AssetInventoryServer.Extensions
6{ 6{
7 public static class SimpleUtils 7 public static class SimpleUtils
8 { 8 {
9 public static string ParseNameFromFilename(string filename) 9 public static string ParseNameFromFilename(string filename)
10 { 10 {
11 filename = Path.GetFileName(filename); 11 filename = Path.GetFileName(filename);
12 12
13 int dot = filename.LastIndexOf('.'); 13 int dot = filename.LastIndexOf('.');
14 int firstDash = filename.IndexOf('-'); 14 int firstDash = filename.IndexOf('-');
15 15
16 if (dot - 37 > 0 && firstDash > 0) 16 if (dot - 37 > 0 && firstDash > 0)
17 return filename.Substring(0, firstDash); 17 return filename.Substring(0, firstDash);
18 else 18 else
19 return String.Empty; 19 return String.Empty;
20 } 20 }
21 21
22 public static UUID ParseUUIDFromFilename(string filename) 22 public static UUID ParseUUIDFromFilename(string filename)
23 { 23 {
24 int dot = filename.LastIndexOf('.'); 24 int dot = filename.LastIndexOf('.');
25 25
26 if (dot > 35) 26 if (dot > 35)
27 { 27 {
28 // Grab the last 36 characters of the filename 28 // Grab the last 36 characters of the filename
29 string uuidString = filename.Substring(dot - 36, 36); 29 string uuidString = filename.Substring(dot - 36, 36);
30 UUID uuid; 30 UUID uuid;
31 UUID.TryParse(uuidString, out uuid); 31 UUID.TryParse(uuidString, out uuid);
32 return uuid; 32 return uuid;
33 } 33 }
34 else 34 else
35 { 35 {
36 UUID uuid; 36 UUID uuid;
37 if (UUID.TryParse(Path.GetFileName(filename), out uuid)) 37 if (UUID.TryParse(Path.GetFileName(filename), out uuid))
38 return uuid; 38 return uuid;
39 else 39 else
40 return UUID.Zero; 40 return UUID.Zero;
41 } 41 }
42 } 42 }
43 } 43 }
44} 44}