Pushing this to share the implementation approach. This is almost entirely stubbed out but provides a framework for the major servers that will existing implementing the grid. There will also be a user service, inventory service, assets and messaging service. So this is a bit of a step back to the old UGAIM approach originally implemented but also entirely appropriate given the architectural approach. Each server also has a container definition and can be deployed into a container. The HTTP server uses Kestrel which interoperates with proxies well. And everything will be async all the way down.

This commit is contained in:
Mike Dickson 2024-06-29 16:03:36 -04:00
parent 994c0690cb
commit 54dc9a0287
15 changed files with 272 additions and 240 deletions

View file

@ -55,14 +55,16 @@ namespace OpenSim.OfflineIM
public OfflineIMServiceRobustConnector(
IConfiguration configuration,
ILogger<OfflineIMServiceRobustConnector> logger,
OfflineIMService offlineIMService,
IHttpServer server) :
this(configuration, logger, server, m_ConfigName)
this(configuration, logger, offlineIMService, server, m_ConfigName)
{
}
public OfflineIMServiceRobustConnector(
IConfiguration configuration,
ILogger<OfflineIMServiceRobustConnector> logger,
OfflineIMService offlineIMService,
IHttpServer server,
string configName)
{
@ -71,7 +73,7 @@ namespace OpenSim.OfflineIM
m_logger.LogDebug($"Starting with config name {configName}");
m_OfflineIMService = new OfflineIMService(configuration);
m_OfflineIMService = offlineIMService;
IServiceAuth auth = ServiceAuth.Create(configuration, configName);

View file

@ -7,6 +7,7 @@
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerfileContext>.</DockerfileContext>
<EnableSdkContainerSupport>true</EnableSdkContainerSupport>
<UserSecretsId>69c28835-32fa-41ba-bd88-238f8375d0a0</UserSecretsId>
</PropertyGroup>
<PropertyGroup>

View file

@ -1,10 +1,12 @@
using System.CommandLine;
using Humanizer;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using MySqlConnector;
using OpenSim.Data.Model.Core;
using OpenSim.Data.Model.Economy;
using OpenSim.Data.Model.Identity;
@ -15,50 +17,55 @@ namespace OpenSim.Server.GridServer;
public class Program
{
public static void SetCommandLineArgs(string console, List<string> inifiles, string prompt)
static string _console = "local";
static string _prompt = "Grid$ ";
static List<string>? _inifiles = null;
public static async Task Main(string[] args)
{
var rootCommand = new RootCommand("Grid Server");
}
var consoleOption = new Option<string>
(name: "--console", description: "console type, one of basic, local or rest.",
getDefaultValue: () => "local")
.FromAmong("basic", "local", "rest");
var promptOption = new Option<string>
(name: "--prompt", description: "Overide the server prompt",
getDefaultValue: () => "Grid$ ");
var inifileOption = new Option<List<string>>
(name: "--inifile", description: "Specify the location of zero or more .ini file(s) to read.");
public static void Main(string[] args)
{
// var rootCommand = new RootCommand("Grid Server");
// var consoleOption = new Option<string>
// (name: "--console", description: "console type, one of basic, local or rest.", getDefaultValue: () => "local")
// .FromAmong("basic", "local", "rest");
// var inifileOption = new Option<List<string>>
// (name: "--inifile", description: "Specify the location of zero or more .ini file(s) to read.");
// var promptOption = new Option<string>
// (name: "--prompt", description: "Overide the server prompt",
// getDefaultValue: () => "GRID> ");
// rootCommand.Add(consoleOption);
// rootCommand.Add(inifileOption);
// rootCommand.Add(promptOption);
rootCommand.Add(consoleOption);
rootCommand.Add(inifileOption);
rootCommand.Add(promptOption);
// rootCommand.SetHandler(
// (consoleOptionValue, inifileOptionValue, promptOptionValue) =>
// {
// SetCommandLineArgs(consoleOptionValue, inifileOptionValue, promptOptionValue);
// },
// consoleOption, inifileOption, promptOption);
rootCommand.SetHandler(
(consoleOptionValue, promptOptionValue, inifileOptionValue) =>
{
_console = consoleOptionValue;
_prompt = promptOptionValue;
_inifiles = inifileOptionValue;
},
consoleOption, promptOption, inifileOption);
// await rootCommand.InvokeAsync(args);
await rootCommand.InvokeAsync(args);
// Create Builder and run program
var builder = WebApplication.CreateBuilder(args);
//builder.Configuration.EnableSubstitutions("$(", ")");
// builder.Configuration.AddCommandLine(args, switchMappings);
// builder.Configuration.EnableSubstitutions("$(", ")");
builder.Configuration.AddIniFile("GridServer.ini", optional: true, reloadOnChange: false);
builder.Configuration.AddEnvironmentVariables();
// foreach (var item in inifile)
// {
// builder.Configuration.AddIniFile(item, optional: true, reloadOnChange: true);
// }
if (_inifiles is not null)
{
foreach (var item in _inifiles)
{
builder.Configuration.AddIniFile(item, optional: true, reloadOnChange: false);
}
}
// Initialize Database
var connectionString = builder.Configuration.GetConnectionString("IdentityConnection");
builder.Services.AddDbContext<IdentityContext>(

View file

@ -0,0 +1,22 @@
namespace OpenSim.Server.GridServer;
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
// add your services here
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//add configuration/middleware here
}
}

View file

@ -1,35 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"DetailedErrors": true,
"ConnectionStrings": {
"IdentityConnection": "server=localhost; port=3306; database=identity; user=opensim; password=*M1ke.Chase*;GuidFormat=None",
"OpenSimCoreConnection": "server=localhost; port=3306; database=opensim; user=opensim; password=*M1ke.Chase*;GuidFormat=None",
"OpenSimRegionConnection": "server=localhost; port=3306; database=opensim; user=opensim; password=*M1ke.Chase*;GuidFormat=None",
"OpenSimEconomyConnection": "server=localhost; port=3306; database=osmoney; user=opensim; password=*M1ke.Chase*; GuidFormat=None",
"OpenSimSearchConnection": "server=localhost; port=3306; database=ossearch; user=opensim; password=*M1ke.Chase*; GuidFormat=None",
"OpenSimMarketConnection": "server=localhost; port=3306; database=market; user=opensim; password=*M1ke.Chase*; GuidFormat=None"
},
"DefaultGroups": {
"GroupNames": [ "Utopia Skye Welcome" ]
},
"RemoteAdmin": {
"UserName": "radmin",
"AccessCode": "N0tAChance",
"UserService_URL": "http://localhost:9000/xmlrpc/RemoteAdmin"
},
"AuthMessageSenderOptions": {
"FromEmailAddress": "noreply@utopiaskye.com",
"SendGridKey": "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"
}
}

View file

@ -9,27 +9,7 @@
"DetailedErrors": true,
"ConnectionStrings": {
"IdentityConnection": "server=localhost; port=3306; database=identity; user=opensim; password=*M1ke.Chase*;GuidFormat=None",
"OpenSimCoreConnection": "server=localhost; port=3306; database=opensim; user=opensim; password=*M1ke.Chase*;GuidFormat=None",
"OpenSimRegionConnection": "server=localhost; port=3306; database=opensim; user=opensim; password=*M1ke.Chase*;GuidFormat=None",
"OpenSimEconomyConnection": "server=localhost; port=3306; database=osmoney; user=opensim; password=*M1ke.Chase*; GuidFormat=None",
"OpenSimSearchConnection": "server=localhost; port=3306; database=ossearch; user=opensim; password=*M1ke.Chase*; GuidFormat=None",
"OpenSimMarketConnection": "server=localhost; port=3306; database=market; user=opensim; password=*M1ke.Chase*; GuidFormat=None"
},
"DefaultGroups": {
"GroupNames": [ "Utopia Skye Welcome" ]
},
"RemoteAdmin": {
"UserName": "radmin",
"AccessCode": "N0tAChance",
"UserService_URL": "http://localhost:9000/xmlrpc/RemoteAdmin"
},
"AuthMessageSenderOptions": {
"FromEmailAddress": "noreply@utopiaskye.com",
"SendGridKey": "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"
}
}

