Sunday, April 8, 2012

IBM ED Search for Android - Part 1

I've decided to write a series of blog posts about my Android App "IBM ED Search" to explain basic usage and some more advanced topics.

The series will use version 2.0 that will be released real soon now.

In this first post I will focus on the very basics of the application.

Let's begin...

Initial Steps and the Search UI


Version 2 makes use of the excellent Actionbar Sherlock library that makes the Android Ice Cream Sandwich Action Bar available on earlier Android versions. The UI looks and feels very similar on devices running Android 2.2 up to the latest version 4.0.

After starting the app for the first time the home screen is shown. The action bar is located at the top and includes a small magnifying glass icon on the right hand side.
A short introduction is shown below the action bar when the app is started for the first time and as long as no searches have been "starred".



In order to search the directory an https connection to the IBM Intranet must be available. Lacking a VPN connection you will need to be on the Intranet WLAN to conduct any searches.

Tapping the icon on the right hand side of the action bar will reveal the search field directly in the action bar. You can now enter the search term you want to search for.



When the search field is shown another icon is appears  to the right of the search field. Tap it to choose the search category/type. A menu will open up to let you choose among different search types like searching for people's name, serial number, bluegroup by names and some more. Pick the search type from the menu and the search field will display a hint in grey on how the search value must be formatted.



The keyboard will show a search button instead of the "Enter" key. Tap it to begin the search.

When all is well and the directory server can be reached the search result will be displayed on a new screen. All matching persons or bluegroups (depending on what type of search was chosen) will be displayed in a list.

The People Search Result Screen

The action bar now shows the search type (e.g. Name) and the search term (e.g. Hofmann, Thomas) and the number of results in brackets.

The list on this screen will include important information about the persons that match the search term, like name, email address, telephone number and job role. In addition, the bluepages person image is displayed on the left hand side.
Person pictures are not loaded along with the search result. Depending on the preferences the application will either load some, all or none of the person pictures belonging to the persons in the result after the result is already displayed.

Tap the "Load Pictures" icon in the action bar on the bottom of the search results screen to trigger the loading of missing pictures (tap and hold the action icons to see a tooltip about what they do). A progress bar at the top of the screen will report download progress.



Use the "Star" icon to "star" a search result. What this means is that you want to keep the search result's content for offline usage. Once starred, it will appear in the list on the home screen and can be recalled even without a connection to the directory server.

Touching and holding an entry in the search result will open a context menu where you can choose different actions in the context of the entry like, dialing the phone number of the person, sending an email or conducting a search for e.g. the management chain of the person in that entry. The menu is rather long. Make sure you scroll down to see every possible action.



Tap the back key to return to the home screen. As an alternative you can also tap the application icon on the top left hand side of the action bar. This will always bring you back to the home screen no matter how deep inside the application you were navigating.

Back on the home screen the introduction text is now replaced by the list of starred search results. Tap it to return to the list of persons that were included in the search result.



The context menu of an person entry in a search result also allows you to star persons. All persons starred will appear on the home screen under the "Starred Persons" list entry (which will always be the first entry). This way you can pick the ones you want to have available for offline usage and quick access.



Friday, April 16, 2010

Equinox Aspects to the Rescue - Patching non-intrusive

For my current project I implemented synchronization between Rational Team Concert (RTC) and Rational Clear Quest (CQ) using the Clear Quest Connector.

The development team uses RTC as its primary tool to work with defects and work item whereas the test team and the customer is using the CQ web client.

Due to a limitation in the CQ Connector all comments in a defect made in RTC are synched to CQ with the user ID of the CQ Connector. As a consequence, the users of the CQ web client are unable to determine who has made a comment.

I created an enhancement request which unfortunately won't be implemented.

So I thought I should roll my own solution to this problem.

Being a fan of AOP and AspectJ, I thought I could use Equinox Aspects to intercept the call where the comment is saved and simply prepend the username. In fact it was just as easy. I only needed to figure out how to use AspectJ with Equinox Aspects in my eclipse installation. The following two guides helped me:

The first thing to do was find a place in the code where I could easily apply my change. I downloaded the RTC SDK and loaded the bundles into a fresh workspace using the target definition supplied in the SDK so that I could browse and search the codebase using eclipse's features like determining call hierarchies etc.

I was looking for a (central) place that would be sufficient to intercept for all comments added. I quickly found such a place in the code in the model class com.ibm.team.workitem.common.internal.model.Comments.

The method I picked looks like this:

public IComment createComment(IContributorHandle creator, XMLString content) {
  Comment comment= ModelFactory.eINSTANCE.createComment();
  Utils.initNew(comment);
  comment.setCreator(creator);
  comment.setContent(content.getXMLText());
  return comment;
}

Looking at the call hierarchy for this method reveals that it is called from various places in the Eclipse UI and also on the server side (the REST services).



Everything I need for the modification is right there - the content of the comment and the creator. I created the following pointcut to match the code:

public pointcut createCommentMethodToIntercept(IContributorHandle creator, XMLString content, IComments comments) :
 
    execution(public IComment Comments.createComment(IContributorHandle, XMLString))
    && args(creator, content)
    && target(comments);

I am extracting the creator, the content and the comments object here.

The actual modification is done using an around advice:

@SuppressWarnings("restriction")
IComment around(IContributorHandle creator, XMLString content, IComments comments) : createCommentMethodToIntercept(creator, content, comments) {
  try {
    Comments concreteComments = (Comments) comments;
    if(shouldApply(getWorkItemType(concreteComments))) {
      ContributorImpl contributorImpl = (ContributorImpl) creator.getFullState();
      String userId = contributorImpl.getName();
      String xmlText = content.getXMLText();
      System.out.println("Original content: " + xmlText);
      content = XMLString.createFromXMLText(userId + ": " + xmlText);
      System.out.println("Replaced content: " + content.getXMLText());
    }
  } catch(ClassCastException e) {
    e.printStackTrace();
  }
  return proceed(creator, content, comments);
}

Since the modification should only affect defects that are synched to ClearQuest I am calling the getWorkItemType method which makes use of the comments object:

private String getWorkItemType(Comments comments) {
  WorkItem workItem = comments.fWorkItem;
  String workItemType = workItem.getWorkItemType();
  System.out.println("WorkItem type: " + workItemType);
  return workItemType;
}

The shoulApply method just checks a system property for a list of work item types that should be affected.

The aspect is then applied to the bundle containing the Comments class which is com.ibm.team.workitem.common by specifying the following line in the manifest file of the plug-in containing the aspect:

Eclipse-SupplementBundle: com.ibm.team.workitem.common

Basically, this is all that needs to be done.

Now, when I add a comment to a defect that gets synched to ClearQuest my name is prepended to the comment:




Of course, Equinox Aspects must be installed correctly and running the weaving hook for the aspect to be applied at runtime.

On the server side RTC also employs OSGI and bundles through a servlet bridge. Unfortunately, I wasn't able to get the aspect applied there.

Saturday, March 7, 2009

Apache and Subversion and LDAP again

I just noticed that Jeremy Whitlock updated his article on Subversion with Apache and LDAP. This might be interessting to you in case you came here for my post on the same subject.

Saturday, September 27, 2008

Installing Subversion on Windows Server with Apache HTTP Server, SSL, Active Directory Authentication and Log Rotation

Necessary Software

First you will need to get hold of the software itself.
  • Subversion can be downloaded at tigris.org. This is the direct link to the installation packages. This guide assumes you download the Subversion binaries for Win32 as zip file and not as installer (at the time of writing the appropriate package is name svn-win32-1.5.2.zip)

  • Since we want to use SSL for communication with the subversion repository we need a Win32 binary of Apache HTTP server that has SSL support compiled in. This site has them. At the time of writing the latest 2.2.x release available is httpd-2.2.9-win32-x86-ssl.zip. The Microsoft Visual C++ 2008 Redistributable Package (x86) is needed to run the Apache binaries.
    Note that for Apache 2.0.x you will need a different svn distribution since the Subversion Apache modules need to be linked to a specific Apache version.

Installation

Subversion

Subversion is installed by simply unzipping the contents of the zip file (see above) to a directory of your choice. For this guide the directory c:\Program Files (x86)\Subversion is assumed to be the installation directory. A directory name that does not include the version number has the benefit that a new version of Subversion can easily be installed by overwriting the older version files.

In order to use the Subversion executables from the command line (like svnadmin for administering a repository) it is recommended to not add the c:\Program Files (x86)\Subversion\bin directory to the computer's PATH environment variable. The problem that might occur if you do so is that DDLs like ssleay32.dll and libeay32.dll that are part of the Subversion distribution might conflict with other versions of these libraries installed by other applications.

Apache HTTP Server

The Apache HTTP Server is installed by unzipping the contents of the zip file to a directory of your choice. For this guide the directory c:\Program Files (x86)\Apache2 is assumed to be the installation directory. Again, upgrading can be done by replacing the files in that directory.

Configuration

Apache HTTP Server

The official Apache HTTP Server documentation can be found here . The platform specific notes for Windows are especially interesting for this guide.

Basic Setup

Apache uses config files found in the conf subdirectory of the Apache installation. For the purpose of this guide only the httpd.conf, http-ssl.conf and http-dav.conf files are of interest.

The first thing to do is to adjust the path directives in httpd.conf. By default, all paths point to c:/Apache2. If you decided to install into this directory you can skip this step. Otherwise all paths directives to c:/Apache2 need to be replaced with c:/Program Files (x86)/Apache2 . Notice that the original config file uses forward slashes as path separators. Apache understands both forward slashes and backslashes but the rotatelogs program used for log rotation only recognizes the forward slashes as path separator so using them everywhere will yield a more uniform configuration file. There should be nine places (not including the comments) where the path needs to be changed.

Next, the Listen 80 directive should be changed to the port you want the server to listen to for non SSL requests. For this guide it is changed to 12080.

The following directives should also be adjusted to make sense for your installation: ServerAdmin and ServerName.

Integrating Subversion

Subversion is integrated into the Apache HTTP Server using two modules that are part of the Subversion distribution. The two modules need to be enabled in the httpd.conf file. Add the
following two lines to the Dynamic Shared Object (DSO) Support section:

LoadModule dav_svn_module "c:/Program Files (x86)/Subversion/bin/mod_dav_svn.so"
LoadModule authz_svn_module "c:/Program Files (x86)/Subversion/bin/mod_authz_svn.so"
These two modules need the DAV module that comes with Apache HTTP Server. Uncomment the following line:
LoadModule dav_module modules/mod_dav.so
Next, an URL needs to be defines to access the repositories. This is done using the following Location directive:

<location>
DAV svn
SVNListParentPath on
SVNParentPath "c:/svn"
</location>

Details about the Subversion-specific directives can be found in the subversion book . SVNParentPath points to the location of the repositories to expose using the /svn URL.

Enabling SSL

Configure SSL Modules
Uncomment the following line in the Dynamic Shared Object (DSO) Support section:
LoadModule ssl_module modules/mod_ssl.so
Generating a Self-Sign Certificate

A certificate is needed for SSL communication. It can either be a certificate issued by a trusted Certification Authority (CA) or one created yourself (a so called self-signed certificate). This guide assumes that a self-signed certificate is to be used and thus must first be generated.

The following command executed in the bin directory of the Apache HTTP server installation directory will generate a certificate named server.crt that is valid for ten years (3650 days).

openssl req -new -x509 -nodes -days 3650 -out server.crt -keyout server.key -config ../conf/openssl.cnf

When you run the command from a command window you will be prompted for details about the certificate like name of your organization, country and so on. This information will be stored into the certificate and later be available to the clients accessing the Apache HTTP Server using https/SSL. Make sure you specify the same name as CN (common name) when you are generating the keys as the one in ServerName in the config files. Otherwise, Apache will not start with SSL enabled.

The process also generates a private key file called server.key which is the private key used to sign the certificate created. OS-level access rights should be used to restrict access to the file.

Enabling SSL Mode

All SSL relevant settings are stored in httpd-ssl.conf. This file needs to be adjusted next. Again, the path to the actual installation needs to be changed like the httpd.conf file before.

The next thing to adjust is the Listen 443 directive. Change it to Listen 12443 to use 12443 as the SSL port (of course you may use different values for your setup).

The SSL Virtual Host Context section needs to be adjusted to match your installation. Like you did before in httpd.conf change the ServerName and ServerAdmin directives. The default port number of 443 also needs to be changed to 12443 everywhere.

The certificate created before is referenced in http-ssl.conf using the directives SSLCertificateFile and SSLCertificateKeyFile. Change it to point to the files created before (move them from the bin to the conf directory before):

SSLCertificateFile conf/server.crt
SSLCertificateKeyFile conf/server.key

Now, uncomment the following line in httpd.conf:

Include conf/extra/httpd-ssl.conf

The last step is to tell Apache to use the SLL mode. This requires passing the -D SSL start parameter when starting the server. See how this is done below.

Configuring Log File Rotation

Log files should not grow infinitely. The rotatelogs.exe program that comes bundled with the Apache HTTP Server can be used to implement log rotation. The relevant directive are found in httpd.conf and httpd-ssl.conf.

Replace the following directives in httpd.conf :
ErrorLog "logs/error.log"
with this one
ErrorLog '|"C:/Program Files (x86)/Apache2/bin/rotatelogs.exe" "C:/windows/system32/LogFiles/Apache2/error_%Y-%m-%d-%H_%M_%S.log" 10M'

CustomLog "logs/access.log" common
with this one
CustomLog '|"C:/Program Files (x86)/Apache2/bin/rotatelogs.exe" "C:/windows/system32/LogFiles/Apache2/access_%Y-%m-%d-%H_%M_%S.log" 10M' common

Replace the following directives in httpd-ssl.conf in the SSL Virtual Host Context section:
ErrorLog "logs/error.log"
with this one
ErrorLog '|"C:/Program Files (x86)/Apache2/bin/rotatelogs.exe" "C:/windows/system32/LogFiles/Apache2/ssl_error_%Y-%m-%d-%H_%M_%S.log" 10M'


CustomLog logs/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
with this one
CustomLog '|"C:/Program Files (x86)/Apache2/bin/rotatelogs.exe" "C:/windows/system32/LogFiles/Apache2/ssl-request_%Y-%m-%d-%H_%M_%S.log" 10M' \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

TransferLog logs/access_log
with this one
TransferLog '|"C:/Program Files (x86)/Apache2/bin/rotatelogs.exe" "C:/windows/system32/LogFiles/Apache2/ssl_access_%Y-%m-%d-%H_%M_%S.log" 10M'

Authentication using Active Directory

To use Active Directory for authentication when a request is made to access a Subversion repository it is necessary to add the following two lines to load the necessary modules:

LoadModule ldap_module modules/mod_ldap.so
LoadModule authnz_ldap_module modules/mod_authnz_ldap.so

The Location directive added above needs to be augmented by the following lines:
Require valid-user
AuthType Basic
AuthBasicProvider ldap
AuthName "Subversion repositories"
AuthLDAPBindDN CN=LDAP,CN=Users,DC=somedomain,DC=com
AuthLDAPBindPassword xxxx
AuthLDAPURL "ldap://server1.somedomain.com:389/cn=Users,dc=somedomain,dc=com?sAMAccountName?sub?(objectClass=*)"
AuthzSVNAccessFile c:/svn/svn-access.txt

so that it looks like this:

<location>
DAV svn
SVNListParentPath on
SVNParentPath c:/svn
Require valid-user
AuthType Basic
AuthBasicProvider ldap
AuthName "Subversion repositories"
AuthLDAPBindDN CN=LDAP,CN=Users,DC=somedomain,DC=com
AuthLDAPBindPassword xxxx
AuthLDAPURL "ldap://server1.somedomain.com:389/cn=Users,dc=somedomain,dc=com?sAMAccountName?sub?(objectClass=*)"
AuthzSVNAccessFile c:/svn/svn-access.txt
</location>

The LDAP user (AuthLDAPBindDN) and the associated password are necessary in case Active Directory is not configured for anonymous queries.

For authorization via Active Directory take a look at PTEROPUS' blog.

WebDav for File Upload

When there a lot of files to add to the repository it makes sense to do that directly on the server because it is much faster. For this the files to add need to be available on the server. One easy way to provide a file upload possibility for the users that want something imported into the repository by an admin on the server is to provide a WebDav share. Users can then connect to this share using clients that are built-into many operating systems (such as Web Folders on Windows).

To setup WebDav uncomment these two line in httpd.conf:

LoadModule dav_fs_module modules/mod_dav_fs.so

Include conf/extra/httpd-dav.conf
and add the following lines to file httpd-dav.conf:

Alias /svnupload c:/svnupload

<location>
DAV on
Options Indexes
AllowOverride None
Order deny,allow
Allow from all
Require valid-user
AuthType Basic
AuthBasicProvider ldap
AuthName "Subversion Repository Upload"
AuthLDAPBindDN CN=LDAP,CN=Users,DC=somedomain,DC=com
AuthLDAPBindPassword xxxx
AuthLDAPURL "ldap://server1.somedomain.com:389
</location>
This will make the directory c:\svnupload accessible for uploading files using WebDav. The httpd-dav.conf file already contains a sample configuration called uploads which can be removed or commented out.

After the config files have been adjusted it is time to setup the server to run as a service. First, the sytnax of the config files need to be checked by running the command from the Apache bin directory.:

httpd.exe -t

If there are errors reported Apache will not be able to start.

Running Apache as a Windows Service

After the config files have been adjusted it is time to setup the server to run as a service. This can be acomplished by running the following command:
httpd -k install -n "Apache for Subversion"
See the platform specific notes for Windows for more options on installing the service.

This will create a new key in the Windows registry under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ApacheforSubversion. A string value named ImagePath will contain the following value: "C:\Program Files (x86)\Apache2\bin\httpd.exe" -k runservice

Use the registry editor to add -D SSL at the end of this value so that is will look like this: "C:\Program Files (x86)\Apache2\bin\httpd.exe" -k runservice -D SSL to enable the SSL mode.

User Account Setup

By default the Apache HTTPS Server runs under the Local System account when installed as a service. For security reasons it should run using a less privileged account. Use the Windows specific tools to create a new account for the server and the Services console to change the account under which the server is run.

Subversion

Create a repository at the location pointed to before if non exists yet by running:

svnadmin create c:\svn\test

from the Subversion bin directory. This will create a repository test which you should now be able to access via http://localhost:12080/svn/test and https://localhost:12443/svn/test