ModeShape
  1. ModeShape
  2. MODE-1832

ModeShape CMIS component has bug in JcrService

    Details

    • Similar Issues:
      Show 10 results 

      Description

      While trying to use the new ModeShape CMIS gear, we found strange exceptions:

      java.lang.StringIndexOutOfBoundsException: String index out of range: -1

      See longer stack trace below. They appear to come from the following method:

      private String workspace(String repositoryId)

      { return repositoryId.indexOf(":") > 0 ? null : repositoryId.substring(repositoryId.indexOf(":"), repositoryId.length()); }

      It appears that the test there is backwards. It should be a less-than and not a greater-than. The method above it (private String name(String repositoryId)) appears to suffer from the same bug.

      — login: FedoraRepository
      java.lang.StringIndexOutOfBoundsException: String index out of range: -1
      at java.lang.String.substring(String.java:1904)
      at org.modeshape.cmis.JcrService.workspace(JcrService.java:378)
      at org.modeshape.cmis.JcrService.login(JcrService.java:360)
      at org.modeshape.cmis.JcrService.getRepositoryInfos(JcrService.java:103)
      at org.apache.chemistry.opencmis.server.support.CmisServiceWrapper.getRepositoryInfos(CmisServiceWrapper.java:488)
      at org.apache.chemistry.opencmis.server.impl.browser.RepositoryService.getRepositories(RepositoryService.java:65)
      at org.apache.chemistry.opencmis.server.impl.browser.CmisBrowserBindingServlet.dispatch(CmisBrowserBindingServlet.java:288)
      at org.apache.chemistry.opencmis.server.impl.browser.CmisBrowserBindingServlet.service(CmisBrowserBindingServlet.java:248)
      ...

        Activity

        Hide
        Edwin Shin
        added a comment -

        I just realized I had a cut-and-paste error in the last link I added to my comment earlier. I meant to refer to https://github.com/ModeShape/modeshape/blob/master/web/modeshape-web-cmis/src/main/java/org/modeshape/cmis/JcrServiceFactory.java#L110 because, as I said, it seems repositoryId should not be derived from the repository name alone.

        Oleg, you said "Actually we are encoding repository name and workspace name as a single parameter in the form", but where is that happening? JcrServiceFactory.java#L110 suggests otherwise. I don't see any reference to getting the workspace name.

        Show
        Edwin Shin
        added a comment - I just realized I had a cut-and-paste error in the last link I added to my comment earlier. I meant to refer to https://github.com/ModeShape/modeshape/blob/master/web/modeshape-web-cmis/src/main/java/org/modeshape/cmis/JcrServiceFactory.java#L110 because, as I said, it seems repositoryId should not be derived from the repository name alone. Oleg, you said "Actually we are encoding repository name and workspace name as a single parameter in the form", but where is that happening? JcrServiceFactory.java#L110 suggests otherwise. I don't see any reference to getting the workspace name.
        Hide
        Oleg Kulikov
        added a comment -

        First where we are encoding.

        CMIS bridge uses web.xml to get access to the repositories. Inside web.xml you can find the following entry

        <context-param>
        <param-name>org.modeshape.jcr.URL</param-name>
        <param-value>file:/repo-config.json</param-value>
        </context-param>

        where repo-config.json contains all the configuration information about repository including its name and available workspaces. For instance repository name is "cmis_repo" and it has a workspace "default". Now at the client to get access we need to specify several parameters like

        parameter.put(SessionParameter.BINDING_TYPE, BindingType.WEBSERVICES.value());
        parameter.put(SessionParameter.WEBSERVICES_ACL_SERVICE, serviceUrl("ACLService?wsdl"));
        parameter.put(SessionParameter.WEBSERVICES_DISCOVERY_SERVICE, serviceUrl("/DiscoveryService?wsdl"));
        parameter.put(SessionParameter.WEBSERVICES_MULTIFILING_SERVICE, serviceUrl("MultiFilingService?wsdl"));
        parameter.put(SessionParameter.WEBSERVICES_NAVIGATION_SERVICE, serviceUrl("NavigationService?wsdl"));
        parameter.put(SessionParameter.WEBSERVICES_OBJECT_SERVICE, serviceUrl("ObjectService?wsdl"));
        parameter.put(SessionParameter.WEBSERVICES_POLICY_SERVICE, serviceUrl("/PolicyService?wsdl"));
        parameter.put(SessionParameter.WEBSERVICES_RELATIONSHIP_SERVICE, serviceUrl("RelationshipService?wsdl"));
        parameter.put(SessionParameter.WEBSERVICES_REPOSITORY_SERVICE, serviceUrl("RepositoryService?wsdl"));
        parameter.put(SessionParameter.WEBSERVICES_VERSIONING_SERVICE, serviceUrl("VersioningService?wsdl"));

        parameter.put(SessionParameter.REPOSITORY_ID, "cmis_repo:default");

        // create session
        session = factory.createSession(parameter, null, new StandardAuthenticationProvider()

        As you can see the last parameters is in the form repository_name:workspace. On the server side we are parsing this parameter and extracting name and workspace again. That code you can find in the JcrService class.

        JcrService class has one bug at the line 111, when it extracts repository name and then calls login(..) which will try to extract name again. Plus this code is not good in sense of possible weird inputs (for example ':' somewhere in the name ) or when we have for instance one repository and no ':'. That is what would be nice to improve.

        Show
        Oleg Kulikov
        added a comment - First where we are encoding. CMIS bridge uses web.xml to get access to the repositories. Inside web.xml you can find the following entry <context-param> <param-name>org.modeshape.jcr.URL</param-name> <param-value> file:/repo-config.json </param-value> </context-param> where repo-config.json contains all the configuration information about repository including its name and available workspaces. For instance repository name is "cmis_repo" and it has a workspace "default". Now at the client to get access we need to specify several parameters like parameter.put(SessionParameter.BINDING_TYPE, BindingType.WEBSERVICES.value()); parameter.put(SessionParameter.WEBSERVICES_ACL_SERVICE, serviceUrl("ACLService?wsdl")); parameter.put(SessionParameter.WEBSERVICES_DISCOVERY_SERVICE, serviceUrl("/DiscoveryService?wsdl")); parameter.put(SessionParameter.WEBSERVICES_MULTIFILING_SERVICE, serviceUrl("MultiFilingService?wsdl")); parameter.put(SessionParameter.WEBSERVICES_NAVIGATION_SERVICE, serviceUrl("NavigationService?wsdl")); parameter.put(SessionParameter.WEBSERVICES_OBJECT_SERVICE, serviceUrl("ObjectService?wsdl")); parameter.put(SessionParameter.WEBSERVICES_POLICY_SERVICE, serviceUrl("/PolicyService?wsdl")); parameter.put(SessionParameter.WEBSERVICES_RELATIONSHIP_SERVICE, serviceUrl("RelationshipService?wsdl")); parameter.put(SessionParameter.WEBSERVICES_REPOSITORY_SERVICE, serviceUrl("RepositoryService?wsdl")); parameter.put(SessionParameter.WEBSERVICES_VERSIONING_SERVICE, serviceUrl("VersioningService?wsdl")); parameter.put(SessionParameter.REPOSITORY_ID, "cmis_repo:default"); // create session session = factory.createSession(parameter, null, new StandardAuthenticationProvider() As you can see the last parameters is in the form repository_name:workspace. On the server side we are parsing this parameter and extracting name and workspace again. That code you can find in the JcrService class. JcrService class has one bug at the line 111, when it extracts repository name and then calls login(..) which will try to extract name again. Plus this code is not good in sense of possible weird inputs (for example ':' somewhere in the name ) or when we have for instance one repository and no ':'. That is what would be nice to improve.
        Hide
        Edwin Shin
        added a comment -

        I think we're missing each other across the water

        I already dealt with the bug on L111 in a local branch. But that doesn't address the user-visible problem which is bringing up the ModeShape + CMIS webapp and trying to GET the /browser or /atom11 CMIS endpoints (as defined in https://github.com/ModeShape/modeshape/blob/master/web/modeshape-web-cmis-war/src/main/webapp/WEB-INF/web.xml)--I noted this in my comment on March 6 with steps to replicate on the war produced by modeshape-web-cmis-war.

        I understand that with the client session code you can pass in that single string as a parameter that encodes repository_name:workspace. I noted this in my comment of March 6 as well. What's escaping me is how that workspace information is supposed to be provided for the CMIS REST endpoint services. I'm almost utterly unfamiliar with CMIS, so the answer may be I'm just trying to consume those endpoints incorrectly: e.g. that I shouldn't expect to get a 200 response from those endpoints in my browser without passing in some additional HTTP headers. Yet, when I allow null to be returned for the workspace, things do appear to work (because the login code then uses the default workspace). If there's a way in JcrService to at least pick out the default workspace and return that if the repositoryId string doesn't encode a workspace, I think that would work too, but again I don't know where that information is available to me in JcrService.

        Show
        Edwin Shin
        added a comment - I think we're missing each other across the water I already dealt with the bug on L111 in a local branch. But that doesn't address the user-visible problem which is bringing up the ModeShape + CMIS webapp and trying to GET the /browser or /atom11 CMIS endpoints (as defined in https://github.com/ModeShape/modeshape/blob/master/web/modeshape-web-cmis-war/src/main/webapp/WEB-INF/web.xml)--I noted this in my comment on March 6 with steps to replicate on the war produced by modeshape-web-cmis-war. I understand that with the client session code you can pass in that single string as a parameter that encodes repository_name:workspace. I noted this in my comment of March 6 as well. What's escaping me is how that workspace information is supposed to be provided for the CMIS REST endpoint services. I'm almost utterly unfamiliar with CMIS, so the answer may be I'm just trying to consume those endpoints incorrectly: e.g. that I shouldn't expect to get a 200 response from those endpoints in my browser without passing in some additional HTTP headers. Yet, when I allow null to be returned for the workspace, things do appear to work (because the login code then uses the default workspace). If there's a way in JcrService to at least pick out the default workspace and return that if the repositoryId string doesn't encode a workspace, I think that would work too, but again I don't know where that information is available to me in JcrService.
        Hide
        Edwin Shin
        added a comment -

        ok, see https://github.com/ModeShape/modeshape/pull/744 which implements the changes we discussed on #modeshape

        Show
        Edwin Shin
        added a comment - ok, see https://github.com/ModeShape/modeshape/pull/744 which implements the changes we discussed on #modeshape
        Hide
        Randall Hauch
        added a comment -

        Rebased and merged the second pull-request into the 'master' branch.

        Show
        Randall Hauch
        added a comment - Rebased and merged the second pull-request into the 'master' branch.

          People

          • Assignee:
            Oleg Kulikov
            Reporter:
            A Soroka
          • Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: