Business Process Modeling - BTMSoftwareSolutions.com

Wednesday, September 28, 2011

Orbeon xForms Upload/Retrieve Docs from Database

The following screen cast shows how you can use the orbeon upload control to capture document information from a file and then use one submission to store the file to a database and another submission to retrieve the file from the database. 

To store the file to the database an xpl file is called which calls an xslt processor to format the input-config element of the url-generator.  The url-generator processor receieves the url of the temp file passed in on instance data dynamically created by xslt processor.  The url-generator processor grabs the file data in binary mode.  We then use an identity processor to aggregate the instance data passed in on the submission and the output of the url-generator.  We call another xlst processor to dynamically create the input-config element for the SQL processor which will insert the document into the database along with metadata about the file - mediatype, filename, size, ids, etc.

To retrieve the document from the database we call another submission which executes another xpl file.  We pass in instance data about the row of the file we selected to be used as parameters in the sql processor.  So we call sql processor and select the appropriate document.  Then we call an xslt processor and to dynamically configure the config-input element of the http-serializer.  We call a second xslt processor to wrap the document base64Binary data with a root document element and pass as the config-data to the http-serializer.

For assistance on your Orbeon xForms project with storing files and/or integrating with Intalio BPM workflow tool please contact us at BTM Software Solutions, LLC.

Unable to display content. Adobe Flash is required.

Monday, March 28, 2011

Orbeon Page Theme and Menu Items Based on User Role

Orbeon xForms when deployed within a webapp container like Tomcat can be accessed at http://localhost:8080/orbeon/.  Here you will get the pre-packaged orbeon samples which are all included in the apps directory.  Orbeon uses a combination of xml, xsl, xpl and xhtml files when displaying this web application of samples.  If you like the theme (style) applied to the web pages, but want to personalize to your web applications including the menu of applications, you need to have an understanding of what components are used within orbeon.  Below is some documentation on how I used the pre-packed files and modified them to display various orbeon resource apps based on a logged in user's role.  The files that you will need to investigate and understand are apps-list.xml, theme-examples.xl, model.xpl, web.xml  and xhtml files located within your orbeon resource apps.

Console Menu Links/Navigation Components

Apps-list.xml - out of the box lists all the orbeon samples in the left navigation menu when you view orbeon web app in web browser.  Modify this file and comment out Orbeon samples and add your applications. 

How is apps-list.xml used?  

