Saturday, May 22, 2010

Activiti by Alfresco: A BPMN 2 Implementation

I'm giving a try on the recent open source project Activiti, which implements BPMN 2 (Business Process Management Notation). Despite being in its first alpha version, Activiti already called a lot of attention from the community. I think it is due to the fact that the leaders are quite reliable people. They are former JBoss' employees, who created and maintained the JBPM project, a business process management framework, and it is quite successful nowadays.

I've met Tom Baeyens and Joram Barrez in the last edition of Devoxx. Their talks were a "must attend" section in all recent Devoxx editions, and they will probably present their brand new product  at this year's edition too. The framework is still in alpha but I think it will evolve a lot until there. By the way, the current version is more about playing and understanding the idea than effectively performing processes. What I've seen so far deserves some comments.

My first impression was nice. Activiti is very simple to install and the team made a very good work on the design of the user interfaces. Of course, I cannot be so critical right now because it is just beginning, but I will follow the project from now on to give constructive feedbacks to the team.
On the other hand, I was expecting something different, simpler, like a process engine 100% controlled by REST web services. I don't like the fact of a web application handling the processes execution (screenshot above). Using Activiti Explorer, you can start processes and perform their activities, but it forces the user to be aware of processes' details. I think an application that implements a business process should be more focused on:
  • the performance of the user when executing his/her activities; and
  • the quality of the data inserted.
Better to wait a little bit more to see the Activiti evolution. I do support the project and hope to see it widely adopted.

Wednesday, May 19, 2010

Canon, Nikon or Sony ?

I wanna buy a SLR camera but I'm not sure which one is the best one for my needs. I went to a shop last week and they told me the best characteristic of each one. Sharing with you:
  • Canon: better for pictures of movements like in sports, streets, shows, etc.
  • Nikon: better for pictures of no movements or quiet moments like landscape, family, monuments, etc.
  • Sony: technically inferior to the above ones but good for dummies, who are starting in the art of photography. 
For a moment I thought the guy was trying to sell me all three models because I want to take all kinds of pictures and do it in an easy way.

Since I'm a beginner, I'm inclined to choose the Sony Alfa 330, which has a good price at the moment. Sony implements lots of image processing internally, enhancing the picture's colors, luminosity and other details, but distorting the reality. Nikon and Canon take shots of the reality, but they demand some expertise in photography to make the pictures look great.

Do you have some knowledge about them? Share it here. ;-)

Monday, May 10, 2010

Yasmim Security: User Authentication using JDBC Realm

