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;
}
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)
{
//uint x, y;

View File

@ -192,7 +192,28 @@ namespace OpenSim.Region.CoreModules.Communications.REST
return false;
}
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)
{
// Try local first
@ -203,6 +224,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
return DoReleaseAgentCall(regionHandle, id, uri);
}
public bool SendCloseAgent(ulong regionHandle, UUID id)
{
// 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
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.ContentType = "application/json";
AgentCreateRequest.Timeout = 10000;
//AgentCreateRequest.KeepAlive = false;
// Fill it in
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
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.ContentType = "application/json";
ChildUpdateRequest.Timeout = 10000;
//ChildUpdateRequest.KeepAlive = false;
// Fill it in
OSDMap args = null;
try
{
args = cAgentData.PackUpdateMessage();
args = cAgentData.Pack();
}
catch (Exception e)
{
@ -453,6 +477,61 @@ namespace OpenSim.Region.CoreModules.Communications.REST
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)
{
//m_log.Debug(" >>> DoReleaseAgentCall <<< " + uri);
@ -466,7 +545,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
WebResponse webResponse = request.GetResponse();
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());
@ -478,18 +557,19 @@ namespace OpenSim.Region.CoreModules.Communications.REST
}
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
}
return true;
}
public bool DoCloseAgentCall(RegionInfo region, UUID id)
{
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);
request.Method = "DELETE";
@ -500,7 +580,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
WebResponse webResponse = request.GetResponse();
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());
@ -512,7 +592,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
}
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
}
@ -696,14 +776,15 @@ namespace OpenSim.Region.CoreModules.Communications.REST
{
//m_log.Debug("[CONNECTION DEBUGGING]: AgentHandler Called");
//m_log.Debug("---------------------------");
//m_log.Debug(" >> uri=" + request["uri"]);
//m_log.Debug(" >> content-type=" + request["content-type"]);
//m_log.Debug(" >> http-method=" + request["http-method"]);
//m_log.Debug("---------------------------\n");
m_log.Debug("---------------------------");
m_log.Debug(" >> uri=" + request["uri"]);
m_log.Debug(" >> content-type=" + request["content-type"]);
m_log.Debug(" >> http-method=" + request["http-method"]);
m_log.Debug("---------------------------\n");
Hashtable responsedata = new Hashtable();
responsedata["content_type"] = "text/html";
responsedata["keepalive"] = false;
UUID agentID;
string action;
@ -729,10 +810,14 @@ namespace OpenSim.Region.CoreModules.Communications.REST
DoAgentPost(request, responsedata, agentID);
return responsedata;
}
else if (method.Equals("GET"))
{
DoAgentGet(request, responsedata, agentID, regionHandle);
return responsedata;
}
else if (method.Equals("DELETE"))
{
DoAgentDelete(request, responsedata, agentID, action, regionHandle);
return responsedata;
}
else
@ -748,7 +833,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
protected virtual void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id)
{
OSDMap args = GetOSDMap(request);
OSDMap args = GetOSDMap((string)request["body"]);
if (args == null)
{
responsedata["int_response_code"] = 400;
@ -782,7 +867,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
protected virtual void DoAgentPut(Hashtable request, Hashtable responsedata)
{
OSDMap args = GetOSDMap(request);
OSDMap args = GetOSDMap((string)request["body"]);
if (args == null)
{
responsedata["int_response_code"] = 400;
@ -810,13 +895,14 @@ namespace OpenSim.Region.CoreModules.Communications.REST
AgentData agent = new AgentData();
try
{
agent.UnpackUpdateMessage(args);
agent.Unpack(args);
}
catch (Exception ex)
{
m_log.InfoFormat("[REST COMMS]: exception on unpacking ChildAgentUpdate message {0}", ex.Message);
return;
}
//agent.Dump();
// This is one of the meanings of PUT agent
result = m_localBackend.SendChildAgentUpdate(regionhandle, agent);
@ -827,7 +913,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
AgentPosition agent = new AgentPosition();
try
{
agent.UnpackUpdateMessage(args);
agent.Unpack(args);
}
catch (Exception ex)
{
@ -840,12 +926,48 @@ namespace OpenSim.Region.CoreModules.Communications.REST
}
responsedata["int_response_code"] = 200;
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)
{
//m_log.Debug(" >>> DoDelete action:" + action + "; regionHandle:" + regionHandle);
@ -857,6 +979,8 @@ namespace OpenSim.Region.CoreModules.Communications.REST
responsedata["int_response_code"] = 200;
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)
{
OSDMap args = GetOSDMap(request);
OSDMap args = GetOSDMap((string)request["body"]);
if (args == null)
{
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)
{
OSDMap args = GetOSDMap(request);
OSDMap args = GetOSDMap((string)request["body"]);
if (args == null)
{
responsedata["int_response_code"] = 400;
@ -1066,14 +1190,14 @@ namespace OpenSim.Region.CoreModules.Communications.REST
#region Misc
public static OSDMap GetOSDMap(Hashtable request)
public static OSDMap GetOSDMap(string data)
{
OSDMap args = null;
try
{
OSD buffer;
// 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)
{
args = (OSDMap)buffer;
@ -1082,13 +1206,13 @@ namespace OpenSim.Region.CoreModules.Communications.REST
else
{
// 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;
}
}
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;
}
}

View File

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

View File

@ -40,8 +40,8 @@ namespace OpenSim.Region.Framework.Scenes
{
UUID AgentID { get; set; }
OSDMap PackUpdateMessage();
void UnpackUpdateMessage(OSDMap map);
OSDMap Pack();
void Unpack(OSDMap map);
}
/// <summary>
@ -74,7 +74,7 @@ namespace OpenSim.Region.Framework.Scenes
public byte[] Throttles;
public OSDMap PackUpdateMessage()
public OSDMap Pack()
{
OSDMap args = new OSDMap();
args["message_type"] = OSD.FromString("AgentPosition");
@ -101,7 +101,7 @@ namespace OpenSim.Region.Framework.Scenes
return args;
}
public void UnpackUpdateMessage(OSDMap args)
public void Unpack(OSDMap args)
{
if (args.ContainsKey("region_handle"))
UInt64.TryParse(args["region_handle"].AsString(), out RegionHandle);
@ -257,7 +257,7 @@ namespace OpenSim.Region.Framework.Scenes
public string CallbackURI;
public OSDMap PackUpdateMessage()
public virtual OSDMap Pack()
{
OSDMap args = new OSDMap();
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!
/// </summary>
/// <param name="hash"></param>
public void UnpackUpdateMessage(OSDMap args)
public virtual void Unpack(OSDMap args)
{
if (args.ContainsKey("region_handle"))
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)
{
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
/// <summary>