- removed OpenSim.Grid.AssetInventoryServer.Metadata class in favor of

OpenSim.Framework.AssetMetadata and related updates in AssetInventory
  server
- removed dependency on MySql.Data.MySqlClient
- commented out the bulk of OpenSimInventoryStorage due to missing
  MySql.Data dependency
- refactor asset creation in OpenSimAssetFrontend
- commented out ForEach implementation, which also depended on
  MySql.Data, until it's supported by OpenSim backends
- commented out some handlers in BrowseFrontend and ReferenceFrontend as
  they relied on either ForEach or the removed Metadata class
0.6.3-post-fixes
Mike Mazur 2009-02-16 02:28:34 +00:00
parent 4c6b7234de
commit ab5e332832
9 changed files with 943 additions and 1120 deletions

View File

@ -73,12 +73,12 @@ namespace OpenSim.Grid.AssetInventoryServer
public interface IAssetStorageProvider : IAssetInventoryServerPlugin public interface IAssetStorageProvider : IAssetInventoryServerPlugin
{ {
BackendResponse TryFetchMetadata(UUID assetID, out Metadata metadata); BackendResponse TryFetchMetadata(UUID assetID, out AssetMetadata metadata);
BackendResponse TryFetchData(UUID assetID, out byte[] assetData); BackendResponse TryFetchData(UUID assetID, out byte[] assetData);
BackendResponse TryFetchDataMetadata(UUID assetID, out AssetBase asset); BackendResponse TryFetchDataMetadata(UUID assetID, out AssetBase asset);
BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData); BackendResponse TryCreateAsset(AssetBase asset);
BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData, out UUID assetID); BackendResponse TryCreateAsset(AssetBase asset, out UUID assetID);
int ForEach(Action<Metadata> action, int start, int count); int ForEach(Action<AssetMetadata> action, int start, int count);
} }
public interface IInventoryStorageProvider : IAssetInventoryServerPlugin public interface IInventoryStorageProvider : IAssetInventoryServerPlugin

View File

@ -1,84 +0,0 @@
using System;
using System.Collections.Generic;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
namespace OpenSim.Grid.AssetInventoryServer
{
public class Metadata
{
public UUID ID;
public string Name;
public string Description;
public DateTime CreationDate;
public string ContentType;
public byte[] SHA1;
public bool Temporary;
public Dictionary<string, Uri> Methods = new Dictionary<string, Uri>();
public OSDMap ExtraData;
public OSDMap SerializeToOSD()
{
OSDMap osdata = new OSDMap();
if (ID != UUID.Zero) osdata["id"] = OSD.FromUUID(ID);
osdata["name"] = OSD.FromString(Name);
osdata["description"] = OSD.FromString(Description);
osdata["creation_date"] = OSD.FromDate(CreationDate);
osdata["type"] = OSD.FromString(ContentType);
osdata["sha1"] = OSD.FromBinary(SHA1);
osdata["temporary"] = OSD.FromBoolean(Temporary);
OSDMap methods = new OSDMap(Methods.Count);
foreach (KeyValuePair<string, Uri> kvp in Methods)
methods.Add(kvp.Key, OSD.FromUri(kvp.Value));
osdata["methods"] = methods;
if (ExtraData != null) osdata["extra_data"] = ExtraData;
return osdata;
}
public byte[] SerializeToBytes()
{
LitJson.JsonData jsonData = OSDParser.SerializeJson(SerializeToOSD());
return System.Text.Encoding.UTF8.GetBytes(jsonData.ToJson());
}
public void Deserialize(byte[] data)
{
OSD osdata = OSDParser.DeserializeJson(System.Text.Encoding.UTF8.GetString(data));
Deserialize(osdata);
}
public void Deserialize(string data)
{
OSD osdata = OSDParser.DeserializeJson(data);
Deserialize(osdata);
}
public void Deserialize(OSD osdata)
{
if (osdata.Type == OSDType.Map)
{
OSDMap map = (OSDMap)osdata;
ID = map["id"].AsUUID();
Name = map["name"].AsString();
Description = map["description"].AsString();
CreationDate = map["creation_date"].AsDate();
ContentType = map["type"].AsString();
SHA1 = map["sha1"].AsBinary();
Temporary = map["temporary"].AsBoolean();
OSDMap methods = map["methods"] as OSDMap;
if (methods != null)
{
foreach (KeyValuePair<string, OSD> kvp in methods)
Methods.Add(kvp.Key, kvp.Value.AsUri());
}
ExtraData = map["extra_data"] as OSDMap;
}
}
}
}

View File

