4 Replies Latest reply on Sep 28, 2012 10:02 AM by rhauch

    ModeShape 3 and programmatic infinispan/ModeShape configuration

    forcam

      Hi,

       

      is it possible to configure ModeShape programatically? I've created a infinispan configuration and now i want to use it with ModeShape but i found no way to tell ModeShape to use my inifinispan configuration.

      I've only find examples with json configuration files.

       

      Here is my infinispan configuration:

       

      // Verbindungsdaten aus dem Environment lesen ...
      final String  driverClassName = System.getenv("database.jdbc.driverClassName");
      final String  url = System.getenv("database.jdbc.url");
      final String  username = System.getenv("database.jdbc.username");
      final String  password = System.getenv("database.jdbc.password");
      final String  database = System.getenv("database.name");
      
      // ... und jetzt die Infinispan-Konfiguration aufbauen
      final ConfigurationBuilder builder = new ConfigurationBuilder();
      final Configuration con = builder.eviction().
              strategy(EvictionStrategy.LIRS).
              maxEntries(10).
           transaction().
              transactionManagerLookup(new DummyTransactionManagerLookup()).
              transactionMode(TransactionMode.TRANSACTIONAL).
              autoCommit(false).
              lockingMode(LockingMode.OPTIMISTIC).
          loaders().
              passivation(false).
              shared(false).
              preload(true).
          addCacheLoader().
              cacheLoader(new JdbcStringBasedCacheStore()).
                  purgeOnStartup(false).
                  fetchPersistentState(false).
                  ignoreModifications(false).
                  addProperty("connectionFactoryClass", "org.infinispan.loaders.jdbc.connectionfactory.PooledConnectionFactory").    // pooled -> c3p0
                  addProperty("connectionUrl", url).
                  addProperty("driverClass", driverClassName).
                  addProperty("databaseType", database).
                  addProperty("userName", username).
                  addProperty("password", password).
                  addProperty("bucketTableNamePrefix", "JCR_TABLE").
                  addProperty("idColumnName", "ID_COLUMN").
                  addProperty("idColumnType", "CHARACTER VARYING(255)").
                  addProperty("dataColumnName", "DATA_COLUMN").
                  addProperty("dataColumnType", "BYTEA").
                  addProperty("timestampColumnName", "TIMESTAMP_COLUMN").
                  addProperty("timestampColumnType", "BIGINT").
                  addProperty("dropTableOnExit", "true").
                  addProperty("createTableOnStart", "true").
      build();
      

       

      --------

      Peter

        • 1. Re: ModeShape 3 and programmatic infinispan/ModeShape configuration
          rhauch

          It is not currently possible to programmatically configure a ModeShape repository (feel free to log an enhancement request, which we'd probably target to 3.1).

           

          However, it IS possible to define a JSON configuration file for your ModeShape repository configuration and "inject" your Infinispan cache configuration. This is not really documented, but the key is to provide an org.modeshape.jcr.Environment implementation that knows about your Infinispan cache, and to supply this in the RepositoryConfiguration constructor or, if you obtain a RepositoryConfiguration object via one of the static methods to then call "with(Environment)" on the RepositoryConfiguration to get a new RepositoryConfiguration that uses your environment object.

           

          The easiest way to implement your own Environment is to extend the org.modeshape.jcr.LocalEnvironment class and override the "createDefaultConfiguration()" method to return your Configuration object. Your JSON file should not define a "cacheContainer" field.

           

          If you also want to defined an Infinispan GlobalConfiguration, the you should also override the "createGlobalConfiguration()" method in LocalEnvironment to return your instance.

           

          I've logged an enhancement to make it easier to inject your own Infinispan cache Configuration objects (see MODE-1649).

          • 2. Re: ModeShape 3 and programmatic infinispan/ModeShape configuration
            rhauch

            I would like to get your feedback on the changes I'm planning to make to allow applications to programmatically configure Infinispan caches.

             

            Rather than subclassing the LocalEnvironment class, you will be able to simply instantiate it and define a cache with your Infinispan Configuration instance:

             

            /* Define the cache configuration using Infinispan's API */

            Configuration cacheConfig = /* etc */

             

            /*

            Set up the environment in which the repository will run.

            Note that "cacheName" is the name of the cache specified in the JSON configuration

            */

            LocalEnvironment env = new LocalEnvironment();

            env.defineCache("cacheName",cacheConfig); // this is the new method!


            /*

            Set up the ModeShape repository configuration. We use a String here, and the string

            can be the path to the JSON file or the JSON content itself. But instead of a String

            we could use a java.io.File object or URL that resolves to the JSON file. */

            String json = /* etc */

            RepositoryConfiguration repoConfig = RepositoryConfiguration.read(json);

            repoConfig = repoConfig.with(env); // use our environment

             

            /* Use the RepositoryConfiguration to deploy a repository to a ModeShape engine */

            ModeShapeEngine engine = new ModeShapeEngine();

            engine.start();

            javax.jcr.Repository repo = engine.deploy(repoConfig);

             

            There are also methods for adding a programmatically-defined CacheContainer, too. For example, you might wish to programmatically instantiate a DefaultCacheContainer with all of the caches defined, along with global and default configurations. If that's the case, then rather than calling "defineCache(...)" above, simply add the container:

             

            CacheContainer container = /* define programmatically */

            LocalEnvironment env = new LocalEnvironment();

            env.addCacheContainer("containerName",container); // this is a new method!


            If you use this, then be sure to reference the cache container in the JSON configuration, via the "cacheContainer" field whose value should match the name of the container used when adding the container to the environment.

             

            I hope these new methods are useful. They will be available in all releases after Beta4.

            • 3. Re: ModeShape 3 and programmatic infinispan/ModeShape configuration
              forcam

              Hi,

               

              thanks for the answer. Now i use my own Environment (extended the class org.modeshape.jcr.LocalEnvironment) and my test use the programmatically created infinispan configuration.

               

              I would still add two methods to LocalEnvironment for adding a infinispan configuration:

               

              defineCache(String name, Configuration config) and defineDefaultCache(Configuration config).

              • 4. Re: ModeShape 3 and programmatic infinispan/ModeShape configuration
                rhauch

                The changes I made for MODE-1649 include a "defineCache(String name, Configuration config)" method (and several others), but I'll also add the "defineDefaultCache(...)" form. Great idea!

                 

                Update: Unfortunately, there's no way to (easily) alter the configuration of an already-used cache container, so adding a "defineDefaultCache(...)" won't work. I think the easiest way to control the default and global configurations is to simply set up your own CacheContainer instance (however you want) and then to tell the LocalEnvironment about it (see the code example above).