Added assets service method AssetsExist(), which returns whether the given list of assets exist.
This method is used to optimize sending assets with embedded assets: e.g., when a Hypergrid visitor takes an item into the inventory.0.8.0.3
parent
ac16a667e1
commit
d1c3f8eef5
|
@ -37,9 +37,8 @@ namespace OpenSim.Data
|
||||||
public abstract class AssetDataBase : IAssetDataPlugin
|
public abstract class AssetDataBase : IAssetDataPlugin
|
||||||
{
|
{
|
||||||
public abstract AssetBase GetAsset(UUID uuid);
|
public abstract AssetBase GetAsset(UUID uuid);
|
||||||
|
|
||||||
public abstract void StoreAsset(AssetBase asset);
|
public abstract void StoreAsset(AssetBase asset);
|
||||||
public abstract bool ExistsAsset(UUID uuid);
|
public abstract bool[] AssetsExist(UUID[] uuids);
|
||||||
|
|
||||||
public abstract List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
public abstract List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace OpenSim.Data
|
||||||
{
|
{
|
||||||
AssetBase GetAsset(UUID uuid);
|
AssetBase GetAsset(UUID uuid);
|
||||||
void StoreAsset(AssetBase asset);
|
void StoreAsset(AssetBase asset);
|
||||||
bool ExistsAsset(UUID uuid);
|
bool[] AssetsExist(UUID[] uuids);
|
||||||
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
||||||
void Initialise(string connect);
|
void Initialise(string connect);
|
||||||
bool Delete(string id);
|
bool Delete(string id);
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace OpenSim.Data
|
||||||
{
|
{
|
||||||
AssetBase GetAsset(UUID uuid);
|
AssetBase GetAsset(UUID uuid);
|
||||||
void StoreAsset(AssetBase asset);
|
void StoreAsset(AssetBase asset);
|
||||||
bool ExistsAsset(UUID uuid);
|
bool[] AssetsExist(UUID[] uuids);
|
||||||
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
||||||
void Initialise(string connect);
|
void Initialise(string connect);
|
||||||
bool Delete(string id);
|
bool Delete(string id);
|
||||||
|
|
|
@ -225,17 +225,38 @@ namespace OpenSim.Data.MSSQL
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if asset exist in m_database
|
/// Check if the assets exist in the database.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="uuid"></param>
|
/// <param name="uuids">The assets' IDs</param>
|
||||||
/// <returns>true if exist.</returns>
|
/// <returns>For each asset: true if it exists, false otherwise</returns>
|
||||||
override public bool ExistsAsset(UUID uuid)
|
public override bool[] AssetsExist(UUID[] uuids)
|
||||||
{
|
{
|
||||||
if (GetAsset(uuid) != null)
|
if (uuids.Length == 0)
|
||||||
|
return new bool[0];
|
||||||
|
|
||||||
|
HashSet<UUID> exist = new HashSet<UUID>();
|
||||||
|
|
||||||
|
string ids = "'" + string.Join("','", uuids) + "'";
|
||||||
|
string sql = string.Format("SELECT id FROM assets WHERE id IN ({0})", ids);
|
||||||
|
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
return true;
|
conn.Open();
|
||||||
|
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
UUID id = DBGuid.FromDB(reader["id"]);
|
||||||
|
exist.Add(id);
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool[] results = new bool[uuids.Length];
|
||||||
|
for (int i = 0; i < uuids.Length; i++)
|
||||||
|
results[i] = exist.Contains(uuids[i]);
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -257,46 +257,44 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if the asset exists in the database
|
/// Check if the assets exist in the database.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="uuid">The asset UUID</param>
|
/// <param name="uuidss">The assets' IDs</param>
|
||||||
/// <returns>true if it exists, false otherwise.</returns>
|
/// <returns>For each asset: true if it exists, false otherwise</returns>
|
||||||
override public bool ExistsAsset(UUID uuid)
|
public override bool[] AssetsExist(UUID[] uuids)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[ASSETS DB]: Checking for asset {0}", uuid);
|
if (uuids.Length == 0)
|
||||||
|
return new bool[0];
|
||||||
|
|
||||||
bool assetExists = false;
|
HashSet<UUID> exist = new HashSet<UUID>();
|
||||||
|
|
||||||
|
string ids = "'" + string.Join("','", uuids) + "'";
|
||||||
|
string sql = string.Format("SELECT id FROM assets WHERE id IN ({0})", ids);
|
||||||
|
|
||||||
lock (m_dbLock)
|
lock (m_dbLock)
|
||||||
{
|
{
|
||||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
using (MySqlCommand cmd = new MySqlCommand("SELECT id FROM assets WHERE id=?id", dbcon))
|
using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue("?id", uuid.ToString());
|
using (MySqlDataReader dbReader = cmd.ExecuteReader())
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
|
while (dbReader.Read())
|
||||||
{
|
{
|
||||||
if (dbReader.Read())
|
UUID id = DBGuid.FromDB(dbReader["id"]);
|
||||||
{
|
exist.Add(id);
|
||||||
// m_log.DebugFormat("[ASSETS DB]: Found asset {0}", uuid);
|
|
||||||
assetExists = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.Error(
|
|
||||||
string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", uuid), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return assetExists;
|
bool[] results = new bool[uuids.Length];
|
||||||
|
for (int i = 0; i < uuids.Length; i++)
|
||||||
|
results[i] = exist.Contains(uuids[i]);
|
||||||
|
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -397,45 +397,43 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if the asset exists in the database
|
/// Check if the assets exist in the database.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="uuid">The asset UUID</param>
|
/// <param name="uuids">The asset UUID's</param>
|
||||||
/// <returns>true if it exists, false otherwise.</returns>
|
/// <returns>For each asset: true if it exists, false otherwise</returns>
|
||||||
public bool ExistsAsset(UUID uuid)
|
public bool[] AssetsExist(UUID[] uuids)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[ASSETS DB]: Checking for asset {0}", uuid);
|
if (uuids.Length == 0)
|
||||||
|
return new bool[0];
|
||||||
|
|
||||||
bool assetExists = false;
|
HashSet<UUID> exists = new HashSet<UUID>();
|
||||||
|
|
||||||
|
string ids = "'" + string.Join("','", uuids) + "'";
|
||||||
|
string sql = string.Format("SELECT ID FROM assets WHERE ID IN ({0})", ids);
|
||||||
|
|
||||||
lock (m_dbLock)
|
lock (m_dbLock)
|
||||||
{
|
{
|
||||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
using (MySqlCommand cmd = new MySqlCommand("SELECT ID FROM XAssetsMeta WHERE ID=?ID", dbcon))
|
using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue("?ID", uuid.ToString());
|
using (MySqlDataReader dbReader = cmd.ExecuteReader())
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
|
while (dbReader.Read())
|
||||||
{
|
{
|
||||||
if (dbReader.Read())
|
UUID id = DBGuid.FromDB(dbReader["ID"]);
|
||||||
{
|
exists.Add(id);
|
||||||
// m_log.DebugFormat("[ASSETS DB]: Found asset {0}", uuid);
|
|
||||||
assetExists = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.Error(string.Format("[XASSETS DB]: MySql failure fetching asset {0}", uuid), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return assetExists;
|
bool[] results = new bool[uuids.Length];
|
||||||
|
for (int i = 0; i < uuids.Length; i++)
|
||||||
|
results[i] = exists.Contains(uuids[i]);
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -231,17 +231,38 @@ namespace OpenSim.Data.PGSQL
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if asset exist in m_database
|
/// Check if the assets exist in the database.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="uuid"></param>
|
/// <param name="uuids">The assets' IDs</param>
|
||||||
/// <returns>true if exist.</returns>
|
/// <returns>For each asset: true if it exists, false otherwise</returns>
|
||||||
override public bool ExistsAsset(UUID uuid)
|
public override bool[] AssetsExist(UUID[] uuids)
|
||||||
{
|
{
|
||||||
if (GetAsset(uuid) != null)
|
if (uuids.Length == 0)
|
||||||
|
return new bool[0];
|
||||||
|
|
||||||
|
HashSet<UUID> exist = new HashSet<UUID>();
|
||||||
|
|
||||||
|
string ids = "'" + string.Join("','", uuids) + "'";
|
||||||
|
string sql = string.Format("SELECT id FROM assets WHERE id IN ({0})", ids);
|
||||||
|
|
||||||
|
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||||
|
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
return true;
|
conn.Open();
|
||||||
|
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
UUID id = DBGuid.FromDB(reader["id"]);
|
||||||
|
exist.Add(id);
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool[] results = new bool[uuids.Length];
|
||||||
|
for (int i = 0; i < uuids.Length; i++)
|
||||||
|
results[i] = exist.Contains(uuids[i]);
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -406,6 +406,43 @@ namespace OpenSim.Data.PGSQL
|
||||||
return exists;
|
return exists;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if the assets exist in the database.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uuids">The assets' IDs</param>
|
||||||
|
/// <returns>For each asset: true if it exists, false otherwise</returns>
|
||||||
|
public bool[] AssetsExist(UUID[] uuids)
|
||||||
|
{
|
||||||
|
if (uuids.Length == 0)
|
||||||
|
return new bool[0];
|
||||||
|
|
||||||
|
HashSet<UUID> exist = new HashSet<UUID>();
|
||||||
|
|
||||||
|
string ids = "'" + string.Join("','", uuids) + "'";
|
||||||
|
string sql = string.Format(@"SELECT ""ID"" FROM XAssetsMeta WHERE ""ID"" IN ({0})", ids);
|
||||||
|
|
||||||
|
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||||
|
{
|
||||||
|
conn.Open();
|
||||||
|
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||||
|
{
|
||||||
|
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
UUID id = DBGuid.FromDB(reader["id"]);
|
||||||
|
exist.Add(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool[] results = new bool[uuids.Length];
|
||||||
|
for (int i = 0; i < uuids.Length; i++)
|
||||||
|
results[i] = exist.Contains(uuids[i]);
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if the asset exists in the database
|
/// Check if the asset exists in the database
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -152,7 +152,7 @@ namespace OpenSim.Data.SQLite
|
||||||
}
|
}
|
||||||
|
|
||||||
//m_log.Info("[ASSET DB]: Creating Asset " + asset.FullID.ToString());
|
//m_log.Info("[ASSET DB]: Creating Asset " + asset.FullID.ToString());
|
||||||
if (ExistsAsset(asset.FullID))
|
if (AssetsExist(new[] { asset.FullID })[0])
|
||||||
{
|
{
|
||||||
//LogAssetLoad(asset);
|
//LogAssetLoad(asset);
|
||||||
|
|
||||||
|
@ -214,32 +214,39 @@ namespace OpenSim.Data.SQLite
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if an asset exist in database
|
/// Check if the assets exist in the database.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="uuid">The asset UUID</param>
|
/// <param name="uuids">The assets' IDs</param>
|
||||||
/// <returns>True if exist, or false.</returns>
|
/// <returns>For each asset: true if it exists, false otherwise</returns>
|
||||||
override public bool ExistsAsset(UUID uuid)
|
public override bool[] AssetsExist(UUID[] uuids)
|
||||||
{
|
{
|
||||||
|
if (uuids.Length == 0)
|
||||||
|
return new bool[0];
|
||||||
|
|
||||||
|
HashSet<UUID> exist = new HashSet<UUID>();
|
||||||
|
|
||||||
|
string ids = "'" + string.Join("','", uuids) + "'";
|
||||||
|
string sql = string.Format("SELECT id FROM assets WHERE id IN ({0})", ids);
|
||||||
|
|
||||||
lock (this)
|
lock (this)
|
||||||
{
|
{
|
||||||
using (SqliteCommand cmd = new SqliteCommand(SelectAssetSQL, m_conn))
|
using (SqliteCommand cmd = new SqliteCommand(SelectAssetSQL, m_conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.Add(new SqliteParameter(":UUID", uuid.ToString()));
|
|
||||||
using (IDataReader reader = cmd.ExecuteReader())
|
using (IDataReader reader = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
if (reader.Read())
|
while (reader.Read())
|
||||||
{
|
{
|
||||||
reader.Close();
|
UUID id = new UUID((string)reader["UUID"]);
|
||||||
return true;
|
exist.Add(id);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reader.Close();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool[] results = new bool[uuids.Length];
|
||||||
|
for (int i = 0; i < uuids.Length; i++)
|
||||||
|
results[i] = exist.Contains(uuids[i]);
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -108,9 +108,10 @@ namespace OpenSim.Data.Tests
|
||||||
{
|
{
|
||||||
TestHelpers.InMethod();
|
TestHelpers.InMethod();
|
||||||
|
|
||||||
Assert.That(m_db.ExistsAsset(uuid1), Is.False);
|
bool[] exist = m_db.AssetsExist(new[] { uuid1, uuid2, uuid3 });
|
||||||
Assert.That(m_db.ExistsAsset(uuid2), Is.False);
|
Assert.IsFalse(exist[0]);
|
||||||
Assert.That(m_db.ExistsAsset(uuid3), Is.False);
|
Assert.IsFalse(exist[1]);
|
||||||
|
Assert.IsFalse(exist[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -159,9 +160,10 @@ namespace OpenSim.Data.Tests
|
||||||
AssetBase a3b = m_db.GetAsset(uuid3);
|
AssetBase a3b = m_db.GetAsset(uuid3);
|
||||||
Assert.That(a3b, Constraints.PropertyCompareConstraint(a3a));
|
Assert.That(a3b, Constraints.PropertyCompareConstraint(a3a));
|
||||||
|
|
||||||
Assert.That(m_db.ExistsAsset(uuid1), Is.True);
|
bool[] exist = m_db.AssetsExist(new[] { uuid1, uuid2, uuid3 });
|
||||||
Assert.That(m_db.ExistsAsset(uuid2), Is.True);
|
Assert.IsTrue(exist[0]);
|
||||||
Assert.That(m_db.ExistsAsset(uuid3), Is.True);
|
Assert.IsTrue(exist[1]);
|
||||||
|
Assert.IsTrue(exist[2]);
|
||||||
|
|
||||||
List<AssetMetadata> metadatas = m_db.FetchAssetMetadataSet(0, 1000);
|
List<AssetMetadata> metadatas = m_db.FetchAssetMetadataSet(0, 1000);
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,8 @@ using OpenMetaverse;
|
||||||
using OpenMetaverse.StructuredData;
|
using OpenMetaverse.StructuredData;
|
||||||
using Amib.Threading;
|
using Amib.Threading;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
namespace OpenSim.Framework
|
namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
|
@ -865,6 +867,54 @@ namespace OpenSim.Framework
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parses a foreign asset ID.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">A possibly-foreign asset ID: http://grid.example.com:8002/00000000-0000-0000-0000-000000000000 </param>
|
||||||
|
/// <param name="url">The URL: http://grid.example.com:8002</param>
|
||||||
|
/// <param name="assetID">The asset ID: 00000000-0000-0000-0000-000000000000. Returned even if 'id' isn't foreign.</param>
|
||||||
|
/// <returns>True: this is a foreign asset ID; False: it isn't</returns>
|
||||||
|
public static bool ParseForeignAssetID(string id, out string url, out string assetID)
|
||||||
|
{
|
||||||
|
url = String.Empty;
|
||||||
|
assetID = String.Empty;
|
||||||
|
|
||||||
|
UUID uuid;
|
||||||
|
if (UUID.TryParse(id, out uuid))
|
||||||
|
{
|
||||||
|
assetID = uuid.ToString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((id.Length == 0) || (id[0] != 'h' && id[0] != 'H'))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Uri assetUri;
|
||||||
|
if (!Uri.TryCreate(id, UriKind.Absolute, out assetUri) || assetUri.Scheme != Uri.UriSchemeHttp)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Simian
|
||||||
|
if (assetUri.Query != string.Empty)
|
||||||
|
{
|
||||||
|
NameValueCollection qscoll = HttpUtility.ParseQueryString(assetUri.Query);
|
||||||
|
assetID = qscoll["id"];
|
||||||
|
if (assetID != null)
|
||||||
|
url = id.Replace(assetID, ""); // Malformed again, as simian expects
|
||||||
|
else
|
||||||
|
url = id; // !!! best effort
|
||||||
|
}
|
||||||
|
else // robust
|
||||||
|
{
|
||||||
|
url = "http://" + assetUri.Authority;
|
||||||
|
assetID = assetUri.LocalPath.Trim(new char[] { '/' });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!UUID.TryParse(assetID, out uuid))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes all invalid path chars (OS dependent)
|
/// Removes all invalid path chars (OS dependent)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1038,6 +1038,18 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool[] AssetsExist(string[] ids)
|
||||||
|
{
|
||||||
|
bool[] exist = new bool[ids.Length];
|
||||||
|
|
||||||
|
for (int i = 0; i < ids.Length; i++)
|
||||||
|
{
|
||||||
|
exist[i] = Check(ids[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return exist;
|
||||||
|
}
|
||||||
|
|
||||||
public string Store(AssetBase asset)
|
public string Store(AssetBase asset)
|
||||||
{
|
{
|
||||||
if (asset.FullID == UUID.Zero)
|
if (asset.FullID == UUID.Zero)
|
||||||
|
|
|
@ -145,11 +145,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
string id = m_scene.AssetService.Store(asset1);
|
string id = m_scene.AssetService.Store(asset1);
|
||||||
if (id == string.Empty)
|
if (id == string.Empty)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[HG ASSET MAPPER]: Asset server {0} did not accept {1}", url, asset.ID);
|
m_log.DebugFormat("[HG ASSET MAPPER]: Failed to post asset {0} to asset server {1}: the server did not accept the asset", asset.ID, url);
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_log.DebugFormat("[HG ASSET MAPPER]: Posted copy of asset {0} from local asset server to {1}", asset1.ID, url);
|
m_log.DebugFormat("[HG ASSET MAPPER]: Posted asset {0} to asset server {1}", asset1.ID, url);
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
@ -279,36 +279,65 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
|
|
||||||
public void Post(UUID assetID, UUID ownerID, string userAssetURL)
|
public void Post(UUID assetID, UUID ownerID, string userAssetURL)
|
||||||
{
|
{
|
||||||
// Post the item from the local AssetCache onto the remote asset server
|
m_log.DebugFormat("[HG ASSET MAPPER]: Starting to send asset {0} with children to asset server {1}", assetID, userAssetURL);
|
||||||
// and place an entry in m_assetMap
|
|
||||||
|
// Find all the embedded assets
|
||||||
|
|
||||||
m_log.Debug("[HG ASSET MAPPER]: Posting object " + assetID + " to asset server " + userAssetURL);
|
|
||||||
AssetBase asset = m_scene.AssetService.Get(assetID.ToString());
|
AssetBase asset = m_scene.AssetService.Get(assetID.ToString());
|
||||||
if (asset != null)
|
if (asset == null)
|
||||||
{
|
{
|
||||||
|
m_log.DebugFormat("[HG ASSET MAPPER]: Something wrong with asset {0}, it could not be found", assetID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Dictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>();
|
Dictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>();
|
||||||
HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, string.Empty);
|
HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, string.Empty);
|
||||||
uuidGatherer.GatherAssetUuids(asset.FullID, asset.Type, ids);
|
uuidGatherer.GatherAssetUuids(asset.FullID, asset.Type, ids);
|
||||||
bool success = false;
|
|
||||||
|
// Check which assets already exist in the destination server
|
||||||
|
|
||||||
|
string url = userAssetURL;
|
||||||
|
if (!url.EndsWith("/") && !url.EndsWith("="))
|
||||||
|
url = url + "/";
|
||||||
|
|
||||||
|
string[] remoteAssetIDs = new string[ids.Count];
|
||||||
|
int i = 0;
|
||||||
|
foreach (UUID id in ids.Keys)
|
||||||
|
remoteAssetIDs[i++] = url + id.ToString();
|
||||||
|
|
||||||
|
bool[] exist = m_scene.AssetService.AssetsExist(remoteAssetIDs);
|
||||||
|
|
||||||
|
var existSet = new HashSet<string>();
|
||||||
|
i = 0;
|
||||||
|
foreach (UUID id in ids.Keys)
|
||||||
|
{
|
||||||
|
if (exist[i])
|
||||||
|
existSet.Add(id.ToString());
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send only those assets which don't already exist in the destination server
|
||||||
|
|
||||||
|
bool success = true;
|
||||||
|
|
||||||
foreach (UUID uuid in ids.Keys)
|
foreach (UUID uuid in ids.Keys)
|
||||||
|
{
|
||||||
|
if (!existSet.Contains(uuid.ToString()))
|
||||||
{
|
{
|
||||||
asset = m_scene.AssetService.Get(uuid.ToString());
|
asset = m_scene.AssetService.Get(uuid.ToString());
|
||||||
if (asset == null)
|
if (asset == null)
|
||||||
m_log.DebugFormat("[HG ASSET MAPPER]: Could not find asset {0}", uuid);
|
m_log.DebugFormat("[HG ASSET MAPPER]: Could not find asset {0}", uuid);
|
||||||
else
|
else
|
||||||
success = PostAsset(userAssetURL, asset);
|
success &= PostAsset(userAssetURL, asset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_log.DebugFormat("[HG ASSET MAPPER]: Didn't post asset {0} because it already exists in asset server {1}", uuid, userAssetURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// maybe all pieces got there...
|
|
||||||
if (!success)
|
if (!success)
|
||||||
m_log.DebugFormat("[HG ASSET MAPPER]: Problems posting item {0} to asset server {1}", assetID, userAssetURL);
|
m_log.DebugFormat("[HG ASSET MAPPER]: Problems sending asset {0} with children to asset server {1}", assetID, userAssetURL);
|
||||||
else
|
else
|
||||||
m_log.DebugFormat("[HG ASSET MAPPER]: Successfully posted item {0} to asset server {1}", assetID, userAssetURL);
|
m_log.DebugFormat("[HG ASSET MAPPER]: Successfully sent asset {0} with children to asset server {1}", assetID, userAssetURL);
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_log.DebugFormat("[HG ASSET MAPPER]: Something wrong with asset {0}, it could not be found", assetID);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -312,6 +312,23 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual bool[] AssetsExist(string[] ids)
|
||||||
|
{
|
||||||
|
int numHG = 0;
|
||||||
|
foreach (string id in ids)
|
||||||
|
{
|
||||||
|
if (IsHG(id))
|
||||||
|
++numHG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numHG == 0)
|
||||||
|
return m_GridService.AssetsExist(ids);
|
||||||
|
else if (numHG == ids.Length)
|
||||||
|
return m_HGService.AssetsExist(ids);
|
||||||
|
else
|
||||||
|
throw new Exception("[HG ASSET CONNECTOR]: AssetsExist: all the assets must be either local or foreign");
|
||||||
|
}
|
||||||
|
|
||||||
public string Store(AssetBase asset)
|
public string Store(AssetBase asset)
|
||||||
{
|
{
|
||||||
bool isHG = IsHG(asset.ID);
|
bool isHG = IsHG(asset.ID);
|
||||||
|
|
|
@ -253,6 +253,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool[] AssetsExist(string[] ids)
|
||||||
|
{
|
||||||
|
return m_AssetService.AssetsExist(ids);
|
||||||
|
}
|
||||||
|
|
||||||
public string Store(AssetBase asset)
|
public string Store(AssetBase asset)
|
||||||
{
|
{
|
||||||
if (m_Cache != null)
|
if (m_Cache != null)
|
||||||
|
|
|
@ -86,6 +86,7 @@ namespace OpenSim.Server.Handlers.Asset
|
||||||
server.AddStreamHandler(new AssetServerGetHandler(m_AssetService));
|
server.AddStreamHandler(new AssetServerGetHandler(m_AssetService));
|
||||||
server.AddStreamHandler(new AssetServerPostHandler(m_AssetService));
|
server.AddStreamHandler(new AssetServerPostHandler(m_AssetService));
|
||||||
server.AddStreamHandler(new AssetServerDeleteHandler(m_AssetService, allowedRemoteDeleteTypes));
|
server.AddStreamHandler(new AssetServerDeleteHandler(m_AssetService, allowedRemoteDeleteTypes));
|
||||||
|
server.AddStreamHandler(new AssetsExistHandler(m_AssetService));
|
||||||
|
|
||||||
MainConsole.Instance.Commands.AddCommand("Assets", false,
|
MainConsole.Instance.Commands.AddCommand("Assets", false,
|
||||||
"show asset",
|
"show asset",
|
||||||
|
|
|
@ -64,9 +64,14 @@ namespace OpenSim.Server.Handlers.Asset
|
||||||
if (p.Length == 0)
|
if (p.Length == 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (p.Length > 1 && p[1] == "data")
|
if (p.Length > 1)
|
||||||
{
|
{
|
||||||
result = m_AssetService.GetData(p[0]);
|
string id = p[0];
|
||||||
|
string cmd = p[1];
|
||||||
|
|
||||||
|
if (cmd == "data")
|
||||||
|
{
|
||||||
|
result = m_AssetService.GetData(id);
|
||||||
if (result == null)
|
if (result == null)
|
||||||
{
|
{
|
||||||
httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
|
httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
|
||||||
|
@ -79,9 +84,9 @@ namespace OpenSim.Server.Handlers.Asset
|
||||||
httpResponse.ContentType = "application/octet-stream";
|
httpResponse.ContentType = "application/octet-stream";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (p.Length > 1 && p[1] == "metadata")
|
else if (cmd == "metadata")
|
||||||
{
|
{
|
||||||
AssetMetadata metadata = m_AssetService.GetMetadata(p[0]);
|
AssetMetadata metadata = m_AssetService.GetMetadata(id);
|
||||||
|
|
||||||
if (metadata != null)
|
if (metadata != null)
|
||||||
{
|
{
|
||||||
|
@ -102,7 +107,18 @@ namespace OpenSim.Server.Handlers.Asset
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AssetBase asset = m_AssetService.Get(p[0]);
|
// Unknown request
|
||||||
|
httpResponse.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||||
|
httpResponse.ContentType = "text/plain";
|
||||||
|
result = new byte[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (p.Length == 1)
|
||||||
|
{
|
||||||
|
// Get the entire asset (metadata + data)
|
||||||
|
|
||||||
|
string id = p[0];
|
||||||
|
AssetBase asset = m_AssetService.Get(id);
|
||||||
|
|
||||||
if (asset != null)
|
if (asset != null)
|
||||||
{
|
{
|
||||||
|
@ -120,6 +136,14 @@ namespace OpenSim.Server.Handlers.Asset
|
||||||
result = new byte[0];
|
result = new byte[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Unknown request
|
||||||
|
httpResponse.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||||
|
httpResponse.ContentType = "text/plain";
|
||||||
|
result = new byte[0];
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Nini.Config;
|
||||||
|
using log4net;
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using OpenSim.Server.Base;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
namespace OpenSim.Server.Handlers.Asset
|
||||||
|
{
|
||||||
|
public class AssetsExistHandler : BaseStreamHandler
|
||||||
|
{
|
||||||
|
//private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private IAssetService m_AssetService;
|
||||||
|
|
||||||
|
public AssetsExistHandler(IAssetService service) :
|
||||||
|
base("POST", "/get_assets_exist")
|
||||||
|
{
|
||||||
|
m_AssetService = service;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||||
|
{
|
||||||
|
XmlSerializer xs;
|
||||||
|
|
||||||
|
string[] ids;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
xs = new XmlSerializer(typeof(string[]));
|
||||||
|
ids = (string[])xs.Deserialize(request);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
httpResponse.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool[] exist = m_AssetService.AssetsExist(ids);
|
||||||
|
|
||||||
|
xs = new XmlSerializer(typeof(bool[]));
|
||||||
|
return ServerUtils.SerializeResult(xs, exist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -153,9 +153,24 @@ namespace OpenSim.Services.AssetService
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual bool[] AssetsExist(string[] ids)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UUID[] uuid = Array.ConvertAll(ids, id => UUID.Parse(id));
|
||||||
|
return m_Database.AssetsExist(uuid);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.Error("[ASSET SERVICE]: Exception getting assets ", e);
|
||||||
|
return new bool[ids.Length];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public virtual string Store(AssetBase asset)
|
public virtual string Store(AssetBase asset)
|
||||||
{
|
{
|
||||||
if (!m_Database.ExistsAsset(asset.FullID))
|
bool exists = m_Database.AssetsExist(new[] { asset.FullID })[0];
|
||||||
|
if (!exists)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[ASSET SERVICE]: Storing asset {0} {1}, bytes {2}", asset.Name, asset.FullID, asset.Data.Length);
|
// "[ASSET SERVICE]: Storing asset {0} {1}, bytes {2}", asset.Name, asset.FullID, asset.Data.Length);
|
||||||
|
|
|
@ -175,9 +175,16 @@ namespace OpenSim.Services.AssetService
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual bool[] AssetsExist(string[] ids)
|
||||||
|
{
|
||||||
|
UUID[] uuid = Array.ConvertAll(ids, id => UUID.Parse(id));
|
||||||
|
return m_Database.AssetsExist(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual string Store(AssetBase asset)
|
public virtual string Store(AssetBase asset)
|
||||||
{
|
{
|
||||||
if (!m_Database.ExistsAsset(asset.FullID))
|
bool exists = m_Database.AssetsExist(new[] { asset.FullID })[0];
|
||||||
|
if (!exists)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[XASSET SERVICE]: Storing asset {0} {1}, bytes {2}", asset.Name, asset.FullID, asset.Data.Length);
|
// "[XASSET SERVICE]: Storing asset {0} {1}, bytes {2}", asset.Name, asset.FullID, asset.Data.Length);
|
||||||
|
|
|
@ -254,6 +254,27 @@ namespace OpenSim.Services.Connectors
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual bool[] AssetsExist(string[] ids)
|
||||||
|
{
|
||||||
|
string uri = m_ServerURI + "/get_assets_exist";
|
||||||
|
|
||||||
|
bool[] exist = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
exist = SynchronousRestObjectRequester.MakeRequest<string[], bool[]>("POST", uri, ids);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// This is most likely to happen because the server doesn't support this function,
|
||||||
|
// so just silently return "doesn't exist" for all the assets.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exist == null)
|
||||||
|
exist = new bool[ids.Length];
|
||||||
|
|
||||||
|
return exist;
|
||||||
|
}
|
||||||
|
|
||||||
public string Store(AssetBase asset)
|
public string Store(AssetBase asset)
|
||||||
{
|
{
|
||||||
if (asset.Local)
|
if (asset.Local)
|
||||||
|
|
|
@ -36,6 +36,7 @@ using OpenSim.Framework;
|
||||||
using OpenSim.Services.Interfaces;
|
using OpenSim.Services.Interfaces;
|
||||||
using OpenSim.Services.Connectors.Hypergrid;
|
using OpenSim.Services.Connectors.Hypergrid;
|
||||||
using OpenSim.Services.Connectors.SimianGrid;
|
using OpenSim.Services.Connectors.SimianGrid;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Services.Connectors
|
namespace OpenSim.Services.Connectors
|
||||||
{
|
{
|
||||||
|
@ -83,39 +84,6 @@ namespace OpenSim.Services.Connectors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool StringToUrlAndAssetID(string id, out string url, out string assetID)
|
|
||||||
{
|
|
||||||
url = String.Empty;
|
|
||||||
assetID = String.Empty;
|
|
||||||
|
|
||||||
Uri assetUri;
|
|
||||||
|
|
||||||
if (Uri.TryCreate(id, UriKind.Absolute, out assetUri) &&
|
|
||||||
assetUri.Scheme == Uri.UriSchemeHttp)
|
|
||||||
{
|
|
||||||
// Simian
|
|
||||||
if (assetUri.Query != string.Empty)
|
|
||||||
{
|
|
||||||
NameValueCollection qscoll = HttpUtility.ParseQueryString(assetUri.Query);
|
|
||||||
assetID = qscoll["id"];
|
|
||||||
if (assetID != null)
|
|
||||||
url = id.Replace(assetID, ""); // Malformed again, as simian expects
|
|
||||||
else
|
|
||||||
url = id; // !!! best effort
|
|
||||||
}
|
|
||||||
else // robust
|
|
||||||
{
|
|
||||||
url = "http://" + assetUri.Authority;
|
|
||||||
assetID = assetUri.LocalPath.Trim(new char[] { '/' });
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.DebugFormat("[HG ASSET SERVICE]: Malformed URL {0}", id);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IAssetService GetConnector(string url)
|
private IAssetService GetConnector(string url)
|
||||||
{
|
{
|
||||||
IAssetService connector = null;
|
IAssetService connector = null;
|
||||||
|
@ -149,7 +117,7 @@ namespace OpenSim.Services.Connectors
|
||||||
string url = string.Empty;
|
string url = string.Empty;
|
||||||
string assetID = string.Empty;
|
string assetID = string.Empty;
|
||||||
|
|
||||||
if (StringToUrlAndAssetID(id, out url, out assetID))
|
if (Util.ParseForeignAssetID(id, out url, out assetID))
|
||||||
{
|
{
|
||||||
IAssetService connector = GetConnector(url);
|
IAssetService connector = GetConnector(url);
|
||||||
return connector.Get(assetID);
|
return connector.Get(assetID);
|
||||||
|
@ -163,7 +131,7 @@ namespace OpenSim.Services.Connectors
|
||||||
string url = string.Empty;
|
string url = string.Empty;
|
||||||
string assetID = string.Empty;
|
string assetID = string.Empty;
|
||||||
|
|
||||||
if (StringToUrlAndAssetID(id, out url, out assetID))
|
if (Util.ParseForeignAssetID(id, out url, out assetID))
|
||||||
{
|
{
|
||||||
IAssetService connector = GetConnector(url);
|
IAssetService connector = GetConnector(url);
|
||||||
return connector.GetCached(assetID);
|
return connector.GetCached(assetID);
|
||||||
|
@ -177,7 +145,7 @@ namespace OpenSim.Services.Connectors
|
||||||
string url = string.Empty;
|
string url = string.Empty;
|
||||||
string assetID = string.Empty;
|
string assetID = string.Empty;
|
||||||
|
|
||||||
if (StringToUrlAndAssetID(id, out url, out assetID))
|
if (Util.ParseForeignAssetID(id, out url, out assetID))
|
||||||
{
|
{
|
||||||
IAssetService connector = GetConnector(url);
|
IAssetService connector = GetConnector(url);
|
||||||
return connector.GetMetadata(assetID);
|
return connector.GetMetadata(assetID);
|
||||||
|
@ -196,7 +164,7 @@ namespace OpenSim.Services.Connectors
|
||||||
string url = string.Empty;
|
string url = string.Empty;
|
||||||
string assetID = string.Empty;
|
string assetID = string.Empty;
|
||||||
|
|
||||||
if (StringToUrlAndAssetID(id, out url, out assetID))
|
if (Util.ParseForeignAssetID(id, out url, out assetID))
|
||||||
{
|
{
|
||||||
IAssetService connector = GetConnector(url);
|
IAssetService connector = GetConnector(url);
|
||||||
return connector.Get(assetID, sender, handler);
|
return connector.Get(assetID, sender, handler);
|
||||||
|
@ -205,12 +173,72 @@ namespace OpenSim.Services.Connectors
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private struct AssetAndIndex
|
||||||
|
{
|
||||||
|
public UUID assetID;
|
||||||
|
public int index;
|
||||||
|
|
||||||
|
public AssetAndIndex(UUID assetID, int index)
|
||||||
|
{
|
||||||
|
this.assetID = assetID;
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool[] AssetsExist(string[] ids)
|
||||||
|
{
|
||||||
|
// This method is a bit complicated because it works even if the assets belong to different
|
||||||
|
// servers; that requires sending separate requests to each server.
|
||||||
|
|
||||||
|
// Group the assets by the server they belong to
|
||||||
|
|
||||||
|
var url2assets = new Dictionary<string, List<AssetAndIndex>>();
|
||||||
|
|
||||||
|
for (int i = 0; i < ids.Length; i++)
|
||||||
|
{
|
||||||
|
string url = string.Empty;
|
||||||
|
string assetID = string.Empty;
|
||||||
|
|
||||||
|
if (Util.ParseForeignAssetID(ids[i], out url, out assetID))
|
||||||
|
{
|
||||||
|
if (!url2assets.ContainsKey(url))
|
||||||
|
url2assets.Add(url, new List<AssetAndIndex>());
|
||||||
|
url2assets[url].Add(new AssetAndIndex(UUID.Parse(assetID), i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query each of the servers in turn
|
||||||
|
|
||||||
|
bool[] exist = new bool[ids.Length];
|
||||||
|
|
||||||
|
foreach (string url in url2assets.Keys)
|
||||||
|
{
|
||||||
|
IAssetService connector = GetConnector(url);
|
||||||
|
lock (EndPointLock(connector))
|
||||||
|
{
|
||||||
|
List<AssetAndIndex> curAssets = url2assets[url];
|
||||||
|
string[] assetIDs = curAssets.ConvertAll(a => a.assetID.ToString()).ToArray();
|
||||||
|
bool[] curExist = connector.AssetsExist(assetIDs);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
foreach (AssetAndIndex ai in curAssets)
|
||||||
|
{
|
||||||
|
exist[ai.index] = curExist[i];
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return exist;
|
||||||
|
}
|
||||||
|
|
||||||
public string Store(AssetBase asset)
|
public string Store(AssetBase asset)
|
||||||
{
|
{
|
||||||
string url = string.Empty;
|
string url = string.Empty;
|
||||||
string assetID = string.Empty;
|
string assetID = string.Empty;
|
||||||
|
|
||||||
if (StringToUrlAndAssetID(asset.ID, out url, out assetID))
|
if (Util.ParseForeignAssetID(asset.ID, out url, out assetID))
|
||||||
{
|
{
|
||||||
IAssetService connector = GetConnector(url);
|
IAssetService connector = GetConnector(url);
|
||||||
// Restore the assetID to a simple UUID
|
// Restore the assetID to a simple UUID
|
||||||
|
|
|
@ -231,6 +231,26 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool[] AssetsExist(string[] ids)
|
||||||
|
{
|
||||||
|
if (String.IsNullOrEmpty(m_serverUrl))
|
||||||
|
{
|
||||||
|
m_log.Error("[SIMIAN ASSET CONNECTOR]: No AssetServerURI configured");
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool[] exist = new bool[ids.Length];
|
||||||
|
|
||||||
|
for (int i = 0; i < ids.Length; i++)
|
||||||
|
{
|
||||||
|
AssetMetadata metadata = GetMetadata(ids[i]);
|
||||||
|
if (metadata != null)
|
||||||
|
exist[i] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return exist;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new asset
|
/// Creates a new asset
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -76,6 +76,13 @@ namespace OpenSim.Services.Interfaces
|
||||||
/// <returns>True if the id was parseable, false otherwise</returns>
|
/// <returns>True if the id was parseable, false otherwise</returns>
|
||||||
bool Get(string id, Object sender, AssetRetrieved handler);
|
bool Get(string id, Object sender, AssetRetrieved handler);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if assets exist in the database.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ids">The assets' IDs</param>
|
||||||
|
/// <returns>For each asset: true if it exists, false otherwise</returns>
|
||||||
|
bool[] AssetsExist(string[] ids);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new asset
|
/// Creates a new asset
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
@ -37,7 +38,7 @@ namespace OpenSim.Tests.Common.Mock
|
||||||
|
|
||||||
public AssetBase FetchAsset(UUID uuid)
|
public AssetBase FetchAsset(UUID uuid)
|
||||||
{
|
{
|
||||||
if (ExistsAsset(uuid))
|
if (AssetsExist(new[] { uuid })[0])
|
||||||
return Assets[uuid];
|
return Assets[uuid];
|
||||||
else
|
else
|
||||||
return null;
|
return null;
|
||||||
|
@ -53,9 +54,9 @@ namespace OpenSim.Tests.Common.Mock
|
||||||
CreateAsset(asset);
|
CreateAsset(asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ExistsAsset(UUID uuid)
|
public bool[] AssetsExist(UUID[] uuids)
|
||||||
{
|
{
|
||||||
return Assets.ContainsKey(uuid);
|
return Array.ConvertAll(uuids, id => Assets.ContainsKey(id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue