From 2c685bff1493451849580cfb6bf44b88322bf0a4 Mon Sep 17 00:00:00 2001 From: diva Date: Mon, 9 Feb 2009 22:27:27 +0000 Subject: Moved prim crossing out of OGS1 and into RESTComms and LocalInterregionComms. This breaks interregion comms with older versions in what concerns prim crossing. In the process of moving the comms, a few things seem to be working better, namely this may address mantis #3011, mantis #1698. Hopefully, this doesn't break anything else. But I'm still seeing weirdnesses with attchments jumping out of place after a cross/TP. The two most notable changes in the crossing process were: * Object gets passed in only one message, not two as done before. * Local object crossings do not get serialized, as done before. --- .../Communications/REST/RESTInterregionComms.cs | 244 ++++++++++++++++++++- 1 file changed, 235 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region/Environment/Modules/Communications/REST/RESTInterregionComms.cs') diff --git a/OpenSim/Region/Environment/Modules/Communications/REST/RESTInterregionComms.cs b/OpenSim/Region/Environment/Modules/Communications/REST/RESTInterregionComms.cs index cfcd618..95b95ee 100644 --- a/OpenSim/Region/Environment/Modules/Communications/REST/RESTInterregionComms.cs +++ b/OpenSim/Region/Environment/Modules/Communications/REST/RESTInterregionComms.cs @@ -123,12 +123,17 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST protected virtual void AddHTTPHandlers() { m_aScene.CommsManager.HttpServer.AddHTTPHandler("/agent/", AgentHandler); + m_aScene.CommsManager.HttpServer.AddHTTPHandler("/object/", ObjectHandler); } #endregion /* IRegionModule */ #region IInterregionComms + /** + * Agent-related communications + */ + public bool SendCreateChildAgent(ulong regionHandle, AgentCircuitData aCircuit) { // Try local first @@ -209,7 +214,32 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST //else // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); return false; - } + } + + /** + * Object-related communications + */ + + public bool SendCreateObject(ulong regionHandle, ISceneObject sog) + { + // Try local first + ISceneObject sogClone = sog.CloneForNewScene(); + if (m_localBackend.SendCreateObject(regionHandle, sogClone)) + { + //m_log.Debug("[REST COMMS]: LocalBackEnd SendCreateObject succeeded"); + return true; + } + + // else do the remote thing + RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle); + if (regInfo != null) + { + return DoCreateObjectCall(regInfo, sog); + } + //else + // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); + return false; + } #endregion /* IInterregionComms */ @@ -454,10 +484,95 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST return true; } + protected bool DoCreateObjectCall(RegionInfo region, ISceneObject sog) + { + ulong regionHandle = GetRegionHandle(region.RegionHandle); + string uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/object/" + sog.UUID + "/" + regionHandle.ToString() + "/"; + //Console.WriteLine(" >>> DoCreateChildAgentCall <<< " + uri); + + WebRequest ObjectCreateRequest = WebRequest.Create(uri); + ObjectCreateRequest.Method = "POST"; + ObjectCreateRequest.ContentType = "text/xml"; + ObjectCreateRequest.Timeout = 10000; + + OSDMap args = new OSDMap(2); + args["sog"] = OSD.FromString(sog.ToXmlString2()); + args["extra"] = OSD.FromString(sog.ExtraToXmlString()); + if (m_aScene.m_allowScriptCrossings) + { + string state = sog.GetStateSnapshot(); + if (state.Length > 0) + args["state"] = OSD.FromString(state); + } + + string strBuffer = ""; + byte[] buffer = new byte[1]; + try + { + strBuffer = OSDParser.SerializeJsonString(args); + System.Text.UTF8Encoding str = new System.Text.UTF8Encoding(); + buffer = str.GetBytes(strBuffer); + + } + 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. + } + + Stream os = null; + try + { // send the Post + ObjectCreateRequest.ContentLength = buffer.Length; //Count bytes to send + os = ObjectCreateRequest.GetRequestStream(); + os.Write(buffer, 0, strBuffer.Length); //Send it + os.Close(); + m_log.InfoFormat("[REST COMMS]: Posted ChildAgentUpdate request to remote sim {0}", uri); + } + //catch (WebException ex) + catch + { + // m_log.InfoFormat("[REST COMMS]: Bad send on CreateObject {0}", ex.Message); + + return false; + } + + // Let's wait for the response + //m_log.Info("[REST COMMS]: Waiting for a reply after DoCreateChildAgentCall"); + + try + { + WebResponse webResponse = ObjectCreateRequest.GetResponse(); + if (webResponse == null) + { + m_log.Info("[REST COMMS]: Null reply on DoCreateObjectCall post"); + } + + StreamReader sr = new StreamReader(webResponse.GetResponseStream()); + //reply = sr.ReadToEnd().Trim(); + sr.ReadToEnd().Trim(); + sr.Close(); + //m_log.InfoFormat("[REST COMMS]: DoCreateChildAgentCall reply was {0} ", reply); + + } + catch (WebException ex) + { + m_log.InfoFormat("[REST COMMS]: exception on reply of DoCreateObjectCall {0}", ex.Message); + // ignore, really + } + + return true; + + } + #endregion /* Do Work */ #region Incoming calls from remote instances + /** + * Agent-related incoming calls + */ + public Hashtable AgentHandler(Hashtable request) { //m_log.Debug("[CONNECTION DEBUGGING]: AgentHandler Called"); @@ -487,17 +602,17 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST string method = (string)request["http-method"]; if (method.Equals("PUT")) { - DoPut(request, responsedata); + DoAgentPut(request, responsedata); return responsedata; } else if (method.Equals("POST")) { - DoPost(request, responsedata, agentID); + DoAgentPost(request, responsedata, agentID); return responsedata; } else if (method.Equals("DELETE")) { - DoDelete(request, responsedata, agentID, action, regionHandle); + DoAgentDelete(request, responsedata, agentID, action, regionHandle); return responsedata; } @@ -534,12 +649,12 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST } catch (Exception ex) { - m_log.InfoFormat("[REST COMMS]: exception on parse of ChildAgentUpdate message {0}", ex.Message); + m_log.InfoFormat("[REST COMMS]: exception on parse of REST message {0}", ex.Message); return null; } } - protected virtual void DoPost(Hashtable request, Hashtable responsedata, UUID id) + protected virtual void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id) { OSDMap args = GetOSDMap(request); if (args == null) @@ -573,7 +688,7 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST responsedata["str_response_string"] = result.ToString(); } - protected virtual void DoPut(Hashtable request, Hashtable responsedata) + protected virtual void DoAgentPut(Hashtable request, Hashtable responsedata) { OSDMap args = GetOSDMap(request); if (args == null) @@ -639,7 +754,7 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST responsedata["str_response_string"] = result.ToString(); } - protected virtual void DoDelete(Hashtable request, Hashtable responsedata, UUID id, string action, ulong regionHandle) + protected virtual void DoAgentDelete(Hashtable request, Hashtable responsedata, UUID id, string action, ulong regionHandle) { //Console.WriteLine(" >>> DoDelete action:" + action + "; regionHandle:" + regionHandle); @@ -651,7 +766,118 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST responsedata["int_response_code"] = 200; responsedata["str_response_string"] = "OpenSim agent " + id.ToString(); } - + + /** + * Object-related incoming calls + */ + + public Hashtable ObjectHandler(Hashtable request) + { + //m_log.Debug("[CONNECTION DEBUGGING]: ObjectHandler Called"); + + //Console.WriteLine("---------------------------"); + //Console.WriteLine(" >> uri=" + request["uri"]); + //Console.WriteLine(" >> content-type=" + request["content-type"]); + //Console.WriteLine(" >> http-method=" + request["http-method"]); + //Console.WriteLine("---------------------------\n"); + + Hashtable responsedata = new Hashtable(); + responsedata["content_type"] = "text/html"; + + UUID objectID; + string action; + ulong regionHandle; + if (!GetParams((string)request["uri"], out objectID, out regionHandle, out action)) + { + m_log.InfoFormat("[REST COMMS]: Invalid parameters for object message {0}", request["uri"]); + responsedata["int_response_code"] = 404; + responsedata["str_response_string"] = "false"; + + return responsedata; + } + + // Next, let's parse the verb + string method = (string)request["http-method"]; + if (method.Equals("POST")) + { + DoObjectPost(request, responsedata, regionHandle); + return responsedata; + } + //else if (method.Equals("PUT")) + //{ + // DoObjectPut(request, responsedata, agentID); + // return responsedata; + //} + //else if (method.Equals("DELETE")) + //{ + // DoObjectDelete(request, responsedata, agentID, action, regionHandle); + // return responsedata; + //} + else + { + m_log.InfoFormat("[REST COMMS]: method {0} not supported in object message", method); + responsedata["int_response_code"] = 404; + responsedata["str_response_string"] = "false"; + + return responsedata; + } + + } + + protected virtual void DoObjectPost(Hashtable request, Hashtable responsedata, ulong regionhandle) + { + OSDMap args = GetOSDMap(request); + if (args == null) + { + responsedata["int_response_code"] = 400; + responsedata["str_response_string"] = "false"; + return; + } + + string sogXmlStr = "", extraStr = "", stateXmlStr = ""; + if (args["sog"] != null) + sogXmlStr = args["sog"].AsString(); + if (args["extra"] != null) + extraStr = args["extra"].AsString(); + + UUID regionID = m_localBackend.GetRegionID(regionhandle); + SceneObjectGroup sog = null; + try + { + sog = new SceneObjectGroup(sogXmlStr); + sog.ExtraFromXmlString(extraStr); + } + catch (Exception ex) + { + m_log.InfoFormat("[REST COMMS]: exception on deserializing scene object {0}", ex.Message); + responsedata["int_response_code"] = 400; + responsedata["str_response_string"] = "false"; + return; + } + + if ((args["state"] != null) && m_aScene.m_allowScriptCrossings) + { + stateXmlStr = args["state"].AsString(); + if (stateXmlStr != "") + { + try + { + sog.SetState(stateXmlStr, regionID); + } + catch (Exception ex) + { + m_log.InfoFormat("[REST COMMS]: exception on setting state for scene object {0}", ex.Message); + + } + } + } + // This is the meaning of POST object + bool result = m_localBackend.SendCreateObject(regionhandle, sog); + + responsedata["int_response_code"] = 200; + responsedata["str_response_string"] = result.ToString(); + } + #endregion #region Misc -- cgit v1.1