@ -57,8 +57,7 @@ namespace OpenSim.Grid.AssetInventoryServer.Plugins
m_server = server; m_server = server;
// Request for / or /?... // Request for / or /?...
//server.HttpServer.AddHandler("get", null, @"(^/$)|(^/\?.*)", BrowseRequestHandler); //m_server.HttpServer.AddStreamHandler(new BrowseRequestHandler(server));
m_server.HttpServer.AddStreamHandler(new BrowseRequestHandler(server));
m_log.Info("[ASSET] Browser Frontend loaded."); m_log.Info("[ASSET] Browser Frontend loaded.");
} }
@ -89,102 +88,102 @@ namespace OpenSim.Grid.AssetInventoryServer.Plugins
#endregion IPlugin implementation #endregion IPlugin implementation
public class BrowseRequestHandler : IStreamedRequestHandler //public class BrowseRequestHandler : IStreamedRequestHandler
{ //{
AssetInventoryServer m_server; // AssetInventoryServer m_server;
string m_contentType; // string m_contentType;
string m_httpMethod; // string m_httpMethod;
string m_path; // string m_path;
public BrowseRequestHandler(AssetInventoryServer server) // public BrowseRequestHandler(AssetInventoryServer server)
{ // {
m_server = server; // m_server = server;
m_contentType = null; // m_contentType = null;
m_httpMethod = "GET"; // m_httpMethod = "GET";
m_path = @"(^/$)|(^/\?.*)"; // m_path = @"(^/$)|(^/\?.*)";
} // }
#region IStreamedRequestHandler implementation // #region IStreamedRequestHandler implementation
public string ContentType // public string ContentType
{ // {
get { return m_contentType; } // get { return m_contentType; }
} // }
public string HttpMethod // public string HttpMethod
{ // {
get { return m_httpMethod; } // get { return m_httpMethod; }
} // }
public string Path // public string Path
{ // {
get { return m_path; } // get { return m_path; }
} // }
public byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) // public byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{ // {
const int ASSETS_PER_PAGE = 25; // const int ASSETS_PER_PAGE = 25;
const string HEADER = "<html><head><title>Asset Server</title></head><body>"; // const string HEADER = "<html><head><title>Asset Server</title></head><body>";
const string TABLE_HEADER = // const string TABLE_HEADER =
"<table><tr><th>Name</th><th>Description</th><th>Type</th><th>ID</th><th>Temporary</th><th>SHA-1</th></tr>"; // "<table><tr><th>Name</th><th>Description</th><th>Type</th><th>ID</th><th>Temporary</th><th>SHA-1</th></tr>";
const string TABLE_FOOTER = "</table>"; // const string TABLE_FOOTER = "</table>";
const string FOOTER = "</body></html>"; // const string FOOTER = "</body></html>";
UUID authToken = Utils.GetAuthToken(httpRequest); // UUID authToken = Utils.GetAuthToken(httpRequest);
StringBuilder html = new StringBuilder(); // StringBuilder html = new StringBuilder();
int start = 0; // int start = 0;
uint page = 0; // uint page = 0;
if (!String.IsNullOrEmpty(httpRequest.Url.Query)) // if (!String.IsNullOrEmpty(httpRequest.Url.Query))
{ // {
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); // NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
if (!String.IsNullOrEmpty(query["page"]) && UInt32.TryParse(query["page"], out page)) // if (!String.IsNullOrEmpty(query["page"]) && UInt32.TryParse(query["page"], out page))
start = (int)page * ASSETS_PER_PAGE; // start = (int)page * ASSETS_PER_PAGE;
} // }
html.AppendLine(HEADER); // html.AppendLine(HEADER);
html.AppendLine("<p>"); // html.AppendLine("<p>");
if (page > 0) // if (page > 0)
html.AppendFormat("<a href=\"{0}?page={1}\">&lt; Previous Page</a> | ", httpRequest.RawUrl, page - 1); // html.AppendFormat("<a href=\"{0}?page={1}\">&lt; Previous Page</a> | ", httpRequest.RawUrl, page - 1);
html.AppendFormat("<a href=\"{0}?page={1}\">Next Page &gt;</a>", httpRequest.RawUrl, page + 1); // html.AppendFormat("<a href=\"{0}?page={1}\">Next Page &gt;</a>", httpRequest.RawUrl, page + 1);
html.AppendLine("</p>"); // html.AppendLine("</p>");
html.AppendLine(TABLE_HEADER); // html.AppendLine(TABLE_HEADER);
m_server.StorageProvider.ForEach( // m_server.StorageProvider.ForEach(
delegate(Metadata data) // delegate(Metadata data)
{ // {
if (m_server.AuthorizationProvider.IsMetadataAuthorized(authToken, data.ID)) // if (m_server.AuthorizationProvider.IsMetadataAuthorized(authToken, data.ID))
{ // {
html.AppendLine(String.Format( // html.AppendLine(String.Format(
"<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td><td>{5}</td></tr>", // "<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td><td>{5}</td></tr>",
data.Name, data.Description, data.ContentType, data.ID, data.Temporary, // data.Name, data.Description, data.ContentType, data.ID, data.Temporary,
BitConverter.ToString(data.SHA1).Replace("-", String.Empty))); // BitConverter.ToString(data.SHA1).Replace("-", String.Empty)));
} // }
else // else
{ // {
html.AppendLine(String.Format( // html.AppendLine(String.Format(
"<tr><td>[Protected Asset]</td><td>&nbsp;</td><td>&nbsp;</td><td>{0}</td><td>{1}</td><td>&nbsp;</td></tr>", // "<tr><td>[Protected Asset]</td><td>&nbsp;</td><td>&nbsp;</td><td>{0}</td><td>{1}</td><td>&nbsp;</td></tr>",
data.ID, data.Temporary)); // data.ID, data.Temporary));
} // }
}, start, ASSETS_PER_PAGE // }, start, ASSETS_PER_PAGE
); // );
html.AppendLine(TABLE_FOOTER); // html.AppendLine(TABLE_FOOTER);
html.AppendLine(FOOTER); // html.AppendLine(FOOTER);
byte[] responseData = System.Text.Encoding.UTF8.GetBytes(html.ToString()); // byte[] responseData = System.Text.Encoding.UTF8.GetBytes(html.ToString());
httpResponse.StatusCode = (int) HttpStatusCode.OK; // httpResponse.StatusCode = (int) HttpStatusCode.OK;
httpResponse.Body.Write(responseData, 0, responseData.Length); // httpResponse.Body.Write(responseData, 0, responseData.Length);
httpResponse.Body.Flush(); // httpResponse.Body.Flush();
return responseData; // return responseData;
} // }
#endregion IStreamedRequestHandler implementation // #endregion IStreamedRequestHandler implementation
} //}
} }
} }

