4 Replies Latest reply on Sep 6, 2016 2:58 AM by Thomas Newman

    Custom BinaryStore deployed as jboss-module

    Thomas Newman Newbie

      Hello,

       

      I have checked these forums and google/stackoverflow.

       

      I can't find a <pre> or <code> tag in this editor so apologies for the formatting below.

       

      I am trying to develop a custom binary store and deploy as a jboss-module and then configure a repository within standalone-modeshape.xml

       

      I am extending FileSystemBinary and overriding storeValue and getInputStream. I am basically encrypting the stream in storeValue and decrypting in getInputStream. Whether or not this is a good approach I don't know. My intention is that the nodes / metadata is unencrypted, allowing normal operation, yet the actual binary on the fs will be encrypted. This should, I hope, allow for the modeshape-rest and modeshape-explorer to operate normally and actually show the image.

      Using smartics-jboss-modules-maven-plugin - Overview I am creating a jboss-modules zip containing my custom binary store and supporting 3rd party libs. Perhaps I haven't done this correct which is causing the problem I will eventually get to

       

      The module.xml is:

       

      <?xml version="1.0" encoding="UTF-8"?>
      <module xmlns="urn:jboss:module:1.1" name="com.asdf.backoffice.imageserver.encryptedstore" slot="asdf1">
        <resources>
        <resource-root path="encryptedstore-1.0-SNAPSHOT.jar" />
        </resources>
        <dependencies>
        <module name="net.sf.jsignature.io-tools.easystream" slot="asdf1" />
        </dependencies>
      </module>

       

      This is deployed to wildfly.../modules with the jar and supporting libs as per my understanding of how to do this.

       

      The config in standalone-modeshape.xml is:

       

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

         <workspaces allow-workspace-creation="false">

            <workspace name="images"/>

         </workspaces>

         <custom-binary-storage classname="com.asdf.imageserver.encryptedstore.EncryptedBinaryStore" module="com.asdf.backoffice.imageserver.encryptedstore"/>

         <sequencers>

            <sequencer name="image-sequencer" classname="image" module="org.modeshape.sequencer.image" path-expression="/files(//*.(png|jpg|jpeg|gif)[*])/jcr:content[@jcr:data] => /derived/image/$1"/>

         </sequencers>

      </repository>

       

      The error I am getting is:

       

      13:12:03,857 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-2) MSC000001: Failed to start service jboss.modeshape.asdfEncrypted.repository: org.jboss.msc.service.StartException in service jboss.modeshape.asdfEncrypted.repository: org.modeshape.jcr.ConfigurationException: The configuration for the 'asdfEncrypted' repository has problems: ERROR: Error at storage.binaryStorage.classname : Field value for 'storage.binaryStorage.classname' expected to be of type string but was of type unknown

      ERROR: Error at storage.binaryStorage.classloader : Field value for 'storage.binaryStorage.classloader' expected to be of type string but was of type unknown

      at org.modeshape.jboss.service.RepositoryService.start(RepositoryService.java:221)

      at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948)

      at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881)

      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

      at java.lang.Thread.run(Thread.java:745)

      Caused by: org.modeshape.jcr.ConfigurationException: The configuration for the 'asdfEncrypted' repository has problems: ERROR: Error at storage.binaryStorage.classname : Field value for 'storage.binaryStorage.classname' expected to be of type string but was of type unknown

      ERROR: Error at storage.binaryStorage.classloader : Field value for 'storage.binaryStorage.classloader' expected to be of type string but was of type unknown

      at org.modeshape.jcr.ModeShapeEngine.deploy(ModeShapeEngine.java:469)

      at org.modeshape.jcr.ModeShapeEngine.deploy(ModeShapeEngine.java:441)

      at org.modeshape.jboss.service.RepositoryService.start(RepositoryService.java:219)

      ... 5 more

       

      Going by the documentation on Custom - ModeShape 5 - Project Documentation Editor

      classloader is only relevant to JSON config.

      classname very much seems like a string to me.

       

      There is no easily found end to end instructions to create a custom binary store and deploy/configure to wildfly. Perhaps there is something in the modeshape git repo but I can't find what I am looking for.

       

      Perhaps my usage of jboss-module slots is wrong.

       

      Please point me towards an end to end example to develop, deploy, configure modeshape custombinarystore in a Wildfly environment.

       

      Regards,

      Thomas.

       

       

       

      CustomBinaryStore:

      @ThreadSafe
      public class EncryptedBinaryStore extends FileSystemBinaryStore {

       

         public EncryptedBinaryStore(File directory) {

         super(directory);
         }

       

         public EncryptedBinaryStore(File directory, File trash) {

         super(directory, trash);
         }

       

         @Override
         public BinaryValue storeValue(InputStream stream, boolean markAsUnused) throws BinaryStoreException {

       

         final FileSystemBinaryStore superDuper = this;
        final InputStream superInputStream = stream;

        final BinaryValue binaryValue;

        try (final OutputStreamToInputStream<BinaryValue> outputStream = new OutputStreamToInputStream<BinaryValue>() {

         @Override
         protected BinaryValue doRead(final InputStream istream) throws Exception {

         return superDuper.storeValue(istream, markAsUnused);
         }

        }) {

         new Encryptor().encryptFile(superInputStream, outputStream);
         binaryValue = outputStream.getResult();
         } catch (Exception e) {

         throw new RuntimeException(e);
         }

       

         return binaryValue;
         }

       

         @Override
         public InputStream getInputStream(BinaryKey key) throws BinaryStoreException {

       

         final FileSystemBinaryStore superDuper = this;
        final InputStream inputStream;

        try (final OutputStreamToInputStream<InputStream> outputStream = new OutputStreamToInputStream<InputStream>() {

         @Override
         protected InputStream doRead(final InputStream istream) throws Exception {

         return superDuper.getInputStream(key);
         }

        }) {

         new Encryptor().decryptFile(superDuper.getInputStream(key), outputStream);
         inputStream = outputStream.getResult();
         } catch (Exception e) {

         throw new RuntimeException(e);
         }

       

         return inputStream;

         }

      }

        • 1. Re: Custom BinaryStore deployed as jboss-module
          Horia Chiorean Master

          This is a bug (see [MODE-2626] Cannot configure a custom binary store in the Wildfly kit - JBoss Issue Tracker) in our WF kit; obviously you're the first person to attempt this

          The fix should be part of 5.2 (which will be released towards the end of September). If you need the fix earlier, you have the option of building the WF kit sources locally (once I fix this and submit the PR) and use that locally until the release.

           

          Also, note that if your binary store uses anything from the ModeShape codebase (in this case you're extending the FS binary store) you should make sure your WF module lists the "org.modeshape" module as a dependency.

          • 2. Re: Custom BinaryStore deployed as jboss-module
            Thomas Newman Newbie

            Thankyou for addressing this issue so quickly.

             

            (When I use <code> in 'html' mode, any xml entries get killed. How am I supposed to do code entries?)

             

            I have checked out master with the pull request and built/deployed the Wildfly kit.

             

            When using modeshape-rest, I get a ClassNotFoundException thrown from DelegatingClassLoader:

            at java.lang.Thread.run(Thread.java:745)rnCaused by: java.lang.ClassNotFoundException: com.zzz.imageserver.encryptedstore.EncryptedBinaryStore
            at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
            at org.modeshape.common.util.DelegatingClassLoader.findClass(DelegatingClassLoader.java:51)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
            at org.modeshape.jcr.RepositoryConfiguration$BinaryStorage.createInstance(RepositoryConfiguration.java:1249)
            at org.modeshape.jcr.RepositoryConfiguration$BinaryStorage.getBinaryStore(RepositoryConfiguration.java:1194)
            at org.modeshape.jcr.JcrRepository$RunningState.(JcrRepository.java:1072)
            at org.modeshape.jcr.JcrRepository$RunningState.(JcrRepository.java:937)
            at org.modeshape.jcr.JcrRepository.doStart(JcrRepository.java:368)
            at org.modeshape.jcr.JcrRepository.login(JcrRepository.java:633)
            ... 49 morern"

             

            My EncryptedBinaryStore is the same as CustomTransientBinaryStore from the pull request.

             

            My module.xml: (This seems OK because if I change the module name, Wildfly won't start)

            <?xml version="1.0" encoding="UTF-8"?>
            <module xmlns="urn:jboss:module:1.1" name="zzz.imageserver">
                <resources>
                    <resource-root path="." />
                </resources>
                <dependencies>
                    <module name="org.modeshape" />
                </dependencies>
            </module>

             

            The jar with my class is deployed along side this module.xml. I have checked package path and file name. I am using "." for path as I will eventually be adding a 3rd party library.

             

            My repository is defined just the same as in the pull request:

            <repository name="zzzEncrypted" anonymous-roles="admin">
            <workspaces allow-workspace-creation="false">
              <workspace name="images"/>
            </workspaces>
            <custom-binary-storage min-string-size="100" mime-type-detection="none" classname="com.zzz.imageserver.encryptedstore.EncryptedBinaryStore" module="zzz.imageserver"/>
            <sequencers>
              <sequencer name="image-sequencer" classname="image" module="org.modeshape.sequencer.image" path-expression="/files(//*.(png|jpg|jpeg|gif)[*])/jcr:content[@jcr:data] => /derived/image/$1"/>
            </sequencers>
            </repository>

             

            I have even tried adding my module to modeshape module.xml (wildfly-10.0.0.Final-ModeShape\modules\org\modeshape\main\module.xml)

            ...
            <module name="sun.jdk" export="true"/>
            <module name="zzz.imageserver" export="true"/>
            </dependencies>
             
            I am sure I don't need to add my module to modeshape common module.
            I am sure the repository definition in standalone-modeshape.xml is supposed to load the module for use.

             

            Any pointers would be greatly appreciated.

             

            Regards,
            Thomas.

            • 3. Re: Custom BinaryStore deployed as jboss-module
              Horia Chiorean Master

              I don't know what's going on, the only thing I can think of is to try and change your module.xml and explicitly add your JAR as a resource root (not just "."). In the test case I'm using "." because I'm using a .class file which is not packaged in a JAR.

               

              Dependency wise, you should not need anything else except your module depending on org.modeshape. If all else fails, you should debug DelegatingClassloader#findClass and look at the delegates collection. If your Wildfly configuration is correct (module name, path on disk, etc) then you should see a WF module class loader which is used to load resources from your module.

              1 of 1 people found this helpful
              • 4. Re: Custom BinaryStore deployed as jboss-module
                Thomas Newman Newbie

                Thanks Horia,

                Just as you said, listing my jar in resources seems to be the difference.

                For future reference, incorrectly listing a dependency eg <module name="org.slf4j.slf4j-api" /> instead of <module name="org.slf4j"/> causes class loading problems as well.

                Regards,

                Thomas.