IMOP host addresses

A user-defined imop: type must have an authority address (i.e., a host name and a port number) in its UTL. Moreover, the IMOP plugin in the Meso runtime must be configured to listen to that address. There are various ways to put the address in code and configure the IMOP plugin accordingly.

Explicit address

The most direct way is to explicitly put the address in the namespace statement. For example, to create an imop:example.com/foo.Bar object, one can write:

namespace imop:example.com/foo;    // the authority address is example.com:90

public object Bar {

   // ...
}

The default port number of the IMOP protocol is port 90, so example.com is equivalent to example.com:90. To make the runtime listen to that address, you will put the following in the config.xml file:

<meso>
   <plugin class="meso.plugin.imop.ImopPlugin">

      <!-- listens to example.com:90 -->
      <listener address="example.com" />

      <!-- the root path to search for *.imop source files -->
      <src path="." />

   </plugin>
</meso>

You will need to start the Meso runtime from an account with administrator's privilege to open the port 90 in an operating system. For example, you can use sudo in many unix-like operating systems:

stefan@macpro:~/remote$ sudo java -jar meso.jar -cf config.xml
Password: ************
Meso 1.6.0 Build 2011-1113 with IMOP transport 0.6
Runtime Build $Date: 2011-11-13 17:27:49 -0800 (Sun, 13 Nov 2011) $
INFO: Authority 'example.com:90' bound to port 90
INFO: Port 90 opened
runtime> _

Note that this is meaningful only if you actually do this at the host of example.com. Otherwise, remote IMOP requests intended for example.com will not be routed to this runtime system anyway.

Wildcard address in namespace

Sometimes you do not know the host address that will be serving your objects, or you do not want the address to be hard-coded in the source code so that the program can be used on multiple hosts without change. In these cases, you can put a wildcard address in the namespace statement. For example:

namespace imop:*/foo;                  // any host name on port 90
namespace imop:*:9900/foo;             // any host name on port 9900
namespace imop:example.com:*/foo;      // example.com on any port
namespace imop:*:*/foo;                // any host name on any port

The supported wildcard patterns are still quite limited at the moment. We might expand it to a full-blown regular expression in the future.

The full UTL of a data type defined under a wildcard namespace will depend on the runtime's configuration. For example, assume that we have this Bar.imop source file:

namespace imop:*:*/foo;    // any host name on any port number

public object Bar {

   // ...
}

And we put it on a server that can be reached with two different host names, foo.com and bar.com, and start the Meso runtime with the following config.xml listening to both addresses:

<meso>
   <plugin class="meso.plugin.imop.ImopPlugin">

      <!-- listens to foo.com:90 -->
      <listener address="foo.com" />

      <!-- listens to bar.com:1234 -->
      <listener address="bar.com:1234" />

      <!-- the root path to search for *.imop source files -->
      <src path="." />

   </plugin>
</meso>

Under this configuration, incoming requests for imop:foo.com/foo.Bar and imop:bar.com:1234/foo.Bar will both be handled by the object defined in the same Bar.imop source file. However, these two UTLs are considered to represent two different objects, and therefore two singleton instances will be created in the runtime, one for each UTL, as if each has a unique source file.

Authority address aliases

To use a remote resource from a client program, one must put its UTL with an explicit authority address in an import statement. This is not a problem when we want to use existing services or APIs that are already published. However, when we are developing a new service, it will be running in a development environment ― usually just the developer's own computer ― whose host name is different from the production site. Wildcard address in the namespace solved the problem on the service side, but we also need our client program use resources from the development site as well. This can be achieved by adding address aliases in the config.xml file. For example:

<meso>
   <plugin class="meso.plugin.imop.ImopPlugin">

      <!-- all requests intended for example.com:90 are directed to localhost:9900 -->
      <alias from="example.com" to="localhost:9900" />

      <!-- the root path to search for *.imop source files -->
      <src path="." />

   </plugin>
</meso>

With this alias in the config file, requests to a UTL such as imop:example.com/foo.Bar will be redirected to imop:localhost:9900/foo.Bar.

The address alias work for the entire runtime, so it can also be useful if the service side programs are hard-coded with explicit addresses in the namespace. For example, if we want to test this object in a development environment:

namespace imop:example.com/foo;    // the authority address is example.com:90

public object Bar {

   // ...
}

We can start a Meso runtime with this config file to serve example.com from localhost:9900:

<meso>
   <plugin class="meso.plugin.imop.ImopPlugin">

      <!-- setup the alias -->
      <alias from="example.com" to="localhost:9900" />

      <!-- will listen to localhost:9900 instead because of the alias -->
      <listener address="example.com" />

      <!-- the root path to search for *.imop source files -->
      <src path="." />

   </plugin>
</meso>

And setup the same alias for the client program so that the client can talk to the server through localhost:9900, even though both sides hard-coded example.com in the namespace and import statements.

We believe that similar aliasing features will be integrated in the IDEs of the Meso language in the future. Programmers will have great flexibility in controlling how network programs can be tested in a development environment without manually setting such aliases.