View File

@ -153,37 +153,11 @@ namespace OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim
public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{ {
Metadata metadata = new Metadata(); AssetBase asset = null;
try try
{ {
AssetBase asset = (AssetBase) new XmlSerializer(typeof (AssetBase)).Deserialize(httpRequest.InputStream); asset = (AssetBase) new XmlSerializer(typeof (AssetBase)).Deserialize(httpRequest.InputStream);
if (asset.Data != null && asset.Data.Length > 0)
{
metadata.ID = asset.Metadata.FullID;
metadata.ContentType = Utils.SLAssetTypeToContentType((int) asset.Metadata.Type);
metadata.Name = asset.Metadata.Name;
metadata.Description = asset.Metadata.Description;
metadata.Temporary = asset.Metadata.Temporary;
metadata.SHA1 = OpenMetaverse.Utils.SHA1(asset.Data);
metadata.CreationDate = DateTime.Now;
BackendResponse storageResponse = m_server.StorageProvider.TryCreateAsset(metadata, asset.Data);
if (storageResponse == BackendResponse.Success)
httpResponse.StatusCode = (int) HttpStatusCode.Created;
else if (storageResponse == BackendResponse.NotFound)
httpResponse.StatusCode = (int) HttpStatusCode.NotFound;
else
httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError;
}
else
{
m_log.Warn("AssetPostHandler called with no asset data");
httpResponse.StatusCode = (int) HttpStatusCode.BadRequest;
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -191,6 +165,23 @@ namespace OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim
httpResponse.StatusCode = (int) HttpStatusCode.BadRequest; httpResponse.StatusCode = (int) HttpStatusCode.BadRequest;
} }
if (asset != null && asset.Data != null && asset.Data.Length > 0)
{
BackendResponse storageResponse = m_server.StorageProvider.TryCreateAsset(asset);
if (storageResponse == BackendResponse.Success)
httpResponse.StatusCode = (int) HttpStatusCode.Created;
else if (storageResponse == BackendResponse.NotFound)
httpResponse.StatusCode = (int) HttpStatusCode.NotFound;
else
httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError;
}
else
{
m_log.Warn("AssetPostHandler called with no asset data");
httpResponse.StatusCode = (int) HttpStatusCode.BadRequest;
}
return new byte[] {}; return new byte[] {};
} }
} }

View File

