11.2. Remote Persistence Managers
Prev | Chapter 11. Remote and Offline JDO | Next

## 11.2. Remote Persistence Managers

In JDO, each persistence manager factory maintains a set of resources shared by all the persistence managers produced by that factory. Sharing common structures like connection pools and data caches drastically reduces the resource consumption of each persistence manager, increasing your application's scalability. Kodo takes this concept one step further by also giving its persistence manager factories the ability to act as servers for persistence managers on remote machines. You can thus leverage the full JDO API in your client tier without duplicating limited resources like database connections on each client. In addition to ensuring that your application scales as more clients are added, this model may allow you to use Kodo in situations where the client machine cannot directly access the necessary server-side resources itself - for example, when the database is only available to the local network.

This remote capability means that you can design your application as a simple two-tiered servlet-database application, and then migrate to a more scalable servlet-JDO middle tier-database architecture as the load on your system increases. This end picture looks much like a standard J2EE application server architecture, except that the code that uses the JDO APIs in the servlet does not need to change at all to toggle between the more performant two-tier architecture and the more scalable three-tier architecture.

Additionally, Kodo's remote capability is useful for applet and Java Web Start application development. In conjunction with the compressed HTTP transport, you can deploy code that uses JDO via an applet or a Web Start application. The persistence managers in these applications will then connect back to the server that they were downloaded from in order to access the database.

| Note
Kodo's remote persistence manager capabilities require an Enterprise Edition license in order to function. See Chapter 13, Enterprise Edition for details about what is included in the Enterprise Edition.

### 11.2.1. Standalone Persistence Manager Server

To configure a persistence manager factory to act as a standalone server to remote persistence managers, set the factory's `kodo.PersistenceManagerServer` configuration property to a plugin string (see Section 2.4, “Plugin Configuration”) describing the `com.solarmetric.remote.Transport` implementation to use for remote communication. You can implement your own `Transport`, or use one of the bulit-in options:

- `false`: The default value. No server is started.

- `tcp`: An alias for `com.solarmetric.remote.TCPTransport` , a TCP transport layer. This transport layer has the following settings:

  - `Port`: The port the server will listen on. Defaults to 5637.

  - `Host`: The host name of the server. Defaults to `localhost`. This setting is not used by the server, but by clients. We discuss client configuration below.

  - `SoTimeout`: The socket read timeout in milliseconds. Defaults to 0 for no timeout.

  - `Decorators`: See Section 11.2.4, “Data Compression and Filtering”

Example 11.3. Configuring a Standalone Persistence Manager Server

    kodo.PersistenceManagerServer: tcp(Port=5555)

When a persistence manager factory is configured as a standalone server, it begins listening for client connections automatically as soon as you obtain the factory. The server will run for as long as the factory remains open, and will shut down when you close the factory. The `kodo.runtime.KodoPersistenceManagerFactory` interface also provides methods for manually managing its server thread. See its Javadoc for details.

Your Kodo distribution includes a program to start a standalone persistence manager server. You can run the program through its Java class, `kodo.jdbc.runtime.StartPersistenceManagerServer`, or through the provided `startpmserver` command-line script. The script accepts the standard Kodo command-line arguments outlined in Section 2.3, “Command Line Configuration”.

Example 11.4. Starting a Standalone Persistence Manager Server

    startpmserver -p server.properties

### 11.2.2. HTTP Persistence Manager Server

Kodo's remote persistence managers can communicate with the server over HTTP, allowing you to use them through firewalls that shut off other ports and protocols. In order to receive HTTP requests from remote clients, Kodo includes the `kodo.remo.PersistenceManagerServerServlet` . You can deploy this servlet into any standards-compliant servlet container.

The `PersistenceManagerServerServlet` services remote persistence manager requests using an internal persistence manager factory. The servlet provides several mechanisms for configuring this persistence manager factory:

1. First, the servlet checks the value of the `kodo.jndi` servlet initialization parameter (servlet initialization parameters are specified in the standard `web.xml` deployment file; see your servlet container documentation for details). If the value of this parameter is non-null, Kodo attempts to look up the persistence manager factory at the indicated JNDI location.

2. If the `kodo.jndi` initialization parameter is not set, Kodo checks the `kodo.properties` intialization parameter. The value of this parameter is a resource path to a Java properties file containing Kodo configuration properties. If no value is given, the resource path defaults to `/kodo.properties`, which corresponds to a `kodo.properties` file located in the root of the WAR or expanded servlet directory.