The apps-list.xml file is imported into theme-plain.xsl and used to create the menu list within our web console.  In order to display only those resources the logged in user has access to, apps-list.xml was modified to include a ‘role’ attribute on the sections element and the applications element.  The section element is the heading within the menu and the application element is the actual web application resource underneath each heading.  User roles are placed within the role attribute separated by a space.  If a user is authorized to have access to an application within our web console, then the user’s role must be placed within this role attribute within apps-list.xml.
    Theme-examples.xsl and {YourApplicationName}.xhtml - Theme-examples.xsl provides the formatting for all xhtml files within our console.  If you wish to apply a different theme, you can place a theme.xsl file with your required format at the root of each application located under the resources/apps directory.  Currently, the only application in our list of orbeon resource applications that uses a modified theme (theme.xsl) is the java-authentication application that comes with Orbeon.  You can use Orbeon's theme-plain.xsl as a starting point and modify it to suit your needs.  Since the user is not logged in at this point, no menu items should be displayed.  If you want to alter how the login screen appears, modifications to this theme.xsl and/or the appropriate xhtml file is required. 

    Before an application's xhtml file is presented to the user, the file is sent to epilogue.xpl if the xhtml file contains a model element (<model>).  If the xhtml file does not contain a model element, then the file is just presented to the user.  The epilogue.xpl file is located in each applications page-flow.xml file.  The epiloque.xpl file processes the xhtml file.  The xForms processor converts orbeon extensions into html elements.  The epilogue.xpl file calls the theme-plain.xsl file, or your theme.xsl file, and the processed xhtml file is passed as the data input to the theme-examples.xsl.  Therefore, to access the processed xhtml file within the xsl, you traverse the html DOM with /html:head being the root node.  If you view the source code of one of your web pages, this is what is accessible to the xsl file. 

    So how do we get the user's role accessible to the theme-examples.xsl file?

    Within each one of our xhtml files, the users credentials are stored within an instance.  This is explained further in the Access Control section which follows shortly.

                                  <xforms:instance id="security" xmlns="">
                                              <xi:include href="input:data"/>
                                  </xforms:instance>
                      OR
                                  <xforms:instance id="userInfo" xmlns="">
                                              <xi:include href="input:data"/>
                                  </xforms:instance>

    When the form loads and authentication matches a user within our Apache DS LDAP, <xi:include /> is replaced with the login information:

    <xforms:instance id=”security’>
      <request-security>
        <auth-type>FORM</auth-type>
        <secure>true</secure>
        <remote-user>scott</remote-user>
        <user-principal>scott</user-principal>
        <role>user</role>
      </request-security>
    </xforms:security>
    Since the xsl file does not have access to instance data, the user’s role is sent to an xforms output control immediately under the body of the xhtml file.  The style color is set to white so the control’s value is blended in with the background of the form and is not visible to the user.  If you attempt to set the relevancy of the control to false, the value will not be available to the form and therefore not available to the xsl file so that is why we just blend the role with the background color.  The xforms output control has an attribute name set to id.  The value of the attribute is set to role.

    <xforms:output id="role" style="color:white" ref="instance('security')/role" />

    When the xhtml is processed, the xforms output control is converted to a span html element.  This attribute is available within the span html element. 
    <span id="role" class="xforms-control xforms-output" style="color:white">officer</span>

    Since the theme-examples.xsl has access to the html document structure, an xsl variable called role is created with its value set to the xpath expression locating the span element with an attribute named id. 

    <xsl:variable name="role" select="/xhtml:html/xhtml:body//xhtml:span[@id = 'role']" />

    This variable is then used within the left content (list of applications) section of the xsl file to control which ‘Sections’ and ‘Applications’ are displayed to the user based on their role.  The xpath expression within this part of the xsl was modified to include an xpath contains() function which looks at the role attribute we defined within the apps-list.xml file.

    <xsl:for-each select="$applications/*/section[contains(@role, $role)]">
    And
    <xsl:for-each select="application[contains(@role, $role)]">

    So, depending on who logs in, we display only those resources available to them based on their role.



    Application Access Control

    Model.xpl - The model.xpl is called for each xhtml file and is defined within the page-flow.xml.  The model.xpl file is located at the root of each application. 

      <page path-info="/home/" model="model.xpl" view="view.xhtml"/>

      Within the model.xpl file is the orbeon request-security processor.  The request security processor extracts information about the currently logged user from the client request (Tomcat). Its configuration contains a list of roles the application developer is interested in. Only those roles will be listed in the processor's output if the role is present.

      <p:processor name="oxf:request-security">
              <p:input name="config">
                  <config>
                      <role>da</role>
                        <role>vendor</role>
                  </config>
              </p:input>
              <p:output name="data" ref="data" debug="xxxxx"/>
          </p:processor>

      The output of the processor is stored within the security or userInfo instance within each xhtml file as described in the theme-examples.xsl narrative.

      Web.xml - Access control to the applications is provided by adding three sections to the web.xml file:
      •  In <security-constraint> you define which role (with <role-name>) is required to access which part of the application (with <url-pattern>). 
      •   In <login-config> you define how the user will authenticate himself. In other words, what method is used to get the user name and password. This can be done either with a form in an HTML page or with standard HTTP authentication. The names of those methods are: FORM and BASIC. In the example below, the form mechanism is demonstrated
      • In <security-role> the security roles used in <security-constraint> section are declared

      <security-constraint>
              <web-resource-collection>
                  <web-resource-name>User Access</web-resource-name>
                  <url-pattern>/java-authentication/</url-pattern>
                                    <url-pattern>/home/</url-pattern>
                        </web-resource-collection>
              <auth-constraint>
                                    <role-name>vendor</role-name>
                  <role-name>da</role-name>
                                    <role-name>it</role-name>
                                    <role-name>officer</role-name>
                                    <role-name>supervisor</role-name>
                                    <role-name>idcenter</role-name>
                        </auth-constraint>
          </security-constraint>
           
          <login-config>
              <auth-method>FORM</auth-method>
              <form-login-config>
                  <form-login-page>/java-authentication/login</form-login-page>
                  <form-error-page>/java-authentication/login-error</form-error-page>
              </form-login-config>
          </login-config>
           
          <security-role>
                        <role-name>vendor</role-name>
                        <role-name>it</role-name>
                        <role-name>da</role-name>
                        <role-name>officer</role-name>
                        <role-name>supervisor</role-name>
                        <role-name>idcenter</role-name>
          </security-role>

      The user information is retrieved through j_security_check from Tomcat using JNDI Realm with user information and roles stored in Intalio Embedded Apache DS LDAP.  If the user is not authenticated, the page is not displayed. 

      Configuration Summary

      The displaying and/or hiding of menu items in the navigation bar is not intended to be security, but rather to clean up the user interface so applications a user does not have authorization for do not clutter up the screen and/or confuse the user. 

      The log-in form with Tomcat Form Based Authentication using JNDI Realm (Apache DS LDAP) are to provide access control to our resource applications.  So if a user writes down a URL they see from another users web browser, even if they do not see the menu link based on their assigned role, they will be displayed with an access denied error page if their credentials/role does not match with the web.xml configuration file.

      This information is provided by BTM Software Solutions.

      Monday, March 14, 2011

      Intalio with Orbeon XML Validation Service

      I recently created an XML validation service using Orbeon to validate XML sent into a business process. The Intalio business process retrieves the XML from eXist XML database and then I call a REST service. The REST service is actually an orbeon webapp that consists of an XPL file with several processors (validation processor and xsl processor) included within the XPL file.  If the XML is valid, the REST service sends back an empty error message and the process proceeds.  If the XML is invalid, the validation processor marks the element that is invalid with an error element <v:error> with some descriptive information.  Before sending back the message to Intalio I transform the validation XML output to only include information about the error.  The XML error message contains information about the XML document, the parent node of each error so user knows which element(s) contains the error, the value of that node(s) and the message contained within the <v:error> element(s) sent back from the Validation processor.  The Intalio process then sends an HTML formatted email to the user.

      Example of email:


      Message: The complaint you submitted has the following errors. Please correct these errors and then resubmit your complaint.
      OTN: R04-12345
      Officer: Police Officer1
      Department: X Regional Police Department
      Defendant: Kitty Meow
      PersonSexCode: XN Error the value is not a member of the enumeration: ("U"/"F"/"M")

      This solution was developed by BTM Software Solutions.  Our web-site address is http://BTMSoftwareSolutions.com for more information.

      Thursday, February 3, 2011

      XML and DOBA Products for E-Commerce

      I recently created an advertisement and product listing site at http://BTMDeals.com.  Some of the products I list on my site come from a wholesale provider company called Doba.  Using my background in XML, Xpath, and XSL I have come up with some creative ways to more efficiently update my web-site and list products in other marketing forums, including an Feed.  Using some common open source products, I can manipulate the Doba watchlist data export to be represented in many different formats and easily uploaded or copied to sites, RSS Feeds, e.

      In the upcoming months, I hope to embark on developing an e-commerce site from scratch based on open source standards and using the technologies that I have come to learn in automating some of the mundane tasks that consume a significant amount of time for e-commerce site owners on a low budget and tight schedule.  As things progress check back often to see any new posts.  Or subscribe to this feed and look for feed titles including Doba and e-commerce.

      If you are a current Doba customer and would like to know if some of these technologies could make your e-commerce business more efficient, please contact me at BTMSoftwareSolutions.com.

      Wednesday, November 24, 2010

      RESTful Service From Email Using Orbeon to Intalio

      In a previous blog, I wrote about how you could use Intalio REST Connector to call an LDAP service created in Orbeon XPL.  In this blog I take a different tactic in using Orbeon and Intalio to meet a clients needs.

      The client project entailed creating a reminder/alerting service using Intalio as the business rules service.  If a timer expires before an updated message comes in to the process, emails are to be sent out to staff and manager.  In the email, they wanted the capability of checking a box and replying to the email which would end the Intalio Process for monitoring that case if monitoring was no longer required.  So this is what I put together for them using Intalio and Orbeon.

      When the email is sent, I format the body of the email using Intalio bpel:doXSLTransform function and in the xsl include HTML and values from the process.  As part of the html email I include a link which is formatted to call an Orbeon XPL file - a RESTful service.  In the url is the location of the service and the necessary parameters.  An example of the url format is below:

      http://{ip}:{port}/orbeon/{appName}/{pagePath}?{parameter1}={value}&........

      So, all this does is call the xpl file location which does the following.
      1. First we use an xsl processor to take the parameters from the url and put them in the pattern required by the delegation processor.
      2. The output of the xsl processor is passed to the input for the call of the delegation processor.  The delegation processor is configured to call Intalio Web Service.
      3. Intalio receives the message and responds back with the results, which in the case is just that the message was received.
      4. An xsl processor takes the result from the delegation processor and displays that result in the users browser.
      So, in this example we were able to call a web service (in this example the service endpoint was located in Intalio as part of a business process) from within an email using orbeon as the RESTful service provider.

      Thinking outside the box, Orbeon components were used without displaying one single xForms to add functionality to our process.

      If you would like more information or would like to implement something similar in your organization, contact us at http://btmsoftwaresolutions.com.

      Sunday, November 14, 2010

      Intalio - Orbeon Email Service

      In a previous post I provided an example of how you could combine Orbeon and Intalio using rest to retrieve information from an LDAP and use it within a business process.  In this post I will describe a completed email service using this approach with the ability to send in multiple LDAP filters and send multiple emails.

      The concept was as follows - allow a process or a user to send in multiple LDAP filter criteria and send emails to all those users returned from the service.  For example, a process may want to send an email to not only one user (cn='userID'), but also that user and a everyone with the title supervisor (title='supervisor'). 

      Email service explained.

      Email service contract expects the following:
      1. A subject for the email
      2. A body for the email (can send in a nicely formatted HTML)
      3. The LDAP attribute(s) you want to filter and the value(s) - 1 to many
        • cn, userID
        • title, supervisor
      The process first counts the number of LDAP parameters being sent in and sets an in process variable to this value - $countFilters.  This variable is set within a main looping sub-process.  The main sub-process exits only when the number of loops equals the number of $countFilters.  We also set a variable $ldap to yes and the $mainLoop variable to 1.  Finally we set a variable $countNodes to 0.  This tells this email sub-process (explained next) gateway whether to call the LDAP REST service.  If $ldap set to yes, the LDAP Service is called.  If set to no, then bypass the LDAP service.

      The process then enters another sub-process (email sub-process).  The first thing this process does is set the in process variable $countNodes to $countNodes +1.  Remember $countNodes is set to 0 by default in the main sub-process because if we have multiple LDAP parameters being sent in, when the email sub-process is completed we may have to start all over again so we have to reset $countNodes.  This email sub-process will only exit when $countNodes equals count(result)  - the xpath function count() of the result nodes returned from the LDAP Rest service.  Next a gateway evaluates the $ldap variable and since we set it to yes, we call LDAP REST service.  We pass in the first filter by using the Intalio data editor and then in process variable $mainLoop to select the node position.  So, params/attribute[$mainLoop] and params/filter[$mainLoop].  LDAP returns 1 or more user information and then we start sending emails.  We use the $countNodes variable to iterate through all the potential results.  So to get the first email, we say results/result[$countNodes]/attribute[name='mail']/value.  This gives us the first person's email.  After the email is sent, we set the $ldap variable to no, because we do not need to call ldap again at this point.  If more emails are to be sent, we loop back in the email sub-process, do not go LDAP REST service because we set $ldap to no and $countNodes is now set to 2.  The next email will be sent.  If there are no emails, then $countNodes = count(result) and we exit the email sub-process.  But, if we sent in more then one LDAP filter, we loop back to the very beginning of the main sub-process because $countParams does not equal count(params).  We also set $mainLoop to 2 and $ldap variable to yes because we need to call the LDAP REST service again to get new user(s) information.  So, we take the next LDAP filters based on node position the user sent in and start the entire email sub-process over.  When email sub-process completes again, if $mainLoop = count(params), then we exit the main sub-process and the email service ends.

      You can call this email service from within an existing business process designed in Intalio or an external system since the email service generated in Intalio provides you with a WSDL.  So for example, you could call this email service from within Orbeon.

      If you would like to implement something similiar in your organization, contact BTM Software Solutions for more information.

      Friday, November 12, 2010

      LDAP connector using Orbeon and Intalio

      In my business processes that I develop for customers they often want email notifications sent for alerts and or events that happen along the business process.  The user information is stored in Apache DS LDAP so the trick is getting the data in the process to be used for html emails.  I came up with a solution several months back which involved using openESB and their LDAP Binding Connector (BC) to create a composite application deployed on Glassfish Server.  The Trigger was an HTTP SOAP call which passed information to the LDAP BC and returned the desired results.

      Even though this solution got the job done, you had to download openESB, develop the composite application in Netbeans, deploy the process to GlassFish Server, etc.  More tools, possibility for errors, something else to learn, something else to support and servers running just for basic LDAP information.

      The product I use for Business Process workflow is Intalio.  And although they currently do not have an LDAP Connector, they do have a REST connector.  Another product I use is Orbeon xForms.  Orbeon does have the ability to query an LDAP through XML Pipe Line (XPL).  So how do these technologies get me my LDAP information into a Intalio Business Process without having to add Netbeans, openESB, Glassfish to my toolbox.  Let me share.

      Orbeon page-flow controller can be called from within your browser - http://localhost:8080/orbeon/ldap/rest.  If you want to filter your LDAP response, then add the parameter to your url - http://localhost:8080/orbeon/ldap/rest?cn={value}.  In the page-flow controller, construct a page element /ldap/rest and a default submission to extract the parameter from the url.  You have to create an xml file to hold these parameters.  The submission will call the ldap.xpl file which I first pass into a xsl processor to construct the filter dynamically for the ldap process.  I pass the xsl processor output to the ldap processor filter configuration.  You can build a test case and test it from your browser.  There is your RESTful LDAP service.

      So how do you integrate this with Intalio.  Well, like I said, Intalio has a REST Connector.  Take your url statement above and using Intalio REST wizard create the RESTful service in intalio.  Drop the WSDL in your process and map your elements (input parameter and response message).  You are done.  Your process will call your end point url, which will call Orbeon XPL file and return the results to Intalio.  No need to install more servers and other tools.  I just use Orbeon and Intalio.

      One note, the xml returned by Orbeon is in an empty namespace.  Intalio mapper will not recognize the variable without a namespace.  So, I had to add one more layer of transformation within the Orbeon XPL file.  After the LDAP response is returned, I pass this output to one final XSL Processor and include a namespace in the root of the xsl - xmlns="http://example.com/rest".  Then when intalio gets the data, a namespace is present and you can map the results in your business process to send out emails.

      Another tip is to use xsl within the process to pass html into the body of the email service so your clients get nicely formatted email messages.

      If you would like assistance on integrating this solution into one of your projects contact me at http://BTMSoftwareSolutions.com.