From 217ffee8cb50e0a7ddfc0d4c4e4bb6a68de909d8 Mon Sep 17 00:00:00 2001
From: diva
Date: Sat, 14 Feb 2009 16:37:55 +0000
Subject: Moved RegionUp to REST/LocalComms. The original functionality has
been entirely maintained, although it will have to be revisited soon, because
it's buggy.
---
OpenSim/Framework/RegionInfo.cs | 69 ++++++
.../Communications/Local/LocalInterregionComms.cs | 17 ++
.../Communications/REST/RESTInterregionComms.cs | 268 ++++++++++++++++++---
.../Framework/Interfaces/IInterregionComms.cs | 23 +-
OpenSim/Region/Framework/Scenes/Scene.cs | 11 +-
.../Framework/Scenes/SceneCommunicationService.cs | 10 +-
6 files changed, 361 insertions(+), 37 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs
index a0e5ba5..84751bd 100644
--- a/OpenSim/Framework/RegionInfo.cs
+++ b/OpenSim/Framework/RegionInfo.cs
@@ -31,6 +31,7 @@ using System.Net.Sockets;
using System.Xml;
using Nini.Config;
using OpenMetaverse;
+using OpenMetaverse.StructuredData;
namespace OpenSim.Framework
{
@@ -605,5 +606,73 @@ namespace OpenSim.Framework
configMember.forceSetConfigurationOption("lastmap_uuid", mapUUID.ToString());
configMember.forceSetConfigurationOption("lastmap_refresh", lastMapRefresh);
}
+
+ public OSDMap PackRegionInfoData()
+ {
+ OSDMap args = new OSDMap();
+ args["region_id"] = OSD.FromUUID(RegionID);
+ if ((RegionName != null) && !RegionName.Equals(""))
+ args["region_name"] = OSD.FromString(RegionName);
+ args["external_host_name"] = OSD.FromString(ExternalHostName);
+ args["http_port"] = OSD.FromString(HttpPort.ToString());
+ args["server_uri"] = OSD.FromString(ServerURI);
+ args["region_xloc"] = OSD.FromString(RegionLocX.ToString());
+ args["region_yloc"] = OSD.FromString(RegionLocY.ToString());
+ args["internal_ep_address"] = OSD.FromString(InternalEndPoint.Address.ToString());
+ args["internal_ep_port"] = OSD.FromString(InternalEndPoint.Port.ToString());
+ if ((RemotingAddress != null) && !RemotingAddress.Equals(""))
+ args["remoting_address"] = OSD.FromString(RemotingAddress);
+ args["remoting_port"] = OSD.FromString(RemotingPort.ToString());
+ args["allow_alt_ports"] = OSD.FromBoolean(m_allow_alternate_ports);
+ if ((proxyUrl != null) && !proxyUrl.Equals(""))
+ args["proxy_url"] = OSD.FromString(proxyUrl);
+
+ return args;
+ }
+
+ public void UnpackRegionInfoData(OSDMap args)
+ {
+ if (args["region_id"] != null)
+ RegionID = args["region_id"].AsUUID();
+ if (args["region_name"] != null)
+ RegionName = args["region_name"].AsString();
+ if (args["external_host_name"] != null)
+ ExternalHostName = args["external_host_name"].AsString();
+ if (args["http_port"] != null)
+ UInt32.TryParse(args["http_port"].AsString(), out m_httpPort);
+ if (args["server_uri"] != null)
+ ServerURI = args["server_uri"].AsString();
+ if (args["region_xloc"] != null)
+ {
+ uint locx;
+ UInt32.TryParse(args["region_xloc"].AsString(), out locx);
+ RegionLocX = locx;
+ }
+ if (args["region_yloc"] != null)
+ {
+ uint locy;
+ UInt32.TryParse(args["region_yloc"].AsString(), out locy);
+ RegionLocY = locy;
+ }
+ IPAddress ip_addr = null;
+ if (args["internal_ep_address"] != null)
+ {
+ IPAddress.TryParse(args["internal_ep_address"].AsString(), out ip_addr);
+ }
+ int port = 0;
+ if (args["internal_ep_port"] != null)
+ {
+ Int32.TryParse(args["internal_ep_port"].AsString(), out port);
+ }
+ InternalEndPoint = new IPEndPoint(ip_addr, port);
+ if (args["remoting_address"] != null)
+ RemotingAddress = args["remoting_address"].AsString();
+ if (args["remoting_port"] != null)
+ UInt32.TryParse(args["remoting_port"].AsString(), out m_remotingPort);
+ if (args["allow_alt_ports"] != null)
+ m_allow_alternate_ports = args["allow_alt_ports"].AsBoolean();
+ if (args["proxy_url"] != null)
+ proxyUrl = args["proxy_url"].AsString();
+ }
}
}
diff --git a/OpenSim/Region/CoreModules/Communications/Local/LocalInterregionComms.cs b/OpenSim/Region/CoreModules/Communications/Local/LocalInterregionComms.cs
index 6e813f4..29bc4f7 100644
--- a/OpenSim/Region/CoreModules/Communications/Local/LocalInterregionComms.cs
+++ b/OpenSim/Region/CoreModules/Communications/Local/LocalInterregionComms.cs
@@ -227,6 +227,23 @@ namespace OpenSim.Region.CoreModules.Communications.Local
return false;
}
+ /**
+ * Region-related communications
+ */
+
+ public bool SendHelloNeighbour(ulong regionHandle, RegionInfo thisRegion)
+ {
+ foreach (Scene s in m_sceneList)
+ {
+ if (s.RegionInfo.RegionHandle == regionHandle)
+ {
+ //m_log.Debug("[LOCAL COMMS]: Found region to SendHelloNeighbour");
+ return s.IncomingHelloNeighbour(thisRegion);
+ }
+ }
+ return false;
+ }
+
#endregion /* IInterregionComms */
#region Misc
diff --git a/OpenSim/Region/CoreModules/Communications/REST/RESTInterregionComms.cs b/OpenSim/Region/CoreModules/Communications/REST/RESTInterregionComms.cs
index fcb3f5b..bc98337 100644
--- a/OpenSim/Region/CoreModules/Communications/REST/RESTInterregionComms.cs
+++ b/OpenSim/Region/CoreModules/Communications/REST/RESTInterregionComms.cs
@@ -45,7 +45,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
{
public class RESTInterregionComms : IRegionModule, IInterregionCommsOut
{
- private bool initialized = false;
+ private static bool initialized = false;
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected bool m_enabled = false;
@@ -78,6 +78,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
return;
InitEach(scene);
+
}
public virtual void PostInitialise()
@@ -115,8 +116,9 @@ namespace OpenSim.Region.CoreModules.Communications.REST
protected virtual void AddHTTPHandlers()
{
- m_aScene.CommsManager.HttpServer.AddHTTPHandler("/agent/", AgentHandler);
+ m_aScene.CommsManager.HttpServer.AddHTTPHandler("/agent/", AgentHandler);
m_aScene.CommsManager.HttpServer.AddHTTPHandler("/object/", ObjectHandler);
+ m_aScene.CommsManager.HttpServer.AddHTTPHandler("/region/", RegionHandler);
}
#endregion /* IRegionModule */
@@ -161,6 +163,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
//else
// m_log.Warn("[REST COMMS]: Region not found " + regionHandle);
return false;
+
}
public bool SendChildAgentUpdate(ulong regionHandle, AgentPosition cAgentData)
@@ -178,6 +181,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
//else
// m_log.Warn("[REST COMMS]: Region not found " + regionHandle);
return false;
+
}
public bool SendReleaseAgent(ulong regionHandle, UUID id, string uri)
@@ -231,6 +235,32 @@ namespace OpenSim.Region.CoreModules.Communications.REST
return false;
}
+ /**
+ * Region-related communications
+ */
+
+ public bool SendHelloNeighbour(ulong regionHandle, RegionInfo thisRegion)
+ {
+ // Try local first
+ if (m_localBackend.SendHelloNeighbour(regionHandle, thisRegion))
+ {
+ //m_log.Debug("[REST COMMS]: LocalBackEnd SendHelloNeighbour succeeded");
+ return true;
+ }
+
+ // else do the remote thing
+ RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle);
+ if ((regInfo != null) &&
+ // Don't remote-call this instance; that's a startup hickup
+ !((regInfo.ExternalHostName == thisRegion.ExternalHostName) && (regInfo.HttpPort == thisRegion.HttpPort)))
+ {
+ return DoHelloNeighbourCall(regInfo, thisRegion);
+ }
+ //else
+ // m_log.Warn("[REST COMMS]: Region not found " + regionHandle);
+ return false;
+ }
+
#endregion /* IInterregionComms */
#region DoWork functions for the above public interface
@@ -482,7 +512,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST
WebRequest ObjectCreateRequest = WebRequest.Create(uri);
ObjectCreateRequest.Method = "POST";
- ObjectCreateRequest.ContentType = "text/xml";
+ ObjectCreateRequest.ContentType = "application/json";
ObjectCreateRequest.Timeout = 10000;
OSDMap args = new OSDMap(2);
@@ -555,6 +585,90 @@ namespace OpenSim.Region.CoreModules.Communications.REST
}
+ protected bool DoHelloNeighbourCall(RegionInfo region, RegionInfo thisRegion)
+ {
+ string uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/region/" + thisRegion.RegionID + "/";
+ //Console.WriteLine(" >>> DoHelloNeighbourCall <<< " + uri);
+
+ WebRequest HelloNeighbourRequest = WebRequest.Create(uri);
+ HelloNeighbourRequest.Method = "POST";
+ HelloNeighbourRequest.ContentType = "application/json";
+ HelloNeighbourRequest.Timeout = 10000;
+
+ // Fill it in
+ OSDMap args = null;
+ try
+ {
+ args = thisRegion.PackRegionInfoData();
+ }
+ catch (Exception e)
+ {
+ m_log.Debug("[REST COMMS]: PackRegionInfoData failed with exception: " + e.Message);
+ }
+ // Add the regionhandle of the destination region
+ ulong regionHandle = GetRegionHandle(region.RegionHandle);
+ args["destination_handle"] = OSD.FromString(regionHandle.ToString());
+
+ string strBuffer = "";
+ byte[] buffer = new byte[1];
+ try
+ {
+ strBuffer = OSDParser.SerializeJsonString(args);
+ UTF8Encoding str = new UTF8Encoding();
+ buffer = str.GetBytes(strBuffer);
+
+ }
+ catch (Exception e)
+ {
+ m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of HelloNeighbour: {0}", e.Message);
+ // ignore. buffer will be empty, caller should check.
+ }
+
+ Stream os = null;
+ try
+ { // send the Post
+ HelloNeighbourRequest.ContentLength = buffer.Length; //Count bytes to send
+ os = HelloNeighbourRequest.GetRequestStream();
+ os.Write(buffer, 0, strBuffer.Length); //Send it
+ os.Close();
+ //m_log.InfoFormat("[REST COMMS]: Posted HelloNeighbour request to remote sim {0}", uri);
+ }
+ //catch (WebException ex)
+ catch
+ {
+ //m_log.InfoFormat("[REST COMMS]: Bad send on HelloNeighbour {0}", ex.Message);
+
+ return false;
+ }
+
+ // Let's wait for the response
+ //m_log.Info("[REST COMMS]: Waiting for a reply after DoHelloNeighbourCall");
+
+ try
+ {
+ WebResponse webResponse = HelloNeighbourRequest.GetResponse();
+ if (webResponse == null)
+ {
+ m_log.Info("[REST COMMS]: Null reply on DoHelloNeighbourCall post");
+ }
+
+ StreamReader sr = new StreamReader(webResponse.GetResponseStream());
+ //reply = sr.ReadToEnd().Trim();
+ sr.ReadToEnd().Trim();
+ sr.Close();
+ //m_log.InfoFormat("[REST COMMS]: DoHelloNeighbourCall reply was {0} ", reply);
+
+ }
+ catch (WebException ex)
+ {
+ m_log.InfoFormat("[REST COMMS]: exception on reply of DoHelloNeighbourCall {0}", ex.Message);
+ // ignore, really
+ }
+
+ return true;
+
+ }
+
#endregion /* Do Work */
#region Incoming calls from remote instances
@@ -617,33 +731,6 @@ namespace OpenSim.Region.CoreModules.Communications.REST
}
- protected OSDMap GetOSDMap(Hashtable request)
- {
- 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"]);
- if (buffer.Type == OSDType.Map)
- {
- args = (OSDMap)buffer;
- return args;
- }
- else
- {
- // uh?
- m_log.Debug("[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);
- return null;
- }
- }
-
protected virtual void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id)
{
OSDMap args = GetOSDMap(request);
@@ -868,10 +955,129 @@ namespace OpenSim.Region.CoreModules.Communications.REST
responsedata["str_response_string"] = result.ToString();
}
+ /*
+ * Region-related incoming calls
+ *
+ */
+
+ public Hashtable RegionHandler(Hashtable request)
+ {
+ //m_log.Debug("[CONNECTION DEBUGGING]: RegionHandler 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 regionID;
+ string action;
+ ulong regionHandle;
+ if (!GetParams((string)request["uri"], out regionID, 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"))
+ {
+ DoRegionPost(request, responsedata, regionID);
+ return responsedata;
+ }
+ //else if (method.Equals("PUT"))
+ //{
+ // DoRegionPut(request, responsedata, regionID);
+ // return responsedata;
+ //}
+ //else if (method.Equals("DELETE"))
+ //{
+ // DoRegionDelete(request, responsedata, regiontID);
+ // return responsedata;
+ //}
+ else
+ {
+ m_log.InfoFormat("[REST COMMS]: method {0} not supported in region message", method);
+ responsedata["int_response_code"] = 404;
+ responsedata["str_response_string"] = "false";
+
+ return responsedata;
+ }
+
+ }
+
+ protected virtual void DoRegionPost(Hashtable request, Hashtable responsedata, UUID id)
+ {
+ OSDMap args = GetOSDMap(request);
+ if (args == null)
+ {
+ responsedata["int_response_code"] = 400;
+ responsedata["str_response_string"] = "false";
+ return;
+ }
+
+ // retrieve the regionhandle
+ ulong regionhandle = 0;
+ if (args["destination_handle"] != null)
+ UInt64.TryParse(args["destination_handle"].AsString(), out regionhandle);
+
+ RegionInfo aRegion = new RegionInfo();
+ try
+ {
+ aRegion.UnpackRegionInfoData(args);
+ }
+ catch (Exception ex)
+ {
+ m_log.InfoFormat("[REST COMMS]: exception on unpacking HelloNeighbour message {0}", ex.Message);
+ return;
+ }
+
+ // This is the meaning of POST region
+ bool result = m_localBackend.SendHelloNeighbour(regionhandle, aRegion);
+
+ responsedata["int_response_code"] = 200;
+ responsedata["str_response_string"] = result.ToString();
+ }
+
+
#endregion
#region Misc
-
+
+ protected OSDMap GetOSDMap(Hashtable request)
+ {
+ 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"]);
+ if (buffer.Type == OSDType.Map)
+ {
+ args = (OSDMap)buffer;
+ return args;
+ }
+ else
+ {
+ // uh?
+ m_log.Debug("[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);
+ return null;
+ }
+ }
+
///
/// Extract the param from an uri.
///
diff --git a/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs b/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs
index d3f44bb..0b62df2 100644
--- a/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs
+++ b/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs
@@ -32,8 +32,11 @@ namespace OpenSim.Region.Framework.Interfaces
{
public delegate bool ChildAgentUpdateReceived(AgentData data);
- public interface IInterregionCommsOut
+ public interface IInterregionCommsOut
{
+
+ #region Agents
+
bool SendCreateChildAgent(ulong regionHandle, AgentCircuitData aCircuit);
///
@@ -70,8 +73,26 @@ namespace OpenSim.Region.Framework.Interfaces
///
bool SendCloseAgent(ulong regionHandle, UUID id);
+ #endregion Agents
+
+ #region Objects
+
+ ///
+ /// Create an object in the destination region. This message is used primarily for prim crossing.
+ ///
+ ///
+ ///
+ ///
+ ///
bool SendCreateObject(ulong regionHandle, ISceneObject sog, bool isLocalCall);
+ #endregion Objects
+
+ #region Regions
+
+ bool SendHelloNeighbour(ulong regionHandle, RegionInfo thisRegion);
+
+ #endregion Regions
}
// This may not be needed, but having it here for now.
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index c31e6f7..b42c46e 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -422,6 +422,8 @@ namespace OpenSim.Region.Framework.Scenes
/// True after all operations complete, throws exceptions otherwise.
public override bool OtherRegionUp(RegionInfo otherRegion)
{
+ m_log.InfoFormat("[SCENE]: Region {0} up in coords {1}-{2}", otherRegion.RegionName, otherRegion.RegionLocX, otherRegion.RegionLocY);
+
if (RegionInfo.RegionHandle != otherRegion.RegionHandle)
{
for (int i = 0; i < m_neighbours.Count; i++)
@@ -517,6 +519,13 @@ namespace OpenSim.Region.Framework.Scenes
return found;
}
+
+ // Alias IncomingHelloNeighbour OtherRegionUp, for now
+ public bool IncomingHelloNeighbour(RegionInfo neighbour)
+ {
+ return OtherRegionUp(neighbour);
+ }
+
///
/// Given float seconds, this will restart the region.
///
@@ -2569,7 +2578,7 @@ namespace OpenSim.Region.Framework.Scenes
///
public void InformClientOfNeighbor(ScenePresence presence, RegionInfo region)
{
- m_sceneGridService.InformNeighborChildAgent(presence, region, m_neighbours);
+ m_sceneGridService.InformNeighborChildAgent(presence, region);
}
///
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index 2f0bbb2..4c10e2c 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -459,7 +459,7 @@ namespace OpenSim.Region.Framework.Scenes
/// This informs a single neighboring region about agent "avatar".
/// Calls an asynchronous method to do so.. so it doesn't lag the sim.
///
- public void InformNeighborChildAgent(ScenePresence avatar, SimpleRegionInfo region, List neighbours)
+ public void InformNeighborChildAgent(ScenePresence avatar, SimpleRegionInfo region)
{
AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo();
agent.BaseFolder = UUID.Zero;
@@ -493,8 +493,10 @@ namespace OpenSim.Region.Framework.Scenes
m_log.Info("[INTERGRID]: Starting to inform neighbors that I'm here");
//RegionUpData regiondata = new RegionUpData(region.RegionLocX, region.RegionLocY, region.ExternalHostName, region.InternalEndPoint.Port);
- bool regionAccepted =
- m_commsProvider.InterRegion.RegionUp(new SerializableRegionInfo(region), regionhandle);
+ //bool regionAccepted =
+ // m_commsProvider.InterRegion.RegionUp(new SerializableRegionInfo(region), regionhandle);
+
+ bool regionAccepted = m_interregionCommsOut.SendHelloNeighbour(regionhandle, region);
if (regionAccepted)
{
@@ -519,7 +521,7 @@ namespace OpenSim.Region.Framework.Scenes
{
//m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: Sending InterRegion Notification that region is up " + region.RegionName);
-
+
List neighbours = new List();
// This stays uncached because we don't already know about our neighbors at this point.
neighbours = m_commsProvider.GridService.RequestNeighbours(m_regionInfo.RegionLocX, m_regionInfo.RegionLocY);
--
cgit v1.1