4 Replies Latest reply on Apr 6, 2013 2:25 AM by mashtun

    Problem getting the binary value from a federated node

    mashtun

      ModeShape & JCR newbie here...

       

      I've spent some time reading the documentation, playing with the code examples and browsing the source code, and have been able to modify one of the examples to use federation to project a view of an external filesystem.  I can successfully use the JCR API to find nodes representing the directories and files in my external data but I've so far been unsuccessful in getting the content of a file.  It seems that Binary.getStream() doesn't try to obtain the stream from the FileSystemConnector that's pointing to my external data.  I'm struggling to figure out what's wrong but expect I've made a configuration error.

       

      I'm using 3.1.3 Final and my current configuration is more or less taken from the test code in modeshape-jcr on github.

       

      My repository config :

       

      {
          "name" : "Federated repository",
          "workspaces" : {
              "predefined" : ["ws1", "ws2"],
              "default" : "default",
              "allowCreation" : true,
              "initialContent" : {
                  "default" : "initialContent.xml"
              }
          },
          "externalSources" : {
              "ptdata" : {
                  "classname" : "org.modeshape.connector.filesystem.FileSystemConnector",
                  "directoryPath" : "/var/local/ptdata",
                  "extraPropertiesStorage" : "json",
                  "readonly" : true,
                  "projections" : [ "default:/federated/ptdata => /" ]
              }
          },
          "security" : {
              "anonymous" : {
                  "roles" : ["readonly","readwrite","admin"],
                  "useOnFailedLogin" : false
              }
          },
          "storage" : {
              "cacheName" : "persistentRepository",
              "cacheConfiguration" : "infinispan-federation-persistent.xml"
          },
          "query" : {
              "indexing" : {
                  "rebuildOnStartup" : {
                      "when" : "never"
                  }
              }
          }
      }
      
      

       

      My initialContent.xml :

       

      <?xml version="1.0" encoding="UTF-8"?>
      <jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0">
          <federated />
      </jcr:root>
      
      

       

      My infinispan-federation-persistent.xml :

       

      <?xml version="1.0" encoding="UTF-8"?>
      <infinispan
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="urn:infinispan:config:5.1 http://www.infinispan.org/schemas/infinispan-config-5.1.xsd"
        xmlns="urn:infinispan:config:5.1">
      
      
          <global>
              <globalJmxStatistics enabled="false" allowDuplicateDomains="true" />
          </global>
      
      
          <namedCache name="persistentRepository">
              <transaction
                transactionManagerLookupClass="org.infinispan.transaction.lookup.GenericTransactionManagerLookup"
                transactionMode="TRANSACTIONAL"
                lockingMode="OPTIMISTIC" />
              <loaders
                passivation="false"
                shared="false"
                preload="false">
                  <loader
                    class="org.infinispan.loaders.file.FileCacheStore"
                    fetchPersistentState="false"
                    purgeOnStartup="false">
                      <properties>
                          <property name="location" value="target/federation_persistent_repository/store" />
                      </properties>
                  </loader>
              </loaders>
          </namedCache>
      </infinispan>
      
      

       

      I can find the node representing an XML file within my external data :

       

            final Node n = root.getNode("federated/ptdata/userdomains/user/m1ka40hepwd93n-lkh/m1ka40hepwd93n-lkh.xml");
      

       

      and if I dump its properties they look correct :

       

      jcr:primaryType=nt:file
      jcr:created=2013-03-25T17:16:48.000Z
      

       

      If I call getNode("jcr:content") on the node then I see FileSystemConnector create a UrlBinaryValue that has the correct SHA1 checksum and file URL for the external XML file.

       

      If I call getProperty("jcr:data").getBinary() on the content node then I get back a StoredBinaryValue associated with a TransientBinaryStore that's pointing to "/tmp/modeshape-binary-store".  Calling getStream() on this Binary results in an exception :

       

      org.modeshape.jcr.value.binary.BinaryStoreException: Unable to find binary value with key "ccd29c40fcf902bf250a07fb76462ab75d893b54" within binary store at "/tmp/modeshape-binary-store"
                at org.modeshape.jcr.value.binary.FileSystemBinaryStore.getInputStream(FileSystemBinaryStore.java:255)
                at org.modeshape.jcr.value.binary.StoredBinaryValue.getStream(StoredBinaryValue.java:63)
              ...<my code>
      

       

      I'm not sure if the TransientBinaryStore pointing at "/tmp/modeshape-binary-store" is expected or not.  I guess I was expecting something related to the FileSystemConnector and the external filesystem.

       

      Any help with figuring out where I'm going wrong would be appreciated.

        • 1. Re: Problem getting the binary value from a federated node
          mashtun

          The problem (if indeed there is a problem and it's not simply user error) is the length of the external file I'm trying to read relative to the "minimumBinarySizeInBytes" property in the (missing) "binaryStorage" property of my repository config.  If I change the existing "storage" property to this :

           

              "storage" : {
                  "cacheName" : "persistentRepository",
                  "cacheConfiguration" : "infinispan-federation-persistent.xml",
                  "binaryStorage" : {
                      "type" : "transient",
                      "minimumBinarySizeInBytes" : 0
                  }
              },
          

           

          (by adding the "binaryStorage" property) then I get a stream from the Binary object and no exception is thrown.  Logging into the repository - repository.login("default") - takes significantly longer (several seconds), presumably because the content of the external files is being cached?  Is this expected or should the stream come from the external file rather than from the internal binary store?

           

          What's the reason a UrlBinaryValue is created with a size equal to the total partition size rather than simply the file size?

          • 2. Re: Problem getting the binary value from a federated node
            rhauch

            Hmm... I think there are a couple of issues.

             

            1. The size of the UriBinaryValue should be created with the file size, not the partition size.
            2. The "minimumBinarySizeInBytes" should not affect the connectors.

             

            Could you log a bug in our JIRA? If so, we'll take a look (hopefully today).

            • 3. Re: Problem getting the binary value from a federated node
              mashtun

              MODE-1882 created - thanks for taking a look!

              • 4. Re: Problem getting the binary value from a federated node
                mashtun

                Randall Hauch wrote:

                 

                Could you log a bug in our JIRA? If so, we'll take a look (hopefully today).

                 

                The changes fix the problem I was seeing - thanks, Randall!