10 Replies Latest reply on Jun 30, 2011 11:04 PM by priyakpandey

    JBPM 5.1 Final Release with jboss-5.1.0.GA embedded server - Users/Roles/Groups Management

    priyakpandey Newbie

      Hi,

      I am using the JBPM 5.1 Final version which is released recently for one of the customer which is supposed to goLive very soon.

      I hve few important things which is difficult to handle,

      1. org.jbpm.DemoTaskService - loads all the users and the groups present in the LoadUsers.mvel and LoadGroups.mvel in the TaskServiceSession.

           1.1. Practically this is going to be huge performance hit incase of even small size organization with 100 - 150 user/groups. 

           1.2. Is there any way / flag by which the user details of only that particular user is loaded who is accessing the server?

           1.3 Why it needs to load all the users/groups in the session?

            1.4 It is currently loads .mvel file to load users/groups? Is there any other version of this class which accees DB?

            1.5 When i comment loading of users and groups and try to start a process, it gives following error in the jboss-5.1.0.GA\server\default\log\server.log. It creates the process instance but task is not created.

        

      2011-06-25 20:34:24,351 INFO  [STDOUT] (http-localhost%2F127.0.0.1-8080-1) ERROR 25-06 20:34:24,350 (RepositoryServlet.java:doAuthorizedAction:78)

      java.lang.NullPointerException


      at java.io.OutputStream.write(OutputStream.java:58)

      at org.drools.guvnor.server.files.FileManagerUtils.loadBinaryPackage(FileManagerUtils.java:188)

      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

      at java.lang.reflect.Method.invoke(Method.java:597)

      at org.jboss.seam.util.Reflections.invoke(Reflections.java:22)

      at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:31)

      at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)

      at org.jboss.seam.transaction.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:28)

      at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)

      at org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:77)

      at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)

      at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:44)

      at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)

      at org.jboss.seam.security.SecurityInterceptor.aroundInvoke(SecurityInterceptor.java:157)

      at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)

      at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)

      at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:166)

      at org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:102)

      at org.drools.guvnor.server.files.FileManagerUtils_$$_javassist_3.loadBinaryPackage(FileManagerUtils_$$_javassist_3.java)

      at org.drools.guvnor.server.files.PackageDeploymentServlet$1.execute(PackageDeploymentServlet.java:269)

      at org.drools.guvnor.server.files.RepositoryServlet.doAuthorizedAction(RepositoryServlet.java:76)

      at org.drools.guvnor.server.files.PackageDeploymentServlet.doGet(PackageDeploymentServlet.java:135)

      at javax.servlet.http.HttpServlet.service(HttpServlet.java:625)

      at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)

      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)

      at org.jboss.seam.web.ContextFilter$1.process(ContextFilter.java:42)

      at org.jboss.seam.servlet.ContextualHttpServletRequest.run(ContextualHttpServletRequest.java:53)

      at org.jboss.seam.web.ContextFilter.doFilter(ContextFilter.java:37)

      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)

      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)

      at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)

      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)

      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)

      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)

      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)

      at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190)

      at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)

      at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)

      at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)

      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)

      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)

      at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)

      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)

      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)

      at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)

      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:598)

      at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)

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

       

      2. org.jbpm.integration.console.TaskManagement - loads user roles from Roles.properties

          2.1 Loads all the users roles and in 'Map<String, List<String>> groupListMap'. Again, Why all the users roles are loaded on startup?

          2.2 Is there any option to defer the loading until it is required?

          2.3  Is there any option to point to DB instead of property file?

          2.4 When I change the user role to load for the particular user then task is getting created but it throws exception in the server.log.

       

      I have noticed that whatever changes i need to make, i have to go through the series of classes modify, recompile and then make it work. Is there any pluggable way where-in i just need to implement the interface and specify the implementation class in the configuration file and JBPM should work.

       

      Any help on this would be appreciated as this is critical and we need to deliver it to a client.

      Thank you in advance.

        • 1. Re: JBPM 5.1 Final Release with jboss-5.1.0.GA embedded server - Users/Roles/Groups Management
          Kris Verlaenen Master

          User and groups currently need to be defined upfront, for validation reason.  Note that this is only at application start-up, not a runtime delay.  And this should also only be done once, as the data is persisted in the database so you don't need to repeat this step every time.

           

          We're working on an extension that would simplify user / group management significantly, a callback interface that you could implement that allow you to define what the valid users are (so you don't have to pre-register) and to resolve user-group relationships.  That should make it a lot easier to integrate the human task service / jbpm console with existing services that already contain this information.  This should be available in the next few weeks.

           

          Kris

          • 2. Re: JBPM 5.1 Final Release with jboss-5.1.0.GA embedded server - Users/Roles/Groups Management
            priyakpandey Newbie

            Thank you Kris for your reply !

            This users/groups and roles are loaded in the session everytime server starts.

            Eventhough this is done just once everytime server starts it would be huge data in the session if i have lets say 300 - 500 users, 300 - 500 groups and roles loaded in the session.

            • 3. Re: JBPM 5.1 Final Release with jboss-5.1.0.GA embedded server - Users/Roles/Groups Management
              Kris Verlaenen Master

              In the installer we're currently doing this every time the server starts as we're using an in-memory database so that is cleaned every time the server goes down.  If you use a more permanent database, you should only insert the valid users / groups once.  Also notice that (1) this data is not stored in memory, only in the database, so storing a few thousand users shouldn't be an issue and (2) a user or group is just a String that represents its id, so the data itself is also very limited.

               

              So I don't think it's as bad as you make it sound But we'll improve this asap as well ...

               

              Kris

              • 4. Re: JBPM 5.1 Final Release with jboss-5.1.0.GA embedded server - Users/Roles/Groups Management
                priyakpandey Newbie

                Thank you for your quick response !

                 

                If you look at DemoTaskService.java main method, it has following code before starting MinaTaskServer.

                      // Add users

                       Map vars = new HashMap();

                        Reader reader = new InputStreamReader( BaseTest.class.getResourceAsStream( "LoadUsers.mvel" ) );    

                        Map<String, User> users = ( Map<String, User> ) eval( reader, vars );  

                        for ( User user : users.values() ) {

                            taskSession.addUser( user );

                        }          

                        reader = new InputStreamReader( BaseTest.class.getResourceAsStream( "LoadGroups.mvel" ) );     

                        Map<String, Group> groups = ( Map<String, Group> ) eval( reader, vars );    

                        for ( Group group : groups.values() ) {

                            taskSession.addGroup( group );

                        }

                 

                What does it do with all users/groups loaded?

                 

                If you look at org.jbpm.integration.console.TaskManagement, after initializing TaskClient it has following,

                try {

                                              ClassLoader loader = Thread.currentThread().getContextClassLoader();

                                              URL url = null;

                                              String propertyName = "roles.properties";

                 

                 

                                              if (loader instanceof URLClassLoader) {

                                                        URLClassLoader ucl = (URLClassLoader) loader;

                                                        url = ucl.findResource(propertyName);

                                              }

                                              if (url == null) {

                                                        url = loader.getResource(propertyName);

                                              }

                                              if (url == null) {

                                                        System.out.println("No properties file: " + propertyName + " found");

                                              } else {

                                                        Properties bundle = new Properties();

                                                        InputStream is = url.openStream();

                                                        if (is != null) {

                                                                  bundle.load(is);

                                                                  is.close();

                                                        } else {

                                                                  throw new IOException("Properties file " + propertyName          + " not available");

                                                        }

                                                        Enumeration<?> propertyNames = bundle.propertyNames();

                                                        while (propertyNames.hasMoreElements()) {

                                                                  String key = (String) propertyNames.nextElement();

                                                                  String value = bundle.getProperty(key);

                                                                  groupListMap.put(key, Arrays.asList(value.split(",")));

                                                                  System.out.print("Loaded user " + key + ":");

                                                                  for (String role: groupListMap.get(key)) {

                                                                            System.out.print(" " + role);

                                                                  }

                                                                  System.out.println();

                                                        }

                                              }

                                    } catch (Throwable t) {

                                              t.printStackTrace();

                                    }

                 

                which loads all the roles of all the users? It can be changed to load on demand for the particular user?

                 

                I am using Oracle but the user/group/roles gets loaded in the session all the time on startup.

                • 5. Re: JBPM 5.1 Final Release with jboss-5.1.0.GA embedded server - Users/Roles/Groups Management
                  Kris Verlaenen Master

                  It simply registers the users and groups, so stores their id in the database tables.  These tables are then used at runtime to validate the users and groups that tasks are assigned to.

                   

                  For user/group management in the console, we don't want to maintain this relationship as part of the human task service.  So we simply use the normal user authentication / authorization facilities provided by JBossAS (using a users.properties and roles.properties file) for the jbpm-console.

                  Once we have the callback interface implemented, it will be trivial to register your own implementation and load users / groups on demand etc.  You can already change the implementation and for example load the groups of a user on demand, but that would require you to modify the jbpm-console code at this point.  Once the callback is there, it will be much easier.  I suggest you start pushing tsurdilo on irc.codehaus.org to hurry up his implementation

                   

                  Note that the documentation on the human task service and the console has been extended recently, so it might be worth rereading those chapters, and hopefully they will help you out as well:

                  http://docs.jboss.org/jbpm/v5.1/userguide/

                   

                  Kris

                  • 6. Re: JBPM 5.1 Final Release with jboss-5.1.0.GA embedded server - Users/Roles/Groups Management
                    priyakpandey Newbie

                    Kris Thank you for your valuable inputs.

                    I noticed that human task service does not maintain the user/group relationships.

                    I also noticed that the authentication/authorization is based on the facilites provided by JBOSS AS as i am trying to configur LDAP for this.

                    Modifying jbpm-console would be painful as i would need to modify the series of clases.

                     

                    Is there any conatct available where in i can  contact tsurdilo on irc.codehaus.org?

                    • 7. Re: JBPM 5.1 Final Release with jboss-5.1.0.GA embedded server - Users/Roles/Groups Management
                      Tihomir Surdilovic Master

                      We are currently working on a callback interface which will allow you to use to write your own implementations (for example LDAP) to resolve users groups and their relationships. You can always contact me via IRC channel #jbpm (irc.codehaus.org). My irc handle is tsurdilo.

                      • 8. Re: JBPM 5.1 Final Release with jboss-5.1.0.GA embedded server - Users/Roles/Groups Management
                        priyakpandey Newbie

                        Thank you for the response!

                        I have a customer going live towards the end of next week, is there any possibility of this being released sometimes early next week?

                        • 9. Re: JBPM 5.1 Final Release with jboss-5.1.0.GA embedded server - Users/Roles/Groups Management
                          Kris Verlaenen Master

                          It is high on our priority list to implement this, but we can't promise we can implement this by early next week.  Make sure to monitor https://issues.jboss.org/browse/JBPM-3276 for progress on this issue.

                           

                          I would recommend at this point, as a temporary solution to customize the code yourself to integrate your own service for user / group management with the task service.  You can then refactor this solution later using this new callback interface once that is available.  Or you try and help out tihomir to make sure it's implemented on time

                           

                          Kris