5 Replies Latest reply on Mar 9, 2016 10:21 AM by nadirx

    Creating new Infinispan 8 configuration

    gregosby

      I have one Infinispan 8 configuration file, two jgroups files, custom tree cache provider (two spring beans that initilizes car and user cache respectively), I cant start the applicatio. I am reading Infinispan 8 user guide and I am bit confused.

       

      I also put some comments in code as I don't know if the implementation is ok or missing something. I dont know, if I did it properly - I want to have different caches like below - cars and users. Both caches have different UDP multicast addresses so I  creatd different jgroups files, but maybe there is some way to parametrize it like ${multicast_address} I see ${nodeName} in Infinispan examplpes but there s nothing about where to put value for such parameter.

       

      I also not sure, whether my treecache provider class is implemented ok, so that it work in clustered cache and start / stop properly and use transactions.

       

      I also see error putting multiple transport stacks, so how should it look like if I have multiple stack files?

       

          <transport stack="cars_file" node-name="${nodeName}" />
          <transport stack="user_file" node-name="${nodeName}" />
      

       

      **Spring bean which is CacheProvider and reads Infinispan config file:**

       

      public class InfinispanCarsCacheProvider implements InitializingBean, DisposableBean {     
              private TreeCache tree;
               
              private String configurationFile = null;
            
              public void afterPropertiesSet() throws Exception {
                  
                  try {
                      Assert.argNotNull("configurationFile", this.getConfigurationFile());
           
                      EmbeddedCacheManager cm = new DefaultCacheManager(this.getConfigurationFile());
                      Cache<String, String> cache = cm.getCache("carsCache"); 
                      TreeCacheFactory tcf = new TreeCacheFactory();
                      tree = tcf.createTreeCache(cache);
                      ///tree.createService();
                      ///tree.startService(); 
                      tree.start();
           
                  }
                 
              }
               
              public void destroy() throws Exception {
                   
                  tree.stop(); 
          
                  //ANY OTHER THINGS TO DO HERE?
          
                /**  try {
                      Field field = PropertyEditorManager.class.getDeclaredField("registry");
                      field.setAccessible(true);
                      Hashtable table = (Hashtable) field.get(null);
                      for( Object obj : table.keySet() ){
                          String name = ((Class<?>)table.get(obj)).getName();
                          if(name.contains("org.jboss.util.propertyeditor")){
                              LOGGER.info("Removing property editor: " + name);
                              table.remove(obj);
                          }
                      }
                  } catch ( Exception e ) {
                      LOGGER.warn("Cannot unregister property editors", e);
                  }
                  LOGGER.info("Cache destroyed.");***/
              }
             
              public boolean putObject(String[] entryKey, String objectKey, Object value) {
                  
                  boolean result;
                  try {
          
                      Object prevObject = tree.put( Fqn.fromList(Arrays.asList(entryKey)), objectKey, value);
                      result = prevObject != null;
                      
                  } catch (CacheException e) {
                      String msg = "Error putting " + getParamDescription(entryKey, objectKey, value);
                     
                      throw new SystemException(msg + e, e);
                  } finally {
                      //tree.setInvocationContext(null);
                  }
                  return result;
              }
          
              private String getParamDescription ( String[] entryKey , String objectKey , Object value ) {
                  return "[entryKey ='" + StringUtils.join(entryKey,",") + "', objectKey='" + objectKey + "', value ='" + value + "']";
              }
          
              public void removeObject ( String[] entryKey , String key ) {
                 
                  try {
                      tree.remove(Fqn.fromList(Arrays.asList(entryKey)), key);
                  } catch (CacheException e) {
                      String msg = "Error removing object [entryKey='" + StringUtils.join(entryKey,",") + "' key='" + key + "']";
                    
                      throw new SystemException(msg + e, e);
                  } finally {
                   // tree.setInvocationContext(null);
                  }
                  
              }
          
              public void removeNode(String[] entryKey) {
                  
                  try {
                      tree.removeNode(Fqn.fromList(Arrays.asList(entryKey)));
                  } catch (CacheException e) {
                      String msg = "Error removing node [entryKey='" + StringUtils.join(entryKey,",") + "']";
                      
                      throw new SystemException(msg + e, e);
                  } finally {
                      // tree.setInvocationContext(null);
                  }
                }
              
              public Object getObject(String[] entryKey, String objectKey) {
                  
                  Object object;
                  try {
                      object = tree.get(Fqn.fromList(Arrays.asList(entryKey)), objectKey);
                  } catch (CacheException e) {
                      String msg = "Error getting object " +  LOGGER.error(msg + e, e);
                      throw new SystemException(msg + e, e);
                  } finally {
                      // tree.setInvocationContext(null);
                  }
                  
                  return object;
              }
              
              public Map getAllObjects(String[] entryKey) {
                  
                  Map object = Collections.emptyMap();
                  try {
                      Node node = tree.getNode(Fqn.fromList(Arrays.asList(entryKey)));
                      
                      if (node != null) {
                          object = node.getData();
                      }
                  } catch (CacheException e) {
                      String msg = "Error getting object " + getParamDescription(entryKey, null, null);
                      
                      throw new SystemException(msg + e, e);
                  } finally {
                      // tree.setInvocationContext(null);
                  }
                  
                  return object;
              }
          
             public String getConfigurationFile () {
                  return configurationFile;
              }
          
              /**
               * @param configurationFile Ustawia wartość configurationFile.
               */
              public void setConfigurationFile ( String configurationFile ) {
                  this.configurationFile = configurationFile;
              }
          
            }
      

       

       

      **Below is Infinispan config:**

       

       

      <?xml version="1.0" encoding="UTF-8"?>
          
          <infinispan
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="urn:infinispan:config:8.0 http://www.infinispan.org/schemas/infinispan-config-8.0.xsd"
                  xmlns="urn:infinispan:config:8.0">
          
              <jgroups>
                  <stack-file name="cars_file" path="cars_jgroups.xml" /> <!-- separate jgroups - different multicast addresses -->
                  <stack-file name="users_file" path="users_jgroups.xml" />
           
              </jgroups>
          
              <cache-container default-cache="carsCache">  
                  <transport stack="cars_file" node-name="${nodeName}" /><!-- what is nodeName, where is value of this parameter, when this will be replaced?? -->
              
                  <invalidation-cache name="carsCache" configuration="invalidation-template" />
                  <invalidation-cache name="usersCache" configuration="invalidation-template" />
               
                  <!--</namedCache>-->
                  <invalidation-cache-configuration name="invalidation-template" mode="ASYNC" queue-flush-interval="10" queue-size="1000" start="LAZY" statistics="true">
                      <locking acquire-timeout="30500" concurrency-level="2500" isolation="READ_COMMITTED" striping="true"/>
                      <transaction mode="BATCH" stop-timeout="60500"  locking="OPTIMISTIC"/>
                      <eviction max-entries="20500" strategy="LRU"/>
                      <expiration interval="10500" lifespan="11" max-idle="11"/>
                  </invalidation-cache-configuration>
          
                   </cache-container>
          
               </infinispan>
      
      
        • 1. Re: Creating new Infinispan 8 configuration
          nadirx

          The relationship is [1 container]:[1 transport], and the embedded configuration only allows a single container, so you'd need to split this into two infinispan xml files. However...

          Why do you need / want two separate transports ?

           

          Tristan

          • 2. Re: Creating new Infinispan 8 configuration
            gregosby

            I thought it would be good approach to have two jgroups files (separate multicast addresses) because I would have separate TreeCache objects for cars and other one for users. Assuming I had one jgroups file - who would dispatch messages to proper TreeCache instance? So that put/remove etc would perform operations on correct TreeCache instance - all messages would be on the same multicast address and port... Would I have cars and persons on the same TreeCache instance? What is the best approach ?

             

            See also how my TreeCacheProvider inits (code above, it starts with Spring context), it starts with specified infinispan.xml file..

             

            On the other hand.. one cache-container can have multiple caches with different settings, so it could fit my usecase but still, I would have only one TreeCache instance so I would have to pay attention to duplicate cache keys from different business domain (cars, person) - what is the best approach?

             

            If I had one infinispan file and one jgroups file and two caches - cars and person, I could initilize my Spring bean holding treecache like this (again - what is the best approach?):

             

            public void afterPropertiesSet() throws Exception { 
                         
                        try { 
                            Assert.argNotNull("configurationFile", this.getConfigurationFile()); 
                  
                            EmbeddedCacheManager cm = new DefaultCacheManager(this.getConfigurationFile()); 
                            Cache<String, String> cache = cm.getCache("carsCache");  
                            TreeCacheFactory tcf = new TreeCacheFactory(); 
                            carsCacheTree = tcf.createTreeCache(cache); 
                             carsCacheTree.start(); 
            
                        //what about other caches??
                            cache = cm.getCache("personCache"); 
                    tcf = new TreeCacheFactory(); 
                            tree2 = tcf.createTreeCache(cache); 
                            tree2.start();     
                        } 
              } 
            
            • 3. Re: Creating new Infinispan 8 configuration
              nadirx

              The transport (i.e. jgroups configuration) can be shared among multiple caches. We have users with thousands of caches on a single transport, so you should not worry about it. Also, have you looked into infinispan-spring ? While it  doesn't automatically create a tree cache, you can certainly use it as a base for one.

               

              Tristan

              • 4. Re: Creating new Infinispan 8 configuration
                gregosby

                Thanks for the hint as for spring integration I will think about it. Propably I would like to be independent from Spring. I could use Spring to instantiate cache only, that is use spring bean initialization process to setup cache instances so that my new cache module would work in other projects without Spring easily.

                When integrating with Spring I would have one Treecache for carsCache and personCache or two separate TreeCache instances for each cache? As for my code above, is it ok, that I create separate treeCaches for each cache name ? Also, since it is clustered cache, do I stop it and initialize it properly?

                • 5. Re: Creating new Infinispan 8 configuration
                  nadirx

                  If you don't need spring, also look into our CDI bindings.

                  As for the caches, it is best if you use a cache per entity, so in this case one for cars and one for persons. Everything else looks good.