View file

@ -4,12 +4,13 @@ using OpenMetaverse;
using OpenSim.Services.Interfaces;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
using OpenSim.Server.HyperGridServer.Dto;
namespace OpenSim.Server.HyperGrid.Controllers;
[ApiController]
[Route("[controller]")]
public class GatekeeperServiceController : ControllerBase, IGatekeeperService
public class GatekeeperServiceController : ControllerBase // , IGatekeeperService
{
private readonly IConfiguration _configuration;
private readonly ILogger<GatekeeperServiceController> _logger;
@ -22,25 +23,26 @@ public class GatekeeperServiceController : ControllerBase, IGatekeeperService
_logger = logger;
}
[HttpGet(Name = "GetHyperLinkRegion")]
[HttpGet(Name = "get_region")]
[Produces("application/xml")]
public GridRegion GetHyperlinkRegion(global::OpenMetaverse.UUID regionID, global::OpenMetaverse.UUID agentID, string agentHomeURI, out string message)
public GetRegionResponse GetHyperlinkRegion(UUID regionID)
{
throw new NotImplementedException();
}
[HttpGet(Name = "LinkRegion")]
[Produces("application/xml")]
public bool LinkRegion(string regionDescriptor, out global::OpenMetaverse.UUID regionID, out ulong regionHandle, out string externalName, out string imageURL, out string reason, out int sizeX, out int sizeY)
{
throw new NotImplementedException();
}
[HttpGet(Name = "LoginAgent")]
[Produces("application/xml")]
public bool LoginAgent(GridRegion source, AgentCircuitData aCircuit, GridRegion destination, out string reason)
{
throw new NotImplementedException();
}
// [HttpGet(Name = "link_region")]
// [Produces("application/xml")]
// public LinkRegionResponse LinkRegion(string regionDescriptor)
// {
// throw new NotImplementedException();
// }
// [HttpPost(Name = "LoginAgent")]
// [Produces("application/xml")]
// public LoginAgentResponse LoginAgent([FromBody]GridRegion source, [FromBody]AgentCircuitData aCircuit, [FromBody]GridRegion destination)
// {
// throw new NotImplementedException();
// }
}

