Root agent retrieval via http/REST. This is a pull, the caller gets the agent. This is not used by the regions yet, but it may be a better alternative to transfer agents even when that is done by the regions. The data is still trivial; soon it will have attachments, scripts and script state. Also, authorization tokens still to come. Serialization using OSD/json, as the other methods.

0.6.5-rc1
diva 2009-03-23 02:37:19 +00:00
parent e1ea3f05aa
commit 5af63a6a5c
6 changed files with 209 additions and 35 deletions

View File

@ -162,6 +162,21 @@ namespace OpenSim.Region.CoreModules.Communications.Local
return false; return false;
} }
public bool SendRetrieveRootAgent(ulong regionHandle, UUID id, out IAgentData agent)
{
agent = null;
foreach (Scene s in m_sceneList)
{
if (s.RegionInfo.RegionHandle == regionHandle)
{
//m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate");
return s.IncomingRetrieveRootAgent(id, out agent);
}
}
//m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate");
return false;
}
public bool SendReleaseAgent(ulong regionHandle, UUID id, string uri) public bool SendReleaseAgent(ulong regionHandle, UUID id, string uri)
{ {
//uint x, y; //uint x, y;

View File

@ -193,6 +193,27 @@ namespace OpenSim.Region.CoreModules.Communications.REST
} }
public bool SendRetrieveRootAgent(ulong regionHandle, UUID id, out IAgentData agent)
{
// Try local first
if (m_localBackend.SendRetrieveRootAgent(regionHandle, id, out agent))
return true;
// else do the remote thing
if (!m_localBackend.IsLocalRegion(regionHandle))
{
RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle);
if (regInfo != null)
{
return DoRetrieveRootAgentCall(regInfo, id, out agent);
}
//else
// m_log.Warn("[REST COMMS]: Region not found " + regionHandle);
}
return false;
}
public bool SendReleaseAgent(ulong regionHandle, UUID id, string uri) public bool SendReleaseAgent(ulong regionHandle, UUID id, string uri)
{ {
// Try local first // Try local first
@ -203,6 +224,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
return DoReleaseAgentCall(regionHandle, id, uri); return DoReleaseAgentCall(regionHandle, id, uri);
} }
public bool SendCloseAgent(ulong regionHandle, UUID id) public bool SendCloseAgent(ulong regionHandle, UUID id)
{ {
// Try local first // Try local first
@ -288,12 +310,13 @@ namespace OpenSim.Region.CoreModules.Communications.REST
{ {
// Eventually, we want to use a caps url instead of the agentID // Eventually, we want to use a caps url instead of the agentID
string uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/agent/" + aCircuit.AgentID + "/"; string uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/agent/" + aCircuit.AgentID + "/";
//m_log.Debug(" >>> DoCreateChildAgentCall <<< " + uri); //Console.WriteLine(" >>> DoCreateChildAgentCall <<< " + uri);
WebRequest AgentCreateRequest = WebRequest.Create(uri); HttpWebRequest AgentCreateRequest = (HttpWebRequest)WebRequest.Create(uri);
AgentCreateRequest.Method = "POST"; AgentCreateRequest.Method = "POST";
AgentCreateRequest.ContentType = "application/json"; AgentCreateRequest.ContentType = "application/json";
AgentCreateRequest.Timeout = 10000; AgentCreateRequest.Timeout = 10000;
//AgentCreateRequest.KeepAlive = false;
// Fill it in // Fill it in
OSDMap args = null; OSDMap args = null;
@ -373,18 +396,19 @@ namespace OpenSim.Region.CoreModules.Communications.REST
{ {
// Eventually, we want to use a caps url instead of the agentID // Eventually, we want to use a caps url instead of the agentID
string uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/agent/" + cAgentData.AgentID + "/"; string uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/agent/" + cAgentData.AgentID + "/";
//m_log.Debug(" >>> DoChildAgentUpdateCall <<< " + uri); //Console.WriteLine(" >>> DoChildAgentUpdateCall <<< " + uri);
WebRequest ChildUpdateRequest = WebRequest.Create(uri); HttpWebRequest ChildUpdateRequest = (HttpWebRequest)WebRequest.Create(uri);
ChildUpdateRequest.Method = "PUT"; ChildUpdateRequest.Method = "PUT";
ChildUpdateRequest.ContentType = "application/json"; ChildUpdateRequest.ContentType = "application/json";
ChildUpdateRequest.Timeout = 10000; ChildUpdateRequest.Timeout = 10000;
//ChildUpdateRequest.KeepAlive = false;
// Fill it in // Fill it in
OSDMap args = null; OSDMap args = null;
try try
{ {
args = cAgentData.PackUpdateMessage(); args = cAgentData.Pack();
} }
catch (Exception e) catch (Exception e)
{ {
@ -453,6 +477,61 @@ namespace OpenSim.Region.CoreModules.Communications.REST
return true; return true;
} }
public bool DoRetrieveRootAgentCall(RegionInfo region, UUID id, out IAgentData agent)
{
agent = null;
// Eventually, we want to use a caps url instead of the agentID
string uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/agent/" + id + "/" + region.RegionHandle.ToString() + "/";
//Console.WriteLine(" >>> DoRetrieveRootAgentCall <<< " + uri);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "GET";
request.Timeout = 10000;
//request.Headers.Add("authorization", ""); // coming soon
HttpWebResponse webResponse = null;
string reply = string.Empty;
try
{
webResponse = (HttpWebResponse)request.GetResponse();
if (webResponse == null)
{
m_log.Info("[REST COMMS]: Null reply on agent get ");
}
StreamReader sr = new StreamReader(webResponse.GetResponseStream());
reply = sr.ReadToEnd().Trim();
sr.Close();
//Console.WriteLine("[REST COMMS]: ChilAgentUpdate reply was " + reply);
}
catch (WebException ex)
{
m_log.InfoFormat("[REST COMMS]: exception on reply of agent get {0}", ex.Message);
// ignore, really
return false;
}
if (webResponse.StatusCode == HttpStatusCode.OK)
{
// we know it's jason
OSDMap args = GetOSDMap(reply);
if (args == null)
{
//Console.WriteLine("[REST COMMS]: Error getting OSDMap from reply");
return false;
}
agent = new CompleteAgentData();
agent.Unpack(args);
return true;
}
//Console.WriteLine("[REST COMMS]: DoRetrieveRootAgentCall returned status " + webResponse.StatusCode);
return false;
}
public bool DoReleaseAgentCall(ulong regionHandle, UUID id, string uri) public bool DoReleaseAgentCall(ulong regionHandle, UUID id, string uri)
{ {
//m_log.Debug(" >>> DoReleaseAgentCall <<< " + uri); //m_log.Debug(" >>> DoReleaseAgentCall <<< " + uri);
@ -466,7 +545,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
WebResponse webResponse = request.GetResponse(); WebResponse webResponse = request.GetResponse();
if (webResponse == null) if (webResponse == null)
{ {
m_log.Info("[REST COMMS]: Null reply on agent get "); m_log.Info("[REST COMMS]: Null reply on agent delete ");
} }
StreamReader sr = new StreamReader(webResponse.GetResponseStream()); StreamReader sr = new StreamReader(webResponse.GetResponseStream());
@ -478,18 +557,19 @@ namespace OpenSim.Region.CoreModules.Communications.REST
} }
catch (WebException ex) catch (WebException ex)
{ {
m_log.InfoFormat("[REST COMMS]: exception on reply of agent get {0}", ex.Message); m_log.InfoFormat("[REST COMMS]: exception on reply of agent delete {0}", ex.Message);
// ignore, really // ignore, really
} }
return true; return true;
} }
public bool DoCloseAgentCall(RegionInfo region, UUID id) public bool DoCloseAgentCall(RegionInfo region, UUID id)
{ {
string uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/agent/" + id + "/" + region.RegionHandle.ToString() +"/"; string uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/agent/" + id + "/" + region.RegionHandle.ToString() +"/";
//m_log.Debug(" >>> DoCloseAgentCall <<< " + uri); //Console.WriteLine(" >>> DoCloseAgentCall <<< " + uri);
WebRequest request = WebRequest.Create(uri); WebRequest request = WebRequest.Create(uri);
request.Method = "DELETE"; request.Method = "DELETE";
@ -500,7 +580,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
WebResponse webResponse = request.GetResponse(); WebResponse webResponse = request.GetResponse();
if (webResponse == null) if (webResponse == null)
{ {
m_log.Info("[REST COMMS]: Null reply on agent get "); m_log.Info("[REST COMMS]: Null reply on agent delete ");
} }
StreamReader sr = new StreamReader(webResponse.GetResponseStream()); StreamReader sr = new StreamReader(webResponse.GetResponseStream());
@ -512,7 +592,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
} }
catch (WebException ex) catch (WebException ex)
{ {
m_log.InfoFormat("[REST COMMS]: exception on reply of agent get {0}", ex.Message); m_log.InfoFormat("[REST COMMS]: exception on reply of agent delete {0}", ex.Message);
// ignore, really // ignore, really
} }
@ -696,14 +776,15 @@ namespace OpenSim.Region.CoreModules.Communications.REST
{ {
//m_log.Debug("[CONNECTION DEBUGGING]: AgentHandler Called"); //m_log.Debug("[CONNECTION DEBUGGING]: AgentHandler Called");
//m_log.Debug("---------------------------"); m_log.Debug("---------------------------");
//m_log.Debug(" >> uri=" + request["uri"]); m_log.Debug(" >> uri=" + request["uri"]);
//m_log.Debug(" >> content-type=" + request["content-type"]); m_log.Debug(" >> content-type=" + request["content-type"]);
//m_log.Debug(" >> http-method=" + request["http-method"]); m_log.Debug(" >> http-method=" + request["http-method"]);
//m_log.Debug("---------------------------\n"); m_log.Debug("---------------------------\n");
Hashtable responsedata = new Hashtable(); Hashtable responsedata = new Hashtable();
responsedata["content_type"] = "text/html"; responsedata["content_type"] = "text/html";
responsedata["keepalive"] = false;
UUID agentID; UUID agentID;
string action; string action;
@ -729,10 +810,14 @@ namespace OpenSim.Region.CoreModules.Communications.REST
DoAgentPost(request, responsedata, agentID); DoAgentPost(request, responsedata, agentID);
return responsedata; return responsedata;
} }
else if (method.Equals("GET"))
{
DoAgentGet(request, responsedata, agentID, regionHandle);
return responsedata;
}
else if (method.Equals("DELETE")) else if (method.Equals("DELETE"))
{ {
DoAgentDelete(request, responsedata, agentID, action, regionHandle); DoAgentDelete(request, responsedata, agentID, action, regionHandle);
return responsedata; return responsedata;
} }
else else
@ -748,7 +833,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
protected virtual void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id) protected virtual void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id)
{ {
OSDMap args = GetOSDMap(request); OSDMap args = GetOSDMap((string)request["body"]);
if (args == null) if (args == null)
{ {
responsedata["int_response_code"] = 400; responsedata["int_response_code"] = 400;
@ -782,7 +867,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
protected virtual void DoAgentPut(Hashtable request, Hashtable responsedata) protected virtual void DoAgentPut(Hashtable request, Hashtable responsedata)
{ {
OSDMap args = GetOSDMap(request); OSDMap args = GetOSDMap((string)request["body"]);
if (args == null) if (args == null)
{ {
responsedata["int_response_code"] = 400; responsedata["int_response_code"] = 400;
@ -810,13 +895,14 @@ namespace OpenSim.Region.CoreModules.Communications.REST
AgentData agent = new AgentData(); AgentData agent = new AgentData();
try try
{ {
agent.UnpackUpdateMessage(args); agent.Unpack(args);
} }
catch (Exception ex) catch (Exception ex)
{ {
m_log.InfoFormat("[REST COMMS]: exception on unpacking ChildAgentUpdate message {0}", ex.Message); m_log.InfoFormat("[REST COMMS]: exception on unpacking ChildAgentUpdate message {0}", ex.Message);
return; return;
} }
//agent.Dump(); //agent.Dump();
// This is one of the meanings of PUT agent // This is one of the meanings of PUT agent
result = m_localBackend.SendChildAgentUpdate(regionhandle, agent); result = m_localBackend.SendChildAgentUpdate(regionhandle, agent);
@ -827,7 +913,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
AgentPosition agent = new AgentPosition(); AgentPosition agent = new AgentPosition();
try try
{ {
agent.UnpackUpdateMessage(args); agent.Unpack(args);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -840,12 +926,48 @@ namespace OpenSim.Region.CoreModules.Communications.REST
} }
responsedata["int_response_code"] = 200; responsedata["int_response_code"] = 200;
responsedata["str_response_string"] = result.ToString(); responsedata["str_response_string"] = result.ToString();
} }
protected virtual void DoAgentGet(Hashtable request, Hashtable responsedata, UUID id, ulong regionHandle)
{
IAgentData agent = null;
bool result = m_localBackend.SendRetrieveRootAgent(regionHandle, id, out agent);
OSDMap map = null;
if (result)
{
if (agent != null) // just to make sure
{
map = agent.Pack();
string strBuffer = "";
try
{
strBuffer = OSDParser.SerializeJsonString(map);
}
catch (Exception e)
{
m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of CreateObject: {0}", e.Message);
// ignore. buffer will be empty, caller should check.
}
responsedata["content_type"] = "application/json";
responsedata["int_response_code"] = 200;
responsedata["str_response_string"] = strBuffer;
}
else
{
responsedata["int_response_code"] = 500;
responsedata["str_response_string"] = "Internal error";
}
}
else
{
responsedata["int_response_code"] = 404;
responsedata["str_response_string"] = "Not Found";
}
}
protected virtual void DoAgentDelete(Hashtable request, Hashtable responsedata, UUID id, string action, ulong regionHandle) protected virtual void DoAgentDelete(Hashtable request, Hashtable responsedata, UUID id, string action, ulong regionHandle)
{ {
//m_log.Debug(" >>> DoDelete action:" + action + "; regionHandle:" + regionHandle); //m_log.Debug(" >>> DoDelete action:" + action + "; regionHandle:" + regionHandle);
@ -857,6 +979,8 @@ namespace OpenSim.Region.CoreModules.Communications.REST
responsedata["int_response_code"] = 200; responsedata["int_response_code"] = 200;
responsedata["str_response_string"] = "OpenSim agent " + id.ToString(); responsedata["str_response_string"] = "OpenSim agent " + id.ToString();
m_log.Debug("[REST COMMS]: Agent Deleted.");
} }
/** /**
@ -918,7 +1042,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
protected virtual void DoObjectPost(Hashtable request, Hashtable responsedata, ulong regionhandle) protected virtual void DoObjectPost(Hashtable request, Hashtable responsedata, ulong regionhandle)
{ {
OSDMap args = GetOSDMap(request); OSDMap args = GetOSDMap((string)request["body"]);
if (args == null) if (args == null)
{ {
responsedata["int_response_code"] = 400; responsedata["int_response_code"] = 400;
@ -1030,7 +1154,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
protected virtual void DoRegionPost(Hashtable request, Hashtable responsedata, UUID id) protected virtual void DoRegionPost(Hashtable request, Hashtable responsedata, UUID id)
{ {
OSDMap args = GetOSDMap(request); OSDMap args = GetOSDMap((string)request["body"]);
if (args == null) if (args == null)
{ {
responsedata["int_response_code"] = 400; responsedata["int_response_code"] = 400;
@ -1066,14 +1190,14 @@ namespace OpenSim.Region.CoreModules.Communications.REST
#region Misc #region Misc
public static OSDMap GetOSDMap(Hashtable request) public static OSDMap GetOSDMap(string data)
{ {
OSDMap args = null; OSDMap args = null;
try try
{ {
OSD buffer; OSD buffer;
// We should pay attention to the content-type, but let's assume we know it's Json // We should pay attention to the content-type, but let's assume we know it's Json
buffer = OSDParser.DeserializeJson((string)request["body"]); buffer = OSDParser.DeserializeJson(data);
if (buffer.Type == OSDType.Map) if (buffer.Type == OSDType.Map)
{ {
args = (OSDMap)buffer; args = (OSDMap)buffer;
@ -1082,13 +1206,13 @@ namespace OpenSim.Region.CoreModules.Communications.REST
else else
{ {
// uh? // uh?
m_log.Debug("[REST COMMS]: Got OSD of type " + buffer.Type.ToString()); Console.WriteLine("[REST COMMS]: Got OSD of type " + buffer.Type.ToString());
return null; return null;
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
m_log.InfoFormat("[REST COMMS]: exception on parse of REST message {0}", ex.Message); Console.WriteLine("[REST COMMS]: exception on parse of REST message " + ex.Message);
return null; return null;
} }
} }

View File

@ -56,6 +56,8 @@ namespace OpenSim.Region.Framework.Interfaces
/// <returns></returns> /// <returns></returns>
bool SendChildAgentUpdate(ulong regionHandle, AgentPosition data); bool SendChildAgentUpdate(ulong regionHandle, AgentPosition data);
bool SendRetrieveRootAgent(ulong regionHandle, UUID id, out IAgentData agent);
/// <summary> /// <summary>
/// Message from receiving region to departing region, telling it got contacted by the client. /// Message from receiving region to departing region, telling it got contacted by the client.
/// When sent over REST, it invokes the opaque uri. /// When sent over REST, it invokes the opaque uri.

View File

@ -40,8 +40,8 @@ namespace OpenSim.Region.Framework.Scenes
{ {
UUID AgentID { get; set; } UUID AgentID { get; set; }
OSDMap PackUpdateMessage(); OSDMap Pack();
void UnpackUpdateMessage(OSDMap map); void Unpack(OSDMap map);
} }
/// <summary> /// <summary>
@ -74,7 +74,7 @@ namespace OpenSim.Region.Framework.Scenes
public byte[] Throttles; public byte[] Throttles;
public OSDMap PackUpdateMessage() public OSDMap Pack()
{ {
OSDMap args = new OSDMap(); OSDMap args = new OSDMap();
args["message_type"] = OSD.FromString("AgentPosition"); args["message_type"] = OSD.FromString("AgentPosition");
@ -101,7 +101,7 @@ namespace OpenSim.Region.Framework.Scenes
return args; return args;
} }
public void UnpackUpdateMessage(OSDMap args) public void Unpack(OSDMap args)
{ {
if (args.ContainsKey("region_handle")) if (args.ContainsKey("region_handle"))
UInt64.TryParse(args["region_handle"].AsString(), out RegionHandle); UInt64.TryParse(args["region_handle"].AsString(), out RegionHandle);
@ -257,7 +257,7 @@ namespace OpenSim.Region.Framework.Scenes
public string CallbackURI; public string CallbackURI;
public OSDMap PackUpdateMessage() public virtual OSDMap Pack()
{ {
OSDMap args = new OSDMap(); OSDMap args = new OSDMap();
args["message_type"] = OSD.FromString("AgentData"); args["message_type"] = OSD.FromString("AgentData");
@ -346,7 +346,7 @@ namespace OpenSim.Region.Framework.Scenes
/// Avoiding reflection makes it painful to write, but that's the price! /// Avoiding reflection makes it painful to write, but that's the price!
/// </summary> /// </summary>
/// <param name="hash"></param> /// <param name="hash"></param>
public void UnpackUpdateMessage(OSDMap args) public virtual void Unpack(OSDMap args)
{ {
if (args.ContainsKey("region_handle")) if (args.ContainsKey("region_handle"))
UInt64.TryParse(args["region_handle"].AsString(), out RegionHandle); UInt64.TryParse(args["region_handle"].AsString(), out RegionHandle);
@ -497,4 +497,17 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public class CompleteAgentData : AgentData
{
public override OSDMap Pack()
{
return base.Pack();
}
public override void Unpack(OSDMap map)
{
base.Unpack(map);
}
}
} }

View File

@ -2549,6 +2549,19 @@ namespace OpenSim.Region.Framework.Scenes
} }
public virtual bool IncomingRetrieveRootAgent(UUID id, out IAgentData agent)
{
agent = null;
ScenePresence sp = GetScenePresence(id);
if ((sp != null) && (!sp.IsChildAgent))
{
sp.IsChildAgent = true;
return sp.CopyAgent(out agent);
}
return false;
}
public virtual bool IncomingReleaseAgent(UUID id) public virtual bool IncomingReleaseAgent(UUID id)
{ {
return m_sceneGridService.ReleaseAgent(id); return m_sceneGridService.ReleaseAgent(id);

View File

@ -2879,6 +2879,13 @@ namespace OpenSim.Region.Framework.Scenes
} }
public bool CopyAgent(out IAgentData agent)
{
agent = new CompleteAgentData();
CopyTo((AgentData)agent);
return true;
}
#endregion Child Agent Updates #endregion Child Agent Updates
/// <summary> /// <summary>