3. Finally, Kodo checks the remainder of the servlet initialization parameters for Kodo configuration properties. These parameter values override the value supplied in the properties file (if any).

You can make sure that the servlet's persistence manager factory is configured as expected by navigating to the servlet in your web browser. The servlet will display a simple web page detailing the configuration of its internal factory.

### 11.2.3. Client Persistence Managers

Client persistence managers are remote proxies to server-side persistence managers created by the server-side persistence manager factory you are communicating with. From an API standpoint, a client persistence manager is exactly like a local one, complete with all Kodo API extensions. Behind the scenes, however, the actions you take on a client persistence manager are sent to the corresponding server-side persistence manager for processing. For performance reasons and because your persistent objects are not proxies themselves, each client persistence manager has a local cache of managed objects, synchronized with the server-side persistence manager's cache.

You obtain client persistence managers in the same way you obtain local persistence managers: from a persistence manager factory that you have constructed through JCA or the `JDOHelper` or `KodoHelper`. Client configuration properties are the same as those used for local Kodo operation, with the following exceptions:

- The `javax.jdo.PersistenceManagerFactoryClass` property must be set to Kodo's client factory, `kodo.remote.ClientPersistenceManagerFactory`.

- The `kodo.PersistenceManagerServer` setting is used to find the remote server. If you are using a standalone persistence manager server, the value of this property is typically the same as its value on the server. If you are using the HTTP servlet , the value of this property on the client is:

      kodo.PersistenceManagerServer: http(URL=<servlet-url>)

  `http` in the setting above is an alias for the `com.solarmetric.remote.HTTPTransport` , whose `URL` property indicates the URL to connect to. You can also specify a `Decorators` property, as discussed in Section 11.2.4, “Data Compression and Filtering”.

- The `kodo.ConnectionRetainMode` property controls how the client handles connections to the server, not how the server handles connections to the database. The available values are the same as the options for database connections:

  - `persistence-manager`: Each client persistence manager obtains a single connection to its server-side counterpart and uses this connection until the persistence manager is closed.

  - `transaction`: A connection is obtained when each transaction begins, and relinquished when the transaction completes. Nontransactional connections are obtained as needed and released immediately.

  - `on-demand`: A connection to the server is obtained when needed, and immediately closed when the request has been fulfilled. This is the default.

- `kodo.ConnectionFactoryProperties` controls pooling not for database connections, but for connections from the client machine to the remote server. The following pooling options are available:

  - `ExceptionAction`: The action to take when when a connection that has thrown an exception is returned to the pool. Set to `destroy` to destroy the connection. Set to `validate` to validate the connection (subject to the `TestOnReturn`, `TestOnBorrow`, and other test settings). Set to `none` to ignore the fact that the connection has thrown an exception, and assume it is still usable. Defaults to `destroy`.

  - `MaxActive`: The maximum number of connections in use at one time. Defaults to 8.

  - `MaxIdle`: The maximum number of idle connections to keep in the pool. Defaults to 8.

  - `MaxWait`: The maximum number of milliseconds to wait for a free connection to become available before giving up. Defaults to 3000.

  - `MinEvictableIdleTimeMillis`: The minimum number of milliseconds that a connection can sit idle before it becomes a candidate for eviction from the pool. Defaults to 30 minutes. Set to 0 to never evict a connection based on idle time alone.

  - `TestOnBorrow`: Whether to to validate connections before obtaining them from the pool. Defaults to `true`.

  - `TestOnReturn`: Set to `true` to validate connections when they are returned to the pool.

  - `TestWhileIdle`: Set to `true` to periodically validate idle connections.

  - `TimeBetweenEvictionRunsMillis`: The number of milliseconds between runs of the eviction thread. Defaults to -1, meaning the eviction thread will never run.

  - `ValidationTimeout`: The minimum number of milliseconds that must elapse before a connection will ever be re-validated. This property is usually used with `TestOnBorrow` or `TestOnReturn` to reduce the number of validations performed, because the same connection is often borrowed and returned many times in short periods of time. Defaults to `300000` (5 minutes).

  - `WhenExhaustedAction`: The action to take when there are no available connections in the pool. Set to `exception` to immediately throw an exception. Set to `block` to block until a connection is available or the maximum wait time is exceeded. Set to `grow` to automatically grow the pool. Defaults to `block`.

  Remember that persistent connections to the server consume server-side resources, and therefore should be minimized if possible. To disable pooling altogether, set `MaxActive` to `0`.