@ -30,7 +30,6 @@
using System; using System;
using System.Reflection; using System.Reflection;
using System.Data; using System.Data;
using MySql.Data.MySqlClient;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Data; using OpenSim.Data;
@ -54,46 +53,18 @@ namespace OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim
#region IAssetStorageProvider implementation #region IAssetStorageProvider implementation
public BackendResponse TryFetchMetadata(UUID assetID, out Metadata metadata) public BackendResponse TryFetchMetadata(UUID assetID, out AssetMetadata metadata)
{ {
metadata = null; metadata = null;
BackendResponse ret; BackendResponse ret;
using (MySqlConnection dbConnection = new MySqlConnection(m_openSimConfig.GetString("asset_database_connect"))) AssetBase asset = m_assetProvider.FetchAsset(assetID);
if (asset == null) ret = BackendResponse.NotFound;
else
{ {
IDataReader reader; metadata = asset.Metadata;
ret = BackendResponse.Success;
try
{
dbConnection.Open();
IDbCommand command = dbConnection.CreateCommand();
command.CommandText = String.Format("SELECT name,description,assetType,temporary FROM assets WHERE id='{0}'", assetID.ToString());
reader = command.ExecuteReader();
if (reader.Read())
{
metadata = new Metadata();
metadata.CreationDate = OpenMetaverse.Utils.Epoch;
metadata.SHA1 = null;
metadata.ID = assetID;
metadata.Name = reader.GetString(0);
metadata.Description = reader.GetString(1);
metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2));
metadata.Temporary = reader.GetBoolean(3);
ret = BackendResponse.Success;
}
else
{
ret = BackendResponse.NotFound;
}
}
catch (MySqlException ex)
{
m_log.Error("Connection to MySQL backend failed: " + ex.Message);
ret = BackendResponse.Failure;
}
} }
m_server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now); m_server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now);
@ -105,33 +76,13 @@ namespace OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim
assetData = null; assetData = null;
BackendResponse ret; BackendResponse ret;
using (MySqlConnection dbConnection = new MySqlConnection(m_openSimConfig.GetString("asset_database_connect"))) AssetBase asset = m_assetProvider.FetchAsset(assetID);
if (asset == null) ret = BackendResponse.NotFound;
else
{ {
IDataReader reader; assetData = asset.Data;
ret = BackendResponse.Success;
try
{
dbConnection.Open();
IDbCommand command = dbConnection.CreateCommand();
command.CommandText = String.Format("SELECT data FROM assets WHERE id='{0}'", assetID.ToString());
reader = command.ExecuteReader();
if (reader.Read())
{
assetData = (byte[])reader.GetValue(0);
ret = BackendResponse.Success;
}
else
{
ret = BackendResponse.NotFound;
}
}
catch (MySqlException ex)
{
m_log.Error("Connection to MySQL backend failed: " + ex.Message);
ret = BackendResponse.Failure;
}
} }
m_server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (assetData != null ? assetData.Length : 0), DateTime.Now); m_server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (assetData != null ? assetData.Length : 0), DateTime.Now);
@ -147,101 +98,63 @@ namespace OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim
return BackendResponse.Success; return BackendResponse.Success;
} }
public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData, out UUID assetID) public BackendResponse TryCreateAsset(AssetBase asset, out UUID assetID)
{ {
assetID = metadata.ID = UUID.Random(); assetID = asset.FullID = UUID.Random();
return TryCreateAsset(metadata, assetData); return TryCreateAsset(asset);
} }
public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData) public BackendResponse TryCreateAsset(AssetBase asset)
{ {
BackendResponse ret; BackendResponse ret;
using (MySqlConnection dbConnection = new MySqlConnection(m_openSimConfig.GetString("asset_database_connect"))) m_assetProvider.CreateAsset(asset);
{ ret = BackendResponse.Success;
try
{
dbConnection.Open();
MySqlCommand command = new MySqlCommand( m_server.MetricsProvider.LogAssetCreate(EXTENSION_NAME, ret, asset.FullID, asset.Data.Length, DateTime.Now);
"REPLACE INTO assets (name,description,assetType,local,temporary,data,id) VALUES " +
"(?name,?description,?assetType,?local,?temporary,?data,?id)", dbConnection);
command.Parameters.AddWithValue("?name", metadata.Name);
command.Parameters.AddWithValue("?description", metadata.Description);
command.Parameters.AddWithValue("?assetType", Utils.ContentTypeToSLAssetType(metadata.ContentType));
command.Parameters.AddWithValue("?local", 0);
command.Parameters.AddWithValue("?temporary", metadata.Temporary);
command.Parameters.AddWithValue("?data", assetData);
command.Parameters.AddWithValue("?id", metadata.ID.ToString());
int rowsAffected = command.ExecuteNonQuery();
if (rowsAffected == 1)
{
ret = BackendResponse.Success;
}
else if (rowsAffected == 2)
{
m_log.Info("Replaced asset " + metadata.ID.ToString());
ret = BackendResponse.Success;
}
else
{
m_log.ErrorFormat("MySQL REPLACE query affected {0} rows", rowsAffected);
ret = BackendResponse.Failure;
}
}
catch (MySqlException ex)
{
m_log.Error("Connection to MySQL backend failed: " + ex.Message);
ret = BackendResponse.Failure;
}
}
m_server.MetricsProvider.LogAssetCreate(EXTENSION_NAME, ret, metadata.ID, assetData.Length, DateTime.Now);
return ret; return ret;
} }
public int ForEach(Action<Metadata> action, int start, int count) public int ForEach(Action<AssetMetadata> action, int start, int count)
{ {
int rowCount = 0; int rowCount = 0;
using (MySqlConnection dbConnection = new MySqlConnection(m_openSimConfig.GetString("asset_database_connect"))) //using (MySqlConnection dbConnection = new MySqlConnection(m_openSimConfig.GetString("asset_database_connect")))
{ //{
MySqlDataReader reader; // MySqlDataReader reader;
try // try
{ // {
dbConnection.Open(); // dbConnection.Open();
MySqlCommand command = dbConnection.CreateCommand(); // MySqlCommand command = dbConnection.CreateCommand();
command.CommandText = String.Format("SELECT name,description,assetType,temporary,data,id FROM assets LIMIT {0}, {1}", // command.CommandText = String.Format("SELECT name,description,assetType,temporary,data,id FROM assets LIMIT {0}, {1}",
start, count); // start, count);
reader = command.ExecuteReader(); // reader = command.ExecuteReader();
} // }
catch (MySqlException ex) // catch (MySqlException ex)
{ // {
m_log.Error("Connection to MySQL backend failed: " + ex.Message); // m_log.Error("Connection to MySQL backend failed: " + ex.Message);
return 0; // return 0;
} // }
while (reader.Read()) // while (reader.Read())
{ // {
Metadata metadata = new Metadata(); // Metadata metadata = new Metadata();
metadata.CreationDate = OpenMetaverse.Utils.Epoch; // metadata.CreationDate = OpenMetaverse.Utils.Epoch;
metadata.Description = reader.GetString(1); // metadata.Description = reader.GetString(1);
metadata.ID = UUID.Parse(reader.GetString(5)); // metadata.ID = UUID.Parse(reader.GetString(5));
metadata.Name = reader.GetString(0); // metadata.Name = reader.GetString(0);
metadata.SHA1 = OpenMetaverse.Utils.SHA1((byte[])reader.GetValue(4)); // metadata.SHA1 = OpenMetaverse.Utils.SHA1((byte[])reader.GetValue(4));
metadata.Temporary = reader.GetBoolean(3); // metadata.Temporary = reader.GetBoolean(3);
metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2)); // metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2));
action(metadata); // action(metadata);
++rowCount; // ++rowCount;
} // }
reader.Close(); // reader.Close();
} //}
return rowCount; return rowCount;
} }

View File

@ -55,13 +55,13 @@ namespace OpenSim.Grid.AssetInventoryServer.Plugins
m_server = server; m_server = server;
// Asset metadata request // Asset metadata request
m_server.HttpServer.AddStreamHandler(new MetadataRequestHandler(server)); //m_server.HttpServer.AddStreamHandler(new MetadataRequestHandler(server));
// Asset data request // Asset data request
m_server.HttpServer.AddStreamHandler(new DataRequestHandler(server)); m_server.HttpServer.AddStreamHandler(new DataRequestHandler(server));
// Asset creation // Asset creation
m_server.HttpServer.AddStreamHandler(new CreateRequestHandler(server)); //m_server.HttpServer.AddStreamHandler(new CreateRequestHandler(server));
m_log.Info("[ASSET] Reference Frontend loaded."); m_log.Info("[ASSET] Reference Frontend loaded.");
} }
@ -92,95 +92,95 @@ namespace OpenSim.Grid.AssetInventoryServer.Plugins
#endregion IPlugin implementation #endregion IPlugin implementation
public class MetadataRequestHandler : IStreamedRequestHandler //public class MetadataRequestHandler : IStreamedRequestHandler
{ //{
AssetInventoryServer m_server; // AssetInventoryServer m_server;
string m_contentType; // string m_contentType;
string m_httpMethod; // string m_httpMethod;
string m_path; // string m_path;
public MetadataRequestHandler(AssetInventoryServer server) // public MetadataRequestHandler(AssetInventoryServer server)
{ // {
m_server = server; // m_server = server;
m_contentType = null; // m_contentType = null;
m_httpMethod = "GET"; // m_httpMethod = "GET";
m_path = @"^/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/metadata"; // m_path = @"^/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/metadata";
} // }
#region IStreamedRequestHandler implementation // #region IStreamedRequestHandler implementation
public string ContentType // public string ContentType
{ // {
get { return m_contentType; } // get { return m_contentType; }
} // }
public string HttpMethod // public string HttpMethod
{ // {
get { return m_httpMethod; } // get { return m_httpMethod; }
} // }
public string Path // public string Path
{ // {
get { return m_path; } // get { return m_path; }
} // }
public byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) // public byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{ // {
byte[] serializedData = null; // byte[] serializedData = null;
UUID assetID; // UUID assetID;
// Split the URL up into an AssetID and a method // // Split the URL up into an AssetID and a method
string[] rawUrl = httpRequest.Url.PathAndQuery.Split('/'); // string[] rawUrl = httpRequest.Url.PathAndQuery.Split('/');
if (rawUrl.Length >= 3 && UUID.TryParse(rawUrl[1], out assetID)) // if (rawUrl.Length >= 3 && UUID.TryParse(rawUrl[1], out assetID))
{ // {
UUID authToken = Utils.GetAuthToken(httpRequest); // UUID authToken = Utils.GetAuthToken(httpRequest);
if (m_server.AuthorizationProvider.IsMetadataAuthorized(authToken, assetID)) // if (m_server.AuthorizationProvider.IsMetadataAuthorized(authToken, assetID))
{ // {
Metadata metadata; // AssetMetadata metadata;
BackendResponse storageResponse = m_server.StorageProvider.TryFetchMetadata(assetID, out metadata); // BackendResponse storageResponse = m_server.StorageProvider.TryFetchMetadata(assetID, out metadata);
if (storageResponse == BackendResponse.Success) // if (storageResponse == BackendResponse.Success)
{ // {
// If the asset data location wasn't specified in the metadata, specify it // // If the asset data location wasn't specified in the metadata, specify it
// manually here by pointing back to this asset server // // manually here by pointing back to this asset server
if (!metadata.Methods.ContainsKey("data")) // if (!metadata.Methods.ContainsKey("data"))
{ // {
metadata.Methods["data"] = new Uri(String.Format("{0}://{1}/{2}/data", // metadata.Methods["data"] = new Uri(String.Format("{0}://{1}/{2}/data",
httpRequest.Url.Scheme, httpRequest.Url.Authority, assetID)); // httpRequest.Url.Scheme, httpRequest.Url.Authority, assetID));
} // }
serializedData = metadata.SerializeToBytes(); // serializedData = metadata.SerializeToBytes();
httpResponse.StatusCode = (int) HttpStatusCode.OK; // httpResponse.StatusCode = (int) HttpStatusCode.OK;
httpResponse.ContentType = "application/json"; // httpResponse.ContentType = "application/json";
httpResponse.ContentLength = serializedData.Length; // httpResponse.ContentLength = serializedData.Length;
httpResponse.Body.Write(serializedData, 0, serializedData.Length); // httpResponse.Body.Write(serializedData, 0, serializedData.Length);
} // }
else if (storageResponse == BackendResponse.NotFound) // else if (storageResponse == BackendResponse.NotFound)
{ // {
m_log.Warn("Could not find metadata for asset " + assetID.ToString()); // m_log.Warn("Could not find metadata for asset " + assetID.ToString());
httpResponse.StatusCode = (int) HttpStatusCode.NotFound; // httpResponse.StatusCode = (int) HttpStatusCode.NotFound;
} // }
else // else
{ // {
httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError; // httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError;
} // }
} // }
else // else
{ // {
httpResponse.StatusCode = (int) HttpStatusCode.Forbidden; // httpResponse.StatusCode = (int) HttpStatusCode.Forbidden;
} // }
return serializedData; // return serializedData;
} // }
httpResponse.StatusCode = (int) HttpStatusCode.NotFound; // httpResponse.StatusCode = (int) HttpStatusCode.NotFound;
return serializedData; // return serializedData;
} // }
#endregion IStreamedRequestHandler implementation // #endregion IStreamedRequestHandler implementation
} //}
public class DataRequestHandler : IStreamedRequestHandler public class DataRequestHandler : IStreamedRequestHandler
{ {
@ -261,110 +261,110 @@ namespace OpenSim.Grid.AssetInventoryServer.Plugins
#endregion IStreamedRequestHandler implementation #endregion IStreamedRequestHandler implementation
} }
public class CreateRequestHandler : IStreamedRequestHandler //public class CreateRequestHandler : IStreamedRequestHandler
{ //{
AssetInventoryServer m_server; // AssetInventoryServer m_server;
string m_contentType; // string m_contentType;
string m_httpMethod; // string m_httpMethod;
string m_path; // string m_path;
public CreateRequestHandler(AssetInventoryServer server) // public CreateRequestHandler(AssetInventoryServer server)
{ // {
m_server = server; // m_server = server;
m_contentType = null; // m_contentType = null;
m_httpMethod = "POST"; // m_httpMethod = "POST";
m_path = "^/createasset"; // m_path = "^/createasset";
} // }
#region IStreamedRequestHandler implementation // #region IStreamedRequestHandler implementation
public string ContentType // public string ContentType
{ // {
get { return m_contentType; } // get { return m_contentType; }
} // }
public string HttpMethod // public string HttpMethod
{ // {
get { return m_httpMethod; } // get { return m_httpMethod; }
} // }
public string Path // public string Path
{ // {
get { return m_path; } // get { return m_path; }
} // }
public byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) // public byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{ // {
byte[] responseData = null; // byte[] responseData = null;
UUID authToken = Utils.GetAuthToken(httpRequest); // UUID authToken = Utils.GetAuthToken(httpRequest);
if (m_server.AuthorizationProvider.IsCreateAuthorized(authToken)) // if (m_server.AuthorizationProvider.IsCreateAuthorized(authToken))
{ // {
try // try
{ // {
OSD osdata = OSDParser.DeserializeJson(new StreamReader(httpRequest.InputStream).ReadToEnd()); // OSD osdata = OSDParser.DeserializeJson(new StreamReader(httpRequest.InputStream).ReadToEnd());
if (osdata.Type == OSDType.Map) // if (osdata.Type == OSDType.Map)
{ // {
OSDMap map = (OSDMap)osdata; // OSDMap map = (OSDMap)osdata;
Metadata metadata = new Metadata(); // Metadata metadata = new Metadata();
metadata.Deserialize(map); // metadata.Deserialize(map);
byte[] assetData = map["data"].AsBinary(); // byte[] assetData = map["data"].AsBinary();
if (assetData != null && assetData.Length > 0) // if (assetData != null && assetData.Length > 0)
{ // {
BackendResponse storageResponse; // BackendResponse storageResponse;
if (metadata.ID != UUID.Zero) // if (metadata.ID != UUID.Zero)
storageResponse = m_server.StorageProvider.TryCreateAsset(metadata, assetData); // storageResponse = m_server.StorageProvider.TryCreateAsset(metadata, assetData);
else // else
storageResponse = m_server.StorageProvider.TryCreateAsset(metadata, assetData, out metadata.ID); // storageResponse = m_server.StorageProvider.TryCreateAsset(metadata, assetData, out metadata.ID);
if (storageResponse == BackendResponse.Success) // if (storageResponse == BackendResponse.Success)
{ // {
httpResponse.StatusCode = (int) HttpStatusCode.Created; // httpResponse.StatusCode = (int) HttpStatusCode.Created;
OSDMap responseMap = new OSDMap(1); // OSDMap responseMap = new OSDMap(1);
responseMap["id"] = OSD.FromUUID(metadata.ID); // responseMap["id"] = OSD.FromUUID(metadata.ID);
LitJson.JsonData jsonData = OSDParser.SerializeJson(responseMap); // LitJson.JsonData jsonData = OSDParser.SerializeJson(responseMap);
responseData = System.Text.Encoding.UTF8.GetBytes(jsonData.ToJson()); // responseData = System.Text.Encoding.UTF8.GetBytes(jsonData.ToJson());
httpResponse.Body.Write(responseData, 0, responseData.Length); // httpResponse.Body.Write(responseData, 0, responseData.Length);
httpResponse.Body.Flush(); // httpResponse.Body.Flush();
} // }
else if (storageResponse == BackendResponse.NotFound) // else if (storageResponse == BackendResponse.NotFound)
{ // {
httpResponse.StatusCode = (int) HttpStatusCode.NotFound; // httpResponse.StatusCode = (int) HttpStatusCode.NotFound;
} // }
else // else
{ // {
httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError; // httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError;
} // }
} // }
else // else
{ // {
httpResponse.StatusCode = (int) HttpStatusCode.BadRequest; // httpResponse.StatusCode = (int) HttpStatusCode.BadRequest;
} // }
} // }
else // else
{ // {
httpResponse.StatusCode = (int) HttpStatusCode.BadRequest; // httpResponse.StatusCode = (int) HttpStatusCode.BadRequest;
} // }
} // }
catch (Exception ex) // catch (Exception ex)
{ // {
httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError; // httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError;
httpResponse.StatusDescription = ex.Message; // httpResponse.StatusDescription = ex.Message;
} // }
} // }
else // else
{ // {
httpResponse.StatusCode = (int) HttpStatusCode.Forbidden; // httpResponse.StatusCode = (int) HttpStatusCode.Forbidden;
} // }
return responseData; // return responseData;
} // }
#endregion IStreamedRequestHandler implementation // #endregion IStreamedRequestHandler implementation
} //}
} }
} }

