13 Replies Latest reply on May 16, 2013 5:40 AM by mgencur

    How to enable indexing?

    drathnow

      I'm trying to enable indexing on one of my Infinispan caches running inside JBoss AS7 but the only configuration documentation I can find refers to standalone configurations using XML and that appears to be much different than JBoss'.  I've read through the jboss-as-infinispan_1_2.xsd and have come up with the following that doesn't seem to create any problem when JBoss starts:

       

      <subsystem xmlns="urn:jboss:domain:infinispan:1.2" default-cache-container="hibernate">

                <cache-container name="request-cache" default-cache="request-cache">

              <local-cache name="control-request-cache" indexing="LOCAL">

                  <transaction mode="FULL_XA"/>

                  <store class="org.infinispan.loaders.file.FileCacheStore" preload="true" passivation="false" fetch-state="true" purge="false">

                       <property name="location">

                          ${java.io.tmpdir}

                      </property>

                  </store>

              </local-cache>

          </cache-container>

      </subsystem>

       

      But whenever I try to search the cache, I get the following error:

       

      java.lang.IllegalArgumentException: Indexing was not enabled on this cache. interface org.hibernate.search.spi.SearchFactoryIntegrator not found in registry

                at org.infinispan.query.impl.ComponentRegistryUtils.getComponent(ComponentRegistryUtils.java:40) [infinispan-query-5.1.4.FINAL.jar:5.1.4.FINAL]

                at org.infinispan.query.SearchManagerImpl.<init>(SearchManagerImpl.java:56) [infinispan-query-5.1.4.FINAL.jar:5.1.4.FINAL]

                at org.infinispan.query.Search.getSearchManager(Search.java:39) [infinispan-query-5.1.4.FINAL.jar:5.1.4.FINAL]

                at zedi.pacbridge.app.cache.InfinispanOutgoingRequestCache.outgoingRequestsForSiteAddress(InfinispanOutgoingRequestCache.java:56) [app-6.0.0.jar:]

      ....

       

      Can someone tell me if there is more confuguration I need to add? Is there somethig I've missed?

       

      Thanks

        • 1. Re: How to enable indexing?
          mgencur

          Hi Dave,

          your configuration looks good. This is how you enable indexing and say that you want to index local changes only (another option would be ALL (vs. LOCAL) - to allow also remote changes to be indexed). It looks like a classpath problem. How do you perform the search?

           

          Martin

          • 2. Re: How to enable indexing?
            drathnow

            Hi Martin,

             

            Thanks for the reply.  Here is the code I'm using to do the search:

             

                @Resource(mappedName="java:jboss/infinispan/container/pacbridge-control-request-cache")

                private static org.infinispan.manager.CacheContainer container; 

                private org.infinispan.Cache<String, OutgoingRequest> theCache;

                    ...

             

                public Collection<OutgoingRequest> outgoingRequestsForSiteAddress(SiteAddress siteAddress) {

                    SearchManager searchManager = Search.getSearchManager(theCache);

                    QueryBuilder queryBuilder = searchManager.buildQueryBuilderForClass(OutgoingRequest.class).get();

                    Query luceneQuery = queryBuilder

                                            .keyword()

                                            .onField("siteAddress")

                                            .matching(siteAddress)

                                            .createQuery();

                    CacheQuery query = searchManager.getQuery(luceneQuery, OutgoingRequest.class);

                    List<? extends Object> list = query.list();

                    return (Collection<OutgoingRequest>)list;

                }

             

             

             

            The objects that are stored in the cach implement an interface that looks like this:

             

            public interface OutgoingRequest {

                @Field

                public String getRequestId();

                @Field

                public Long getEventId();

                @Field

                @FieldBridge(impl = SiteAddressFieldBridge.class)

                public SiteAddress getSiteAddress();

            }

             

            public class SiteAddressFieldBridge implements StringBridge {

                    @Override

                public String objectToString(Object object) {

                    return object.toString();

                }

            }

            • 3. Re: How to enable indexing?
              mgencur

              Hi Dave,

              it does not look like a good way to work with queries and indexing in general. The JBossAS Infinispan subsystem is quite limited and does not even allow you to specify the kind of storage for indexes (ram, file system, Infinispan etc.). Furthermore, querying Infinispan needs Hibernate Search on the classpath and these libraries are not included in JBossAS distribution (in its submodules). You would basically need to add a new module to JBossAS with Hibernate Search dependencies, Infinspan query, Lucene and maybe some other. I haven't tried that and I think the JBossAS Infinispan subsystem was not designed for this purpose (querying). You would better use "library" mode and package all necesssary libraries with your application, and configure the cache through Infinispan's native configuration.

               

              Cheers

              Martin

              • 4. Re: How to enable indexing?
                mgencur

                A good example might be this one: https://github.com/qa/pv243/tree/master/lesson05-infinispan-updated/carmart 

                This was created not a long time ago and work nicely.

                • 5. Re: How to enable indexing?
                  drathnow

                  If I understand what you're saying, my code is okay but you would suggest I include all the necessary libraries with my application rather than rely on the ones supplied by JBoss.  Looking at the example, there isn't much difference between what I'm doing and what the example shows, as far as the code is concerned (Other than the fact that I missed the "@Indexed" annotation on the OutgoingRequest class.)

                   

                  If that's the case, then I'll try that.

                   

                  Thanks!

                   

                  P.S. Forgot to mention that I have to configure my cache programmatically!

                  • 6. Re: How to enable indexing?
                    drathnow

                    Martin,

                     

                    So changed my code to use "library" mode, essentially copying the code from the carmart example.  Now, whenever I try to query my cache, I get the following exception:

                     

                    Caused by: java.lang.IllegalArgumentException: HSEARCH000109: zedi.pacbridge.app.controls.OutgoingRequest is not an indexed type

                              at org.hibernate.search.impl.ImmutableSearchFactory.getSafeIndexBindingForEntity(ImmutableSearchFactory.java:346) [hibernate-search-engine-4.1.0.CR3.jar:4.1.0.CR3]

                              at org.hibernate.search.impl.ImmutableSearchFactory.getAnalyzer(ImmutableSearchFactory.java:248) [hibernate-search-engine-4.1.0.CR3.jar:4.1.0.CR3]

                              at org.hibernate.search.query.dsl.impl.ConnectedQueryContextBuilder$HSearchEntityContext.<init>(ConnectedQueryContextBuilder.java:55) [hibernate-search-engine-4.1.0.CR3.jar:4.1.0.CR3]

                              at org.hibernate.search.query.dsl.impl.ConnectedQueryContextBuilder.forEntity(ConnectedQueryContextBuilder.java:46) [hibernate-search-engine-4.1.0.CR3.jar:4.1.0.CR3]

                              at org.infinispan.query.SearchManagerImpl.buildQueryBuilderForClass(SearchManagerImpl.java:95) [infinispan-query-5.1.4.FINAL.jar:5.1.4.FINAL]

                              at zedi.pacbridge.app.cache.InfinispanOutgoingRequestCache.hasOutgoingRequests(InfinispanOutgoingRequestCache.java:83) [pacbridge-app-6.0.0.jar:]

                    . . .

                     

                    To try to solve this, I change the OutgoingRequest from an interface to a base class for my various request types.  The base class looks like this:

                     

                    @Indexed

                    public abstract class OutgoingRequest implements Serializable {

                        private static final long serialVersionUID = 1001L;

                       

                        @Field

                        private String requestId;

                        @Field

                        private Long eventId;

                        @Field

                        private Long creationTime;

                        @Field

                        @FieldBridge(impl = SiteAddressFieldBridge.class)

                        private SiteAddress siteAddress;

                     

                        public abstract OutgoingRequestProcessor outgoingRequestProcessor();

                        public abstract void incrementSendAttempts();

                        public abstract Integer sendAttempts();

                       

                        protected OutgoingRequest(SiteAddress siteAddress, Long eventId) {

                            this.eventId = eventId;

                            this.siteAddress = siteAddress;

                            this.creationTime = System.currentTimeMillis();

                            this.requestId = UUID.randomUUID().toString();

                        }

                     

                        public String getRequestId() {

                            return requestId;

                        }

                     

                        public Long getEventId() {

                            return eventId;

                        }

                     

                        public SiteAddress getSiteAddress() {

                            return siteAddress;

                        }

                    }

                     

                    And the concrete class, which I'm currently trying to store and retrieve looks like this:

                     

                     

                    @Indexed

                    public class ControlRequest extends OutgoingRequest implements Serializable {

                        private static final long serialVersionUID = 1001L;

                     

                        private List<Control> controls;

                        private int sendAttempts;

                        private Long creationTime;

                        private Long lastSendAttempt;

                        private String lastStatusMessage;

                     

                        public ControlRequest(SiteAddress siteAddress, Long eventId, List<Control> controls) {

                            super(siteAddress, eventId);

                            this.controls = controls;

                            this.controls = new ArrayList<Control>(controls);

                            this.creationTime = System.currentTimeMillis();

                        }

                     

                     

                        public void incrementSendAttempts() {

                            sendAttempts++;

                            lastSendAttempt = System.currentTimeMillis();

                        }

                       

                        @Override

                        public Integer sendAttempts() {

                            return sendAttempts;

                        }

                       

                        public Control[] getControls() {

                            return controls.toArray(new Control[controls.size()]);

                        }

                       

                        public Long getLastSendAttempt() {

                            return lastSendAttempt;

                        }

                       

                        public String getLastStatusMessage() {

                            return lastStatusMessage;

                        }

                       

                        public Long getCreationTime() {

                            return creationTime;

                        }

                       

                        public int getSendAttempts() {

                            return sendAttempts;

                        }

                     

                        @Override

                        public OutgoingRequestProcessor outgoingRequestProcessor() {

                         ...

                        }

                    }

                     

                     

                    So, any idea why this won't work?  Are there problems with the way I've defined my fields?

                     

                    Thanks.

                    • 7. Re: How to enable indexing?
                      mgencur

                      Hi Dave,

                      I'm not really sure what is causing the problem. However, you're using diferrent versions for Infinispan and Hibernate Search. I'm using ISPN 5.2.1. With your version, it is necessary to add at least @ProvidedId annotation to the class. Not sure what else. Maybe it's worth a try. My example works with ispn 5.2.1 and HS 4.2.0

                       

                      Martin

                      1 of 1 people found this helpful
                      • 8. Re: How to enable indexing?
                        drathnow

                        Okay, so upgraded to ISPN 5.2.1 but now I get the following whenever I try to access the cache:

                         

                        Caused by: java.lang.NullPointerException

                                  at org.infinispan.query.impl.LifecycleManager.cacheStarted(LifecycleManager.java:150) [infinispan-query-5.2.1.Final.jar:5.2.1.Final]

                                  at org.infinispan.factories.ComponentRegistry.start(ComponentRegistry.java:177) [infinispan-core-5.1.2.FINAL.jar:5.1.2.FINAL]

                                  at org.infinispan.CacheImpl.start(CacheImpl.java:499) [infinispan-core-5.1.2.FINAL.jar:5.1.2.FINAL]

                                  at org.infinispan.manager.DefaultCacheManager.createCache(DefaultCacheManager.java:626) [infinispan-core-5.1.2.FINAL.jar:5.1.2.FINAL]

                                  at org.infinispan.manager.DefaultCacheManager.getCache(DefaultCacheManager.java:516) [infinispan-core-5.1.2.FINAL.jar:5.1.2.FINAL]

                                  at zedi.pacbridge.app.cache.InfinispanOutgoingRequestCache.start(InfinispanOutgoingRequestCache.java:42) [pacbridge-app-6.0.0.jar:]

                             ...

                         

                        My configuraiton code looks like this:

                         

                            void startup() {

                                GlobalConfiguration glob = new GlobalConfigurationBuilder()

                                    .nonClusteredDefault().globalJmxStatistics().enable()

                                    .jmxDomain("zedi.pacbridge.app")

                                    .build();

                               

                                Configuration defaultConfig = new ConfigurationBuilder()

                                    .transaction()

                                    .transactionMode(TransactionMode.TRANSACTIONAL)

                                    .build();  //default config

                               

                                Configuration requestCacheConfig = new ConfigurationBuilder()

                                    .jmxStatistics()

                                        .enable()

                                    .clustering()

                                        .cacheMode(CacheMode.LOCAL)

                                    .transaction()

                                        .transactionMode(TransactionMode.TRANSACTIONAL)

                                        .autoCommit(false)

                                        .lockingMode(LockingMode.OPTIMISTIC)

                                        .transactionManagerLookup(new GenericTransactionManagerLookup())

                                    .locking()

                                        .isolationLevel(IsolationLevel.REPEATABLE_READ)

                                    .eviction()

                                        .maxEntries(100)

                                        .strategy(EvictionStrategy.LRU)

                                    .loaders()

                                    .passivation(true)

                                        .addFileCacheStore()

                                    .indexing()

                                        .enable()

                                        .addProperty("default.directory_provider", "ram")

                                    .build();

                               

                                manager = new DefaultCacheManager(glob, defaultConfig);

                                ((DefaultCacheManager) manager).defineConfiguration(OutgoingRequestCache.CACHE_NAME, requestCacheConfig);

                                manager.start();

                            }

                         

                         

                        Thoughts?

                        • 9. Re: How to enable indexing?
                          mgencur

                          You're still using infinispan-core v5.1.2. I'm not sure if this is compatible with infinispan-query 5.2.1. It would make sense to change the core library to 5.2.1 too. No other thoughts.

                          1 of 1 people found this helpful
                          • 10. Re: How to enable indexing?
                            drathnow

                            Hi Martin,

                             

                            I've been away for a couple of weeks and have just gotten back to this.

                             

                            Both infinispan-core-5.2.1.FINAL.jar and infinispan-query-5.2.1.FINAL.jar are in my ear's "/lib" folder but when I deploy my app, JBoss picks up the wrong infinispan-query jar.  The only place it could be coming from is from JBoss' submodules.   infinispan-core-5.1.2.FINAL.jar is under <JBOSS_HOME>/modules/org/infinispan...

                             

                            I've looked at the carmart sample and it simply puts the jar files under the war's WEB-INF/lib folder.  Is there something else that needs to be done so that JBoss will pick up the inifinispan-core-5.2.1.FINAL.jar from the ear's lib folder?


                            Dave.

                            • 11. Re: How to enable indexing?
                              mgencur

                              Hi Dave,

                              what you describe is quite strange. IMO this shouldn't happen unless you use "Dependencies: ..." entry in your Manifest.mf. Read https://docs.jboss.org/author/display/AS72/Class+Loading+in+AS7 for more information. It might help you to get it to run.

                               

                              Martin

                              • 12. Re: How to enable indexing?
                                drathnow

                                Hi Martin,

                                 

                                I finally got it working and, as you said, everything looked okay.  The problems were buried in my maven build scripts.  Once I sorted out a couple of problems with dependencies and coerced the correct versions of hibernate-search and infinispan jar files into my ear, things started working...sort of.  Whenever I tried to search on my OutgoingRequest abstract class I kept getting the exception "OutgoingRequest is not an indexed type".  So, I created another concrete class and was able to get searches to work using that class.

                                 

                                I'll have to dig into Hibernate search a bit to figure out how to fix the problem with searching for my abstract class but as far as the Infinispan problem go, they appear to be fixed.

                                 

                                Many thanks for your help,

                                Dave.

                                • 13. Re: How to enable indexing?
                                  mgencur

                                  Hi Dave, I'm glad you solved it :-)

                                   

                                  Martin