- Database connectivity and JDBC-related properties are ignored by the client persistence manager factory. All database communication takes place on the server, so these properties are only valid on the server-side persistence manager factory. There are, however, two exceptions to this rule. If specified, the client will transfer your local `javax.jdo.option.ConnectionUserName` and `javax.jdo.option.ConnectionPassword` settings to the server. This allows different remote clients to connect as different database users.

Other than the bullet points above, you configure client persistence manager factories in the same way as local factories. Keep in mind, though, that the configuration you specify on the client only applies to the client factory, not the server. For example, if you configure a data cache and query cache on the client, these caches will only "see" changes made by the client; they will not automatically synchronize with changes made by any other client or changes made on the server. Thus, you will typically want to configure components like the data cache, query cache, lock manager, etc. on the server only (where clients can still benefit from them by proxy), and turn them off on the client.

Example 11.5. Client Configuration

    javax.jdo.PersistenceManagerFactoryClass: kodo.remote.ClientPersistenceManagerFactory
    javax.jdo.option.Multithreaded: false
    javax.jdo.option.Optimistic: true
    javax.jdo.option.NontransactionalRead: true
    javax.jdo.option.RetainValues: true

    kodo.LicenseKey: xxxx
    kodo.PersistenceManagerServer: tcp(Host=jdohost.mydomain.com, Port=5555)
    kodo.ConnectionRetainMode: transaction
    kodo.ConnectionFactoryProperties: MaxIdle=3, ValidationTimeout=60000

Example 11.6. HTTP Client Configuration

    javax.jdo.PersistenceManagerFactoryClass: kodo.remote.ClientPersistenceManagerFactory
    javax.jdo.option.Multithreaded: false
    javax.jdo.option.Optimistic: true
    javax.jdo.option.NontransactionalRead: true
    javax.jdo.option.RetainValues: true

    kodo.LicenseKey: xxxx
    kodo.PersistenceManagerServer: http(URL=http://jdohost.mydomain.com/tomcat/pmserver)
    kodo.ConnectionRetainMode: transaction
    kodo.ConnectionFactoryProperties: MaxIdle=3, ValidationTimeout=60000

### 11.2.4. Data Compression and Filtering

Kodo's built in transport implementations -- `tcp, http` -- allow you to wrap their data streams in decorators to add additional functionality such as data compression and filtering. Each accepts a `Decorators` configuration property specifying a semicolon-separated list of `com.solarmetric.remote.StreamDecorator`s to decorate the input and output streams between the client and server. Each item in the list can be the full class name of a custom decorator, or one of the following built-in aliases:

- `gzip`: Use gzip compression when transferring data.

Example 11.7. Enabling Compression with the TCP Transport

On the server:

    kodo.PersistenceManagerServer: tcp(Port=5555, Decorators=gzip)

On the client:

    kodo.PersistenceManagerServer: tcp(Host=jdohost.mydomain.com, Port=5555, Decorators=gzip)

Example 11.8. Enabling Compression with the HTTP Transport

In the server properties file / servlet configuration:

    kodo.PersistenceManagerServer: http(Decorators=gzip)

On the client:

    kodo.PersistenceManagerServer: http(URL=http://jdohost.mydomain.com/tomcat/pmserver, Decorators=gzip)

### 11.2.5. Remote Persistence Manager Deployment

Using Kodo's remote features involves deploying Kodo to the server machine as well as one or more client machines. Deploying Kodo on the server is exactly the same as deploying Kodo for local use. You must include all Kodo libraries, your configuration properties file (if you use one), your logging configuration file (again, if you use one), your JDBC drivers, your enhanced persistent classes, your metadata, and your O/R mapping information. All of these topics are covered in other sections of this manual.

Deploying Kodo on the client is also the same as deploying Kodo for local use, with two small exceptions:

1. JDBC libraries are not required on the client.

2. O/R mapping information is not required on the client.

Note that you may include the above information in your deployment; it is simply not required.

### 11.2.6. Remote Persistence Manager Transfer Listeners

The Kodo remote package provides a mechanism for your application to register an object that can listen for the transfer events. Transfer events take place during flush operations as objects are sent to the server, and when objects are loaded from the server by extents, queries, or obtaining objects by ID. For more details, please see the javadoc for `kodo.remote.RemoteTransferListener` .

Prev | Up | Next
Chapter 11. Remote and Offline JDO | Home | Chapter 12. Management and Monitoring