HttpApi name conflict

Hello,
I am working on an HttpApi server to expose our RemObjects SDK server as a Rest server. When a request comes in, the rest server passes the call to the original sdk server and then returns the result back to the client as JSON. The problem I’m facing is that both servers define an object name ‘Project’ and this raises an error when calling the original sdk server:

System.InvalidCastException: ‘Object cannot be stored in an array of this type.’

at this line:

Project[] _Result = ((Project[])(___localMessage.Read(“Result”, typeof(Project[]), RemObjects.SDK.StreamingFormat.Default)));

If I want to keep the same names for the same objects (aka ‘Project’), how can this be fixed?

Thanks

ROServer1.zip (2.0 MB)

Hello

So here we have a proxy server that relays incoming requests to another SDK server.
Here is a naming conflict as we have to define structures both in the _intf file (to be able to send requests to the base server) and as part of the HttpAPI proxy server definition.

The solution is to reuse the base server definitions. Add the base server RODL as embedded resource to the proxy server project and set its build action to Embedded Resource. Then remove your own custom Project class definition and reuse one in the _Intf file.

Now your server will be able to start and will be able to relay requests to the base server.

This is a mixed-mode server application where data structures are defined in a RODL file while services are defined in a CodeFirst way.

Unfortunately there is still one issue: the proxy server exposes services it does not implement in its RODL. Also it seems that some methods in the source RODL have HttpAPI attributes attached, so the OpenAPI service definition at http://localhost:8099/api/ also contains references to methods not implemented by this server.

We need to add some code to fix this without any changes to the base server application and without manual RODL editing.

Add this class to the proxy server app project:

	sealed class ProxyRodlProvider : IRodlProvider
	{
		private readonly RodlLibrary _library;

		public ProxyRodlProvider(Assembly assembly)
		{
			String resourceName = "";
            // Search RODL resource name
			foreach (String resource in assembly.GetManifestResourceNames())
			{
				if (String.Equals(Path.GetExtension(resource), ".rodl", StringComparison.OrdinalIgnoreCase))
				{
					resourceName = resource;
				}
			}

            if (String.IsNullOrEmpty(resourceName))
            {
	            throw new ServerSetupException("RODL not found");
            }

            // Load the RODL stream
            var rodlData = assembly.GetManifestResourceStream(resourceName);

            // Deserialize RODL
            var rodlLibrary = new RodlLibrary(rodlData);

            // Remove all service and event sink definitions
            rodlLibrary.Services.Clear();
            rodlLibrary.EventSinks.Clear();

            this._library = rodlLibrary;
		}

		public ICollection<Stream> GetRodls()
		{
			var rodlStream = new MemoryStream(2048);
			this._library.SaveToStream(rodlStream, false);
			rodlStream.Seek(0, SeekOrigin.Begin);

			return new Stream[] { rodlStream };
        }
	}

This class loads RODL resource form the provided assembly and then removes service definitions and event sink definitions from the loaded RODL.

Then modify the Program.Main method:

        public static int Main(string[] args)
        {
            ApplicationServer server = new ApplicationServer("RestService");

            HttpApiDispatcher dispatcher = new HttpApiDispatcher();
            dispatcher.ApiHost = "localhost:8099";
            dispatcher.Server = server.NetworkServer.ServerChannel as IHttpServer;

            // Code added
            RodlResource.AddIgnoredAssembly(typeof(Program).Assembly);
            RodlResource.RegisterRodlProvider(new ProxyRodlProvider(typeof(Program).Assembly));

            server.Run(args);
            return 0;
        }

Note the 2 code lines added here. They order Remoting SDK not to try to auto-load RODL resource from the current assembly. Instead a custom adjusted RODL is used supplied by a custom RODL provider.

Now the RODL and OpenAPI exposed by the proxy server applications do not mention services it does not implement.

Regards

Hello, thanks again. We will add your changes to the project…