View file

@ -0,0 +1,40 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* (c) 2024 Utopia Skye LLC
*/
using Microsoft.AspNetCore.Mvc;
using OpenSim.Framework;
using OpenMetaverse;
using OpenSim.Services.Interfaces;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
using OpenSim.Server.HyperGridServer.Dto;
namespace OpenSim.Server.HyperGrid.Controllers;
[ApiController]
[Route("[controller]")]
public class HeloServiceController : ControllerBase
{
private readonly IConfiguration _configuration;
private readonly ILogger<HeloServiceController> _logger;
public HeloServiceController(
IConfiguration configuration,
ILogger<HeloServiceController> logger)
{
_configuration = configuration;
_logger = logger;
}
[HttpGet]
[Route("helo")]
public void Helo()
{
throw new NotImplementedException();
}
}

View file

@ -1,3 +1,11 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* (c) 2024 Utopia Skye LLC
*/
using Microsoft.AspNetCore.Mvc;
using OpenSim.Framework;
using OpenMetaverse;
@ -9,7 +17,7 @@ namespace OpenSim.Server.HyperGrid.Controllers;
[ApiController]
[Route("[controller]")]
public class UserAgentServiceController : ControllerBase, IUserAgentService
public class UserAgentServiceController : ControllerBase //, IUserAgentService
{
private readonly IConfiguration _configuration;
private readonly ILogger<UserAgentServiceController> _logger;
@ -22,87 +30,87 @@ public class UserAgentServiceController : ControllerBase, IUserAgentService
_logger = logger;
}
[HttpGet(Name = "LoginAgentToGrid")]
[Produces("application/xml")]
public bool LoginAgentToGrid(GridRegion source, AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, bool fromLogin, out string reason)
{
throw new NotImplementedException();
}
// [HttpGet]
// [Route(homeagent/{agentid})]
// public bool LoginAgentToGrid(GridRegion source, AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, bool fromLogin, out string reason)
// {
// throw new NotImplementedException();
// }
[HttpGet(Name = "LogoutAgent")]
[Produces("application/xml")]
public void LogoutAgent(UUID userID, UUID sessionID)
{
throw new NotImplementedException();
}
// [HttpGet(Name = "LogoutAgent")]
// [Produces("application/xml")]
// public void LogoutAgent(UUID userID, UUID sessionID)
// {
// throw new NotImplementedException();
// }
[HttpGet(Name = "GetHomeRegion")]
[Produces("application/xml")]
public GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt)
{
throw new NotImplementedException();
}
// [HttpGet(Name = "GetHomeRegion")]
// [Produces("application/xml")]
// public GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt)
// {
// throw new NotImplementedException();
// }
[HttpGet(Name = "GetServerURLs")]
[Produces("application/xml")]
public Dictionary<string, object> GetServerURLs(UUID userID)
{
throw new NotImplementedException();
}
// [HttpGet(Name = "GetServerURLs")]
// [Produces("application/xml")]
// public Dictionary<string, object> GetServerURLs(UUID userID)
// {
// throw new NotImplementedException();
// }
[HttpGet(Name = "GetUserInfo")]
[Produces("application/xml")]
public Dictionary<string, object> GetUserInfo(UUID userID)
{
throw new NotImplementedException();
}
// [HttpGet(Name = "GetUserInfo")]
// [Produces("application/xml")]
// public Dictionary<string, object> GetUserInfo(UUID userID)
// {
// throw new NotImplementedException();
// }
[HttpGet(Name = "LocateUser")]
[Produces("application/xml")]
public string LocateUser(UUID userID)
{
throw new NotImplementedException();
}
// [HttpGet(Name = "LocateUser")]
// [Produces("application/xml")]
// public string LocateUser(UUID userID)
// {
// throw new NotImplementedException();
// }
[HttpGet(Name = "GetUUI")]
[Produces("application/xml")]
public string GetUUI(UUID userID, UUID targetUserID)
{
throw new NotImplementedException();
}
// [HttpGet(Name = "GetUUI")]
// [Produces("application/xml")]
// public string GetUUI(UUID userID, UUID targetUserID)
// {
// throw new NotImplementedException();
// }
[HttpGet(Name = "GetUUID")]
[Produces("application/xml")]
public UUID GetUUID(string first, string last)
{
throw new NotImplementedException();
}
// [HttpGet(Name = "GetUUID")]
// [Produces("application/xml")]
// public UUID GetUUID(string first, string last)
// {
// throw new NotImplementedException();
// }
[HttpGet(Name = "StatusNotification")]
[Produces("application/xml")]
public List<UUID> StatusNotification(List<string> friends, UUID userID, bool online)
{
throw new NotImplementedException();
}
// [HttpGet(Name = "StatusNotification")]
// [Produces("application/xml")]
// public List<UUID> StatusNotification(List<string> friends, UUID userID, bool online)
// {
// throw new NotImplementedException();
// }
[HttpGet(Name = "IsAgentComingHome")]
[Produces("application/xml")]
public bool IsAgentComingHome(UUID sessionID, string thisGridExternalName)
{
throw new NotImplementedException();
}
// [HttpGet(Name = "IsAgentComingHome")]
// [Produces("application/xml")]
// public bool IsAgentComingHome(UUID sessionID, string thisGridExternalName)
// {
// throw new NotImplementedException();
// }
[HttpGet(Name = "VerifyAgent")]
[Produces("application/xml")]
public bool VerifyAgent(UUID sessionID, string token)
{
throw new NotImplementedException();
}
// [HttpGet(Name = "VerifyAgent")]
// [Produces("application/xml")]
// public bool VerifyAgent(UUID sessionID, string token)
// {
// throw new NotImplementedException();
// }
[HttpGet(Name = "VerifyClient")]
[Produces("application/xml")]
public bool VerifyClient(UUID sessionID, string reportedIP)
{
throw new NotImplementedException();
}
// [HttpGet(Name = "VerifyClient")]
// [Produces("application/xml")]
// public bool VerifyClient(UUID sessionID, string reportedIP)
// {
// throw new NotImplementedException();
// }
}

View file

@ -0,0 +1,6 @@
namespace OpenSim.Server.HyperGridServer.Dto;
public class GetRegionResponse
{
}

View file

@ -0,0 +1,14 @@
using OpenMetaverse;
namespace OpenSim.Server.HyperGridServer.Dto;
public class LinkRegionResponse
{
UUID regionID;
ulong regionHandle;
string externalName;
string imageURL;
string reason;
int sizeX;
int sizeY;
}

View file

@ -0,0 +1,6 @@
namespace OpenSim.Server.HyperGridServer.Dto;
public class LoginAgentResponse
{
}

View file

@ -15,49 +15,55 @@ namespace OpenSim.Server.HyperGrid;
public class Program
{
public static void SetCommandLineArgs(string console, List<string> inifiles, string prompt)
static string _console = "local";
static string _prompt = "HyperGrid$ ";
static List<string>? _inifiles = null;
public static async Task Main(string[] args)
{
var rootCommand = new RootCommand("Grid Server");
}
var consoleOption = new Option<string>
(name: "--console", description: "console type, one of basic, local or rest.",
getDefaultValue: () => "local")
.FromAmong("basic", "local", "rest");
var promptOption = new Option<string>
(name: "--prompt", description: "Overide the server prompt",
getDefaultValue: () => "HyperGrid$ ");
var inifileOption = new Option<List<string>>
(name: "--inifile", description: "Specify the location of zero or more .ini file(s) to read.");
public static void Main(string[] args)
{
// var rootCommand = new RootCommand("Grid Server");
// var consoleOption = new Option<string>
// (name: "--console", description: "console type, one of basic, local or rest.", getDefaultValue: () => "local")
// .FromAmong("basic", "local", "rest");
// var inifileOption = new Option<List<string>>
// (name: "--inifile", description: "Specify the location of zero or more .ini file(s) to read.");
// var promptOption = new Option<string>
// (name: "--prompt", description: "Overide the server prompt",
// getDefaultValue: () => "GRID> ");
// rootCommand.Add(consoleOption);
// rootCommand.Add(inifileOption);
// rootCommand.Add(promptOption);
rootCommand.Add(consoleOption);
rootCommand.Add(inifileOption);
rootCommand.Add(promptOption);
// rootCommand.SetHandler(
// (consoleOptionValue, inifileOptionValue, promptOptionValue) =>
// {
// SetCommandLineArgs(consoleOptionValue, inifileOptionValue, promptOptionValue);
// },
// consoleOption, inifileOption, promptOption);
rootCommand.SetHandler(
(consoleOptionValue, promptOptionValue, inifileOptionValue) =>
{
_console = consoleOptionValue;
_prompt = promptOptionValue;
_inifiles = inifileOptionValue;
},
consoleOption, promptOption, inifileOption);
// await rootCommand.InvokeAsync(args);
await rootCommand.InvokeAsync(args);
// Create Builder and run program
var builder = WebApplication.CreateBuilder(args);
// builder.Configuration.AddCommandLine(args, switchMappings);
//builder.Configuration.EnableSubstitutions("$(", ")");
builder.Configuration.AddIniFile("HyperGridServer.ini", optional: true, reloadOnChange: false);
builder.Configuration.AddEnvironmentVariables();
// builder.Configuration.EnableSubstitutions("$(", ")");
builder.Configuration.AddIniFile("GridServer.ini", optional: true, reloadOnChange: false);
// foreach (var item in inifile)
// {
// builder.Configuration.AddIniFile(item, optional: true, reloadOnChange: true);
// }
if (_inifiles is not null)
{
foreach (var item in _inifiles)
{
builder.Configuration.AddIniFile(item, optional: true, reloadOnChange: false);
}
}
// Initialize Database
var connectionString = builder.Configuration.GetConnectionString("IdentityConnection");

View file

@ -1,8 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View file

@ -9,27 +9,8 @@
"DetailedErrors": true,
"ConnectionStrings": {
"IdentityConnection": "server=localhost; port=3306; database=identity; user=opensim; password=*M1ke.Chase*;GuidFormat=None",
"OpenSimCoreConnection": "server=localhost; port=3306; database=opensim; user=opensim; password=*M1ke.Chase*;GuidFormat=None",
"OpenSimRegionConnection": "server=localhost; port=3306; database=opensim; user=opensim; password=*M1ke.Chase*;GuidFormat=None",
"OpenSimEconomyConnection": "server=localhost; port=3306; database=osmoney; user=opensim; password=*M1ke.Chase*; GuidFormat=None",
"OpenSimSearchConnection": "server=localhost; port=3306; database=ossearch; user=opensim; password=*M1ke.Chase*; GuidFormat=None",
"OpenSimMarketConnection": "server=localhost; port=3306; database=market; user=opensim; password=*M1ke.Chase*; GuidFormat=None"
},
"DefaultGroups": {
"GroupNames": [ "Utopia Skye Welcome" ]
},
"RemoteAdmin": {
"UserName": "radmin",
"AccessCode": "N0tAChance",
"UserService_URL": "http://localhost:9000/xmlrpc/RemoteAdmin"
},
"AuthMessageSenderOptions": {
"FromEmailAddress": "noreply@utopiaskye.com",
"SendGridKey": "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"
}
}