View File

@ -45,7 +45,7 @@ namespace OpenSim.Grid.AssetInventoryServer.Plugins.Simple
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
AssetInventoryServer server; AssetInventoryServer server;
Dictionary<UUID, Metadata> metadataStorage; Dictionary<UUID, AssetMetadata> metadataStorage;
Dictionary<UUID, string> filenames; Dictionary<UUID, string> filenames;
public SimpleAssetStoragePlugin() public SimpleAssetStoragePlugin()
@ -54,7 +54,7 @@ namespace OpenSim.Grid.AssetInventoryServer.Plugins.Simple
#region Required Interfaces #region Required Interfaces
public BackendResponse TryFetchMetadata(UUID assetID, out Metadata metadata) public BackendResponse TryFetchMetadata(UUID assetID, out AssetMetadata metadata)
{ {
metadata = null; metadata = null;
BackendResponse ret; BackendResponse ret;
@ -98,8 +98,9 @@ namespace OpenSim.Grid.AssetInventoryServer.Plugins.Simple
public BackendResponse TryFetchDataMetadata(UUID assetID, out AssetBase asset) public BackendResponse TryFetchDataMetadata(UUID assetID, out AssetBase asset)
{ {
Metadata metadata = null; asset = new AssetBase();
byte[] assetData = null; AssetMetadata metadata = asset.Metadata;
string filename; string filename;
BackendResponse ret; BackendResponse ret;
@ -108,7 +109,7 @@ namespace OpenSim.Grid.AssetInventoryServer.Plugins.Simple
{ {
try try
{ {
assetData = File.ReadAllBytes(filename); asset.Data = File.ReadAllBytes(filename);
ret = BackendResponse.Success; ret = BackendResponse.Success;
} }
catch (Exception ex) catch (Exception ex)
@ -116,80 +117,74 @@ namespace OpenSim.Grid.AssetInventoryServer.Plugins.Simple
m_log.ErrorFormat("Failed reading data for asset {0} from {1}: {2}", assetID, filename, ex.Message); m_log.ErrorFormat("Failed reading data for asset {0} from {1}: {2}", assetID, filename, ex.Message);
ret = BackendResponse.Failure; ret = BackendResponse.Failure;
} }
asset.Metadata.Type = (sbyte) Utils.ContentTypeToSLAssetType(asset.Metadata.ContentType);
asset.Metadata.Local = false;
} }
else else
{ {
asset = null;
ret = BackendResponse.NotFound; ret = BackendResponse.NotFound;
} }
asset = new AssetBase();
asset.Data = assetData;
asset.Metadata.FullID = metadata.ID;
asset.Metadata.Name = metadata.Name;
asset.Metadata.Description = metadata.Description;
asset.Metadata.CreationDate = metadata.CreationDate;
asset.Metadata.Type = (sbyte) Utils.ContentTypeToSLAssetType(metadata.ContentType);
asset.Metadata.Local = false;
asset.Metadata.Temporary = metadata.Temporary;
server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now); server.MetricsProvider.LogAssetMetadataFetch(EXTENSION_NAME, ret, assetID, DateTime.Now);
server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (assetData != null ? assetData.Length : 0), DateTime.Now); server.MetricsProvider.LogAssetDataFetch(EXTENSION_NAME, ret, assetID, (asset != null && asset.Data != null ? asset.Data.Length : 0), DateTime.Now);
return ret; return ret;
} }
public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData, out UUID assetID) public BackendResponse TryCreateAsset(AssetBase asset, out UUID assetID)
{ {
assetID = metadata.ID = UUID.Random(); assetID = asset.FullID = UUID.Random();
return TryCreateAsset(metadata, assetData); return TryCreateAsset(asset);
} }
public BackendResponse TryCreateAsset(Metadata metadata, byte[] assetData) public BackendResponse TryCreateAsset(AssetBase asset)
{ {
BackendResponse ret; BackendResponse ret;
string path; string path;
string filename = String.Format("{0}.{1}", metadata.ID, Utils.ContentTypeToExtension(metadata.ContentType)); string filename = String.Format("{0}.{1}", asset.FullID, Utils.ContentTypeToExtension(asset.Metadata.ContentType));
if (metadata.Temporary) if (asset.Metadata.Temporary)
path = Path.Combine(TEMP_DATA_DIR, filename); path = Path.Combine(TEMP_DATA_DIR, filename);
else else
path = Path.Combine(DEFAULT_DATA_DIR, filename); path = Path.Combine(DEFAULT_DATA_DIR, filename);
try try
{ {
File.WriteAllBytes(path, assetData); File.WriteAllBytes(path, asset.Data);
lock (filenames) filenames[metadata.ID] = path; lock (filenames) filenames[asset.FullID] = path;
// Set the creation date to right now // Set the creation date to right now
metadata.CreationDate = DateTime.Now; asset.Metadata.CreationDate = DateTime.Now;
lock (metadataStorage) lock (metadataStorage)
metadataStorage[metadata.ID] = metadata; metadataStorage[asset.FullID] = asset.Metadata;
ret = BackendResponse.Success; ret = BackendResponse.Success;
} }
catch (Exception ex) catch (Exception ex)
{ {
m_log.ErrorFormat("Failed writing data for asset {0} to {1}: {2}", metadata.ID, filename, ex.Message); m_log.ErrorFormat("Failed writing data for asset {0} to {1}: {2}", asset.FullID, filename, ex.Message);
ret = BackendResponse.Failure; ret = BackendResponse.Failure;
} }
server.MetricsProvider.LogAssetCreate(EXTENSION_NAME, ret, metadata.ID, assetData.Length, DateTime.Now); server.MetricsProvider.LogAssetCreate(EXTENSION_NAME, ret, asset.FullID, asset.Data.Length, DateTime.Now);
return ret; return ret;
} }
public int ForEach(Action<Metadata> action, int start, int count) public int ForEach(Action<AssetMetadata> action, int start, int count)
{ {
int rowCount = 0; int rowCount = 0;
lock (metadataStorage) //lock (metadataStorage)
{ //{
foreach (Metadata metadata in metadataStorage.Values) // foreach (Metadata metadata in metadataStorage.Values)
{ // {
action(metadata); // action(metadata);
++rowCount; // ++rowCount;
} // }
} //}
return rowCount; return rowCount;
} }
@ -202,7 +197,7 @@ namespace OpenSim.Grid.AssetInventoryServer.Plugins.Simple
{ {
this.server = server; this.server = server;
metadataStorage = new Dictionary<UUID, Metadata>(); metadataStorage = new Dictionary<UUID, AssetMetadata>();
filenames = new Dictionary<UUID, string>(); filenames = new Dictionary<UUID, string>();
LoadFiles(DEFAULT_DATA_DIR, false); LoadFiles(DEFAULT_DATA_DIR, false);
@ -272,18 +267,18 @@ namespace OpenSim.Grid.AssetInventoryServer.Plugins.Simple
string filename = assets[i]; string filename = assets[i];
byte[] data = File.ReadAllBytes(filename); byte[] data = File.ReadAllBytes(filename);
Metadata metadata = new Metadata(); AssetMetadata metadata = new AssetMetadata();
metadata.CreationDate = File.GetCreationTime(filename); metadata.CreationDate = File.GetCreationTime(filename);
metadata.Description = String.Empty; metadata.Description = String.Empty;
metadata.ID = SimpleUtils.ParseUUIDFromFilename(filename); metadata.FullID = SimpleUtils.ParseUUIDFromFilename(filename);
metadata.Name = SimpleUtils.ParseNameFromFilename(filename); metadata.Name = SimpleUtils.ParseNameFromFilename(filename);
metadata.SHA1 = OpenMetaverse.Utils.SHA1(data); metadata.SHA1 = OpenMetaverse.Utils.SHA1(data);
metadata.Temporary = false; metadata.Temporary = false;
metadata.ContentType = Utils.ExtensionToContentType(Path.GetExtension(filename).TrimStart('.')); metadata.ContentType = Utils.ExtensionToContentType(Path.GetExtension(filename).TrimStart('.'));
// Store the loaded data // Store the loaded data
metadataStorage[metadata.ID] = metadata; metadataStorage[metadata.FullID] = metadata;
filenames[metadata.ID] = filename; filenames[metadata.FullID] = filename;
} }
} }
catch (Exception ex) catch (Exception ex)

View File

@ -851,7 +851,6 @@
<Reference name="OpenSim.Framework" /> <Reference name="OpenSim.Framework" />
<Reference name="OpenSim.Grid.AssetInventoryServer" /> <Reference name="OpenSim.Grid.AssetInventoryServer" />
<Reference name="OpenSim.Framework.Servers"/> <Reference name="OpenSim.Framework.Servers"/>
<Reference name="MySql.Data"/>
<Reference name="log4net"/> <Reference name="log4net"/>
<Reference name="Nini.dll" /> <Reference name="Nini.dll" />