In the previous post, I introduced you to the Yasmim application. Today, I'm going into details on its implementation, starting from a very important non-functional requirement: the user authentication. Since I'm using a JEE6 Application server, I'm going to explain how we did it using the security infrastructure provided by the container.
    JDBC Realm

    This is a configuration entirely made in the application server. It may demand some time, but at least your application is going to be free from the basic security complexity. Yasmim uses JDBC Realm because we stored the user data in a database, which could be a third party database (single sign-on for multiple applications in the context of an organization) or the database of the application (users and groups embedded to be independent from the organizational context).

    The figure below proposes a data structure for users and groups. It is more complex and realistic than most examples found on the web, but it follows basically the same principle: a group contains several users and a user can be part of several groups. We created a N-N relationship between the tables account_group and user_account, using the intermediary table user_group.
    The script to create this structure is available in the repository. The beginning of the script creates the structure above in a MySQL database. For the purpose of this application, you can create the database with just these three tables. If you don't know how to create a MySQL database, follow this post. You will need a connection poll pointing to this database. If you don't know how to create a connection pool, I also wrote a post explaining this.

    The sql scripts below consider the model above and they are used to populate the tables for test purposes. The first one inserts 2 users in the database: John Smith and Mary Allen. Their password is secret but it is not readable because a MD5 algorithm was applied on it. The realm will need encoded passwords because we have specified the MD5 as the diggest algorithm in the realm configuration detailed later on. The column confirmation_code is not relevant now, so we defined it as null.
    insert into user_account values
       ('johnsmith@acme.com','Xr4ilOzQ4PCOq3aQ0qbuaQ==',
        'John','Smith',1,'1980-02-09',null);
    insert into user_account values 
       ('maryallen@acme.com','Xr4ilOzQ4PCOq3aQ0qbuaQ==',
        'Mary','Allen',0,'1976-05-10',null);
    Then, we insert the basic groups admins and users. The group users was defined as the default for registered users, but this attribute is not relevant either here. Maybe we can explore it in a future post.
    insert into access_group values
       ('admins','Administrative Group', null);
    insert into access_group values
       ('users','Default User Group', 1);
    Finally, we associate the users with the groups. Mary Allen is part of the groups admins and users and John Smith is part of the group users. So, Mary can do everything John can do, but John can't do everything that Mary can.
    insert into user_group values
       ('admins', 'maryallen@acme.com');
    insert into user_group values
       ('users', 'maryallen@acme.com');
    insert into user_group values
       ('users', 'johnsmith@acme.com');
    Follow the steps below to configure the JDBC Realm:
    1. Go to the Glassfish admin console (http://localhost:4848/), navigate to Configuration > Security > Realms and press "New...";
    2. Name: yasmim-realm - it will be used to refer to this realm in the application (tag realm-name in the file web.xml);
    3. Class Name: com.sun.enterprise.security
              .auth.realm.jdbc.JDBCRealm;
    4. Properties specific to this Class (using the model above as a reference):
      1. JAAS Context: jdbcRealm - identifier for the login module;
      2. JNDI: jdbc/yasmim - the data source JNDI name pointing to the connection pool where the tables are available;
      3. User Table: user_account - user table according to the model above;
      4. User Name Column: user_id - column where the user name is stored;
      5. Password Column: password - column where the password is stored;
      6. Group Table: user_group - notice that the group table is not the access_group, but the intermediary table user_group. access_group is used to store further details about the groups;
      7. Group Name Column: group_id - this is the foreign key to the access_group table, thus this is the id of the group;
      8. Digest Algorithm: MD5 - of course you are not going to save the password as it is. This is actually embarrassing for you to know the password of your users. So, let's inform to the realm that the password was scrambled by the MD5 algorithm; and
      9. Encoding: Base64 -  the encoding used by the MD5 algorithm.
    That's all for the server-side. Now, we are going to configure the application to use this realm.

    Application Configuration

    We have to configure the files web.xml and sun-web.xml. An example of web.xml configured for this purpose is available in the Yasmim repository. Here, some comments about the configuration:

    Since some pages are going to be protected, we'll need an access denied page to alert the user:
    <error-page>
        <error-code>403</error-code>
        <location>/access_denied.xhtml</location>
    </error-page>
    
    On the application side, the access to resources of the system is given to roles, that can be assumed by users and groups. Roles are declared this way:
    <security-role>
        <description/>
        <role-name>admin</role-name>
    </security-role>
    <security-role>
        <description/>
        <role-name>user</role-name>
    </security-role>
    
    This security constraint states that only users with the role admin can access the content of the /admin folder. These users can perform GET and POST http methods only.
    <security-constraint>
        <display-name>Admin Constraints</display-name>
        <web-resource-collection>
          <web-resource-name>Administrators</web-resource-name>
          <description/>
          <url-pattern>/admin/*</url-pattern>
          <http-method>GET</http-method>
          <http-method>POST</http-method>
        </web-resource-collection>
        <auth-constraint>
            <role-name>admin</role-name>
        </auth-constraint>
    </security-constraint>
    
    This second constraint states that only users with the role user can access the content of the /media folder. The tag url-pattern is flexible enough to consider several complex situations, but you may find some difficulty if the name of the files and folders are not so well organized.
    <security-constraint>
        <display-name>Users Constraints</display-name>
        <web-resource-collection>
            <web-resource-name>Users</web-resource-name>
            <description/>
            <url-pattern>/media/*</url-pattern>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
        </web-resource-collection>
        <auth-constraint>
            <role-name>user</role-name>
        </auth-constraint>
    </security-constraint>
    
    Now, we define which authentication method will be presented to the user. We chose the most common one, which is the FORM method. yasmim-realm is the name of the realm we have just created. /login.xhtml is the authentication page and /login_error.xhtml is shown in case of authentication failure.
    <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>yasmim-realm</realm-name>
        <form-login-config>
          <form-login-page>/login.xhtml</form-login-page>
          <form-error-page>/login_error.xhtml</form-error-page>
        </form-login-config>
    </login-config>
    
    In addition to the web.xml file, the sun-web.xml file is used to associate the application roles with the user groups. It is a practical way to associate roles to several users at the same time. The file is located in the WEB-INF folder, together with web.xml, and its content is shown below:
    <sun-web-app error-url="">
      <context-root>/yasmim</context-root>
      <security-role-mapping>
        <role-name>admin</role-name>
        <group-name>admins</group-name>
      </security-role-mapping>
      <security-role-mapping>
        <role-name>user</role-name>
        <group-name>users</group-name>
        <group-name>admins</group-name>
      </security-role-mapping>
    </sun-web-app>
    In this case, the role admin is associated with the group admins and the role user is associated with the groups admins and users.

    Implementation of the Authentication Page

    There are, at least, three pages to consider: login.xhtml, login_error.xhtml and access_denied.xhtml. The login.xhtml page was declared in the web.xml file as the page that collects the authentication data from the user though a standardized form. The form contains the username and password fields and the submit command to post those data to the server. The action of the form and the name of each field are pre-defined. Look at the code below:
    <form method="post" action="j_security_check">
      <h:panelGrid columns="2">
        <h:outputLabel for="j_username" value="E-mail"/>
        <input type="text" name="j_username"/>
    
        <h:outputLabel for="j_password" value="Password"/>
        <input type="password" name="j_password"/>
    
        <h:outputText value=" "/>
        <h:panelGrid columns="2">
          <input type="submit" name="submit" value="Sign in"/>
          <h:button outcome="index" value="Cancel"/>
        </h:panelGrid>
      </h:panelGrid>
    </form>
    
    This is a JSF 2.0 page with Facelets, but it can be a simple HTML page too. The important thing is the form action, which is j_security_check, and the username and password fields, which are named respectively as j_username and j_password. When the user submit the data the web container will handle it in a special way without interfering in the logic of your application. If you don't need any other fancy feature, the work is done here.

    According to the authentication and authorization data in the database and what was declared in the application configuration, Once authenticated, Mary Allen has full access to the content of the folders admin and media and John Smith has access only to the content of the folder media. To save your time, take the Yasmim source code as a starting point and explore other possibilities.

    Sunday, May 2, 2010

    Yet Another System for Multimedia Information Management - YASMIM

    As part of my research, I'm developing a system for media archiving with features that makes it a media information management. I figured out a nice acronym for this system: Yet Another System for Multimedia Information Management - YASMIM. The reason why it is "Yet Another System" is because there are several multimedia archiving systems out there and I'm going to create one more (I'm so brave! :P). It is not just a multimedia archiving system, but also a system to organize all information possibly related to the content of the media.

    This system has 3 personal goals:
    1. demonstrate my scientific contributions to the field of multimedia systems;
    2. update my expertise on enterprise systems and manipulation of large datasets to get ready to the market again; and
    3. share my acquired knowledge with people interested in JEE6 (EJB3, JPA, JSF) server applications and JavaFX desktop applications because the best way to learn is sharing and teaching.
    According to my plans, I'm going to finish my PhD in October, 2010. I'm writing the thesis right now and it is all about the YASMIM system. it's planned to support several kinds of media, including images, videos, audios, and 3D models. The main differentials are the possibility to segment and annotate all these kinds of media within only one integrated system and provide these features through a web service interface, in addition to the conventional web interface. This system is open source, but I can only make it fully available after my thesis defense. However, I have published an initial (but compilable) source on GitHub. If you wish, you can help me to develop it and we can figure out together many other innovative aspects. ;)


    Why did I chose JEE6 and JavaFX? The first reason is that I'm supposed to get into the market soon and I have to update my knowledge of enterprise systems, which was what I used to work before the PhD. But of course, I cannot put in the thesis this reason. Better to find reasonable technical reasons. So, the technical reasons to choose JEE6 were:
    • the architecture allows the expansion of available resources without redesigning the code;
    • support for multiple user sessions;
    • support for authentication and authorization and I just have to worry about the content sensitiveness;
    • totally based on POJO, so I can keep the code as simple as possible while focusing on the algorithm part; and
    • the support for web services is native and implemented by Java annotations.
    The technical reasons to choose JavaFX as the client technology were:
    • vectorial user interface rendering;
    • multi-platform, including mobile devices; and
    • good support for media playback.
    An alternative platform to implement this system would be Adobe Flash. However, a basic technical problem prevented me to choose this platform: I use a Linux 64 bits operating system and it doesn't work appropriately on it. Thus, besides having a bigger number of machines supporting Flash, some platforms do not support it well. Considering JavaFX, most platforms support it well, however, less machines have it installed. So, my decision was in favor of more compatibility.

    If you are interested in this kind of application, not only for multimedia processing, but also to learn about Enterprise Java and JavaFX, be my guest and get involved on http://github.com/htmfilho/Yasmim.