13 Replies Latest reply on Sep 13, 2010 10:15 AM by rhauch

    Custom node types and inifinispan connector

    craigching

      Ok, so I've moved on from my other problem with custom node types and am commencing with using the infinispan connector.  What I'm seeing is that the first time I run the code (full maven code and modeshape/infinispan configuration attached), everything appears to work fine.  I can see that "car" is in the repository namespace prefixes.  For instance, this is the output I see when printing the namespace prefixes:

       

      Prefix: xmlns

      Prefix:

      Prefix: modeint

      Prefix: mode

      Prefix: xs

      Prefix: xsi

      Prefix: jcr

      Prefix: mix

      Prefix: sv

      Prefix: car

      Prefix: nt

      Prefix: xml

       

      The next time I run, I see the following namespace prefixes:

       

      Prefix: xmlns

      Prefix:

      Prefix: modeint

      Prefix: mode

      Prefix: xs

      Prefix: xsi

      Prefix: jcr

      Prefix: mix

      Prefix: sv

      Prefix: ns001

      Prefix: nt

      Prefix: xml

       

      The 'ns001' is suspect, I think it's probably meant to be 'car' but isn't for some reason.  I also get the following exception stack trace:

       

      javax.jcr.RepositoryException: The "primaryNodeTypeName" parameter value "car:Car" was not a valid node type name

      at org.modeshape.jcr.AbstractJcrNode.addNode(AbstractJcrNode.java:1453)

      at org.modeshape.jcr.AbstractJcrNode.addNode(AbstractJcrNode.java:1356)

      at net.webasap.modeshape.InfinispanJcrRepository.main(InfinispanJcrRepository.java:89)

       

      Here is the relevant code for illustration, but, as I said, it's attached too:

       

                      session = repo.login();

                      registerNodeTypes("cars.cnd", session);

                      String [] prefixes = session.getNamespacePrefixes();

                      for (String prefix : prefixes) {

                          System.out.println("Prefix: " + prefix);

                      }

                      Node root = session.getRootNode();

                      Node type = root.addNode("Hybrid", "nt:unstructured");

                      for(int i = 0; i < 10; ++i) {

                          Node car = type.addNode("car_" + i, "car:Car");

                          car.setProperty("car:maker", "Volkswagen");

                          car.setProperty("car:model", "Passat");

                          car.setProperty("car:year", "2010");

                          car.setProperty("car:msrp", "$32,000");

                      }

                      session.save();

       

      So, am I doing something wrong?  Or am I running into defects in modeshape or infinispan?  Any help appreciated!

        • 1. Re: Custom node types and inifinispan connector
          rhauch

          I think there are several things that are not configured correctly.

           

          First, as mentioned on the other thread, all CND files specified in the configuration file are currently expected to be on the classpath, so your "cars.cnd" file needs to be moved accordingly (e.g., in a "src/main/resources" folder or the existing the "src/main/java" folder).

           

          Second, your "infinispan-jcr-config.xml" file uses a wrong XML prefix when specifying the node types. It is this:

           

          <mode:nodeTypes mode:resource="/cars.cnd" />

           

          but should be this:

           

          <jcr:nodeTypes mode:resource="/cars.cnd" />

           

           

          Once these two issues are corrected, you don't need to programmatically register your node types. In fact, doing so is just extra work.

           

          Finally, the reason the "cars" namespace is getting a different prefix upon subsequent program starts is because of the way ModeShape handles the "/jcr:system" branch. Because the "/jcr:system" branch is shared amongst all workspaces in a repository, ModeShape uses a separate workspace for this system content, and this workspace is federated into each of the "real" workspaces. If you do not specify where this system workspace is to be stored, ModeShape creates and uses an in-memory repository source. Thus, all this system information (including custom namespace registrations) is lost when the program terminates. When your program is run again and ModeShape access the content persisted in Infinispan (or any other persistent store), it comes across content that uses the "http://www.modeshape.org/examples/cars/1.0" namespace. This namespace isn't registered (since the system information was transient), so it creates a new prefix called "ns001".

           

          You can correct this several ways.

           

          1) You could programmatically ensure the custom namespaces are already registered, but that's kind of bogus and doesn't handle any dynamically-registered namespaces.

           

          2) You could correct this by specifying the custom namespaces in your configuration file. This actually works great if you want to ensure that your application's namespaces always use particular namespace prefixes, but it doesn't handle any namespaces registered dynamically. To do this, include this kind of fragment as a child of the appropriate "mode:repository" element:

           

          <mode:namespaces>

              <mode:namespace jcr:name="car" mode:uri="http://www.modeshape.org/examples/cars/1.0"/>

          </mode:namespaces>

           

          3) The best way to deal with this is actually to tell ModeShape where to persist the "/jcr:system" branch. For details, see Section 8.2 in the Reference Guide that talks about defining the SYSTEM_WORKSPACE_NAME for your repository. I'd suggest pre-defining a second workspace in Infinispan (called "jcr:system"). This will definitely persist all non-standard namespace registrations, and is actually required if you want to use versioning or clustering (see the warnings here, here, and here).

           

          I hope this helps!

           

          Best regards,

           

          Randall

          • 2. Re: Custom node types and inifinispan connector
            rhauch

            BTW, I was able to make the changes I described above (moving the CND file onto the classpath, changing the configuration file to correctly reference the CND file, and each of the 3 options for the system workspace), and in each case was able to successfully run your program multiple times. Let me know if my suggestions above were not clear.

            • 3. Re: Custom node types and inifinispan connector
              craigching

              Randall, thanks so much for your help!  Your explanation makes sense.  So, I've tried to alter the repository configuration as you suggested (adding a system workspace), but I'm getting the following exception:

               

              Exception in thread "main" java.lang.IllegalArgumentException: No enum const class org.modeshape.jcr.JcrRepository$Option.SYSTEM_WORKSPACE_NAME

              at java.lang.Enum.valueOf(Enum.java:196)

              at org.modeshape.jcr.JcrRepository$Option.valueOf(JcrRepository.java:155)

              at org.modeshape.jcr.JcrRepository$Option.findOption(JcrRepository.java:289)

              at org.modeshape.jcr.JcrEngine.doCreateJcrRepository(JcrEngine.java:262)

              at org.modeshape.jcr.JcrEngine.getRepository(JcrEngine.java:209)

              at org.modeshape.jcr.JcrEngine.getRepository(JcrEngine.java:76)

              at org.modeshape.jcr.JcrRepositoryFactory.getRepository(JcrRepositoryFactory.java:153)

              at net.webasap.modeshape.InfinispanJcrRepository.main(InfinispanJcrRepository.java:67)

               

              Here is my altered configuration (and I've added cars.cnd to the classpath as well):


              <?xml version="1.0" encoding="UTF-8"?>

               

              <configuration xmlns:mode="http://www.modeshape.org/1.0"

              xmlns:jcr="http://www.jcp.org/jcr/1.0">

               

              <mode:sources jcr:primaryType="nt:unstructured">

               

              <mode:source jcr:name="CarStore"

              mode:classname="org.modeshape.connector.infinispan.InfinispanSource"

              mode:description="Cars repository"

              mode:defaultworkspaceName="cars"

              mode:cacheConfigurationName="repl-cache.xml"

              mode:updatesAllowed="true">

                    <mode:predefinedWorkspaceNames>cars</mode:predefinedWorkspaceNames>   

                         <mode:predefinedWorkspaceNames>system</mode:predefinedWorkspaceNames>   

              </mode:source>

               

              </mode:sources>

               

                  <mode:repositories>

                      <mode:repository jcr:name="Cars">

                          <!-- Specify the source that should be used for the repository -->

                          <mode:source>CarStore</mode:source>

                          <!-- Define the options for the JCR repository, using camelcase version of JcrRepository.Option names -->

                          <mode:options jcr:primaryType="mode:options">

                              <jaasLoginConfigName jcr:primaryType="mode:option" mode:value="modeshape-jcr"/>

              <systemWorkspaceName jcr:primaryType="mode:option" mode:value="system@CarStore"/>

                          </mode:options>

                          <!-- Define any custom node types. Importing CND files via JcrConfiguration is equivalent to specifying here. -->

                          <jcr:nodeTypes mode:resource="/cars.cnd" />

                          <!-- Define any namespaces for this repository, other than those already defined by JCR or ModeShape -->

                      </mode:repository>

                  </mode:repositories>

               

              </configuration>

               

              • 4. Re: Custom node types and inifinispan connector
                craigching

                It looks like <systemWorkspaceName> should be <systemSourceName>, so the documentation is wrong if so.  (I can't find SYSTEM_WORKSPACE_NAME in JcrRepository.Options either, so that really can't be right).

                 

                So, making that change, I run it once and fine.  The second time I run it, though, I get the following:

                 

                2010-09-09 11:06:59,780 DEBUG [main] (Logger.java:214) - Could not load repository named 'Cars'

                javax.jcr.RepositoryException: There is no repository named "Cars"

                at org.modeshape.jcr.JcrEngine.getRepository(JcrEngine.java:213)

                at org.modeshape.jcr.JcrEngine.getRepository(JcrEngine.java:76)

                at org.modeshape.jcr.JcrRepositoryFactory.getRepository(JcrRepositoryFactory.java:153)

                at net.webasap.modeshape.InfinispanJcrRepository.main(InfinispanJcrRepository.java:67)

                 

                There certainly *should* be a repository named Cars.  I'll keep digging ...

                • 5. Re: Custom node types and inifinispan connector
                  rhauch

                  You're right - the "SYSTEM_WORKSPACE_NAME" option should be "SYSTEM_SOURCE_NAME". I've logged MODE-894 to update the docs.

                   

                  Also, I went back an reran your program with the change to use a "system" workspace in Infinispan, and I also got the error when running a second time. After a bit of investigation, I found the issue was in a base class used by the Infinispan connector. I've logged this as MODE-893. I already have a fix implemented and tested locally (and your program successfully runs multiple times), and will commit to SVN shortly. I will attach the changes as a patch to the issue, which you can grab to patch the JARs -- or you can download trunk and build locally.

                   

                  Thanks for your patience and diligence working through these issues!

                  • 6. Re: Custom node types and inifinispan connector
                    craigching

                    Thanks so much for your help Randall!  I'll definitely give your changes a whorl, just let me know when they're committed.


                    FYI, I've excluded the infinispan 4.0.0.FINAL transitive artifacts that the modeshape infinispan connector relies on and replaced them with 4.1.0.CR3 (and I'll change that to final once infinispan 4.1.0.FINAL hits the maven repository).  Any chance the next version of the ModeShape infinispan connector would change it's dependencies to 4.1.0.FINAL as well?  We're about to do some performance testing as a proof-of-concept for using mode shape over infinispan and would like to use the newer version of infinispan if at all possible.

                    • 7. Re: Custom node types and inifinispan connector
                      rhauch

                      I'm running a full build locally, and if all goes well I should be committed the fix in about 20 minutes. After that happens, I'll be sure to update this thread.

                       

                      We will be changing to Infinispan 4.1.0.FINAL before the 2.3 release; see MODE-881. Right now, the roadmap has 2.3 coming out in the middle of October, but I honestly believe it will be around the end of Sept.

                       

                      BTW, Infinispan 4.1.0.FINAL is already in the JBoss Maven repository (see for instance http://repository.jboss.org/nexus/content/groups/public-jboss/org/infinispan/infinispan-core/4.1.0.FINAL/).

                      • 8. Re: Custom node types and inifinispan connector
                        craigching

                        Excellent, that is perfect timing for us, we'll keep you posted of any problems we run into with our tests.  As for Infinispan final being in maven, I swear it wasn't last night ;-) I'll check it out, thanks for the heads up!

                        • 9. Re: Custom node types and inifinispan connector
                          rhauch

                          Sounds great. Are you interested in the RemoteCacheManager functionality in Infinispan 4.1.0.FINAL? If so, then MODE-758 may be of interest. Let me know (and vote it up) if it is; it's currently scheduled for 2.3, but I could get it in relatively quickly if you wanted to help test it out prior to the 2.3 release.

                          • 10. Re: Custom node types and inifinispan connector
                            craigching

                            I don't think so, we're running our infinispan caches in replication mode inside of our web containers of which there will almost always be a fixed number.  If I understand that, that would be for talking to remote caches so that you aren't having to eat the cost of rebalancing/synching when a new node starts up.  Certainly interesting and probably it would be for us down the road, but not yet.  Thanks for pointing it out though, I'll keep it in mind!

                            • 11. Re: Custom node types and inifinispan connector
                              rhauch

                              I've logged MODE-894 to update the docs.

                              ...

                              I've logged this as MODE-893

                               

                              Both of these issues have been fixed in SVN (trunk), and both fixes will be in the next release (2.3). I'm now able to successfully run your program multiple times, and each time it adds more 'car:Car' nodes.  I've marked both issues as resolved, but if it turns out the fixes are not correct or are insufficient, please feel free to reopen them (or ask here if you have questions).

                               

                              Also, in case it helps, I've attached my version of your project to MODE-893.

                               

                              Best regards.

                              • 12. Re: Custom node types and inifinispan connector
                                craigching

                                Thanks Randall, I have it built and can verify that it's working in my environment now.  I really appreciate the help with this, we can get on with our proof of concept now!

                                 

                                EDIT:  I'll mention also that I verified it with 2.3-SNAPSHOT.

                                • 13. Re: Custom node types and inifinispan connector
                                  rhauch

                                  Craig Ching wrote:

                                   

                                  Thanks Randall, I have it built and can verify that it's working in my environment now.  I really appreciate the help with this, we can get on with our proof of concept now!

                                   

                                  EDIT:  I'll mention also that I verified it with 2.3-SNAPSHOT.

                                   

                                  Excellent. Glad it's working for you now.