ZideStore & Free/Busy

Zidestore, the OpenGroupware integration server, can provide free/busy information for groupware users to clients via an HTTP request; this information can be provided in iCal VFREEBUSY format or in XML (Exchange's free/busy "map" format).

This information has now been integrated into WMOGAG.

The free/busy information request URL is: "http://{server:port}/zidestore/so/freebusy".

The data returned depends upon the parameters passed this this request. Both XML and iCalendar requests support "start" and "end" parameters which determine the date range of the free/busy information returned to the client. The date values must be presented in "%Y%m%dT%H%M00Z" form. The date "December 21st, 2005" would be written as "2005-12-21", if you wished to indicate a time (say 5:00pm) as well as a date you would specify "2005-12-21T17:00:00". Both the hour and minute are relevant to the data returned but the seconds field, while it must be specified, is discarded. The specified time must be in GMT, ZideStore does not appear to support specifying a timezone within the parameter (something like: "2005-12-21T17:00:00-10:00").
If no time is specified then the GMT time of "00:00:00 is assumed for both start and end. So a query for an iCalender free/busy with a start and end of: "start=2005-12-20&end=2006-01-15" returns a VFREEBUSY with a DTSTART of "20051220T000000Z" and a DTEND of "20060228T175600Z".

If no start and end time is specified then 121 days of free/busy information is returned, sixty days previous to the current date and sixty days forward from the current date. For instance, if the current date is 2005-12-29 then the free/busy information from 2005-10-29 through 2006-02-28 is returned. If only a start date is specified then from that day through 60 days forward from the current date is returned. If only an end date is specified then from 60 days previous to the current date through that date is returned.

For an iCalendar format response format the name of the user for which you desire free/busy information into two parameters: "name" as the left part of the e-mail address and "server" as the right, or domain, portion of the e-mail address. The username specification for an iCalendar request will look like "name=awilliam&server=whitemice.org" for a user whose e-mail address is "awilliam@whitemice.org". So the request for free/busy information for this user would look like: "http://{server:port}/zidestore/so/freebusy?name=awilliam&server=whitemice.org&start=2005-12-01&end=2006-01-15"

An iCalendar Free/Busy response will look something like:
PRODID:-//OpenGroupware.org/ZideStore 1.3//

For an XML response format the username as a parameter named "u" with a value of the accounts e-mail address, like "u=awilliam@whitemice.org". The XML format request also supports an "interval" parameter. Interval specifies the resolution of the response in minutes and if not specified defaults to 30. A request for XML free/busy information for this user would look like: "http://{server:port}/zidestore/so/freebusy?u=awilliam@whitemice.org&start=2005-12-01&end=2006-01-15&interval=30"

An XML Free/Busy reponse will look something like:

<a:response xmlns:a="WM">
<a:item><a:displayname>adam@morrison-ind.com</a:displayname><a:email type="SMTP">adam@morrison-ind.com</a:email><a:type>1</a:type><a:fbdata>000000000...</a:fbdata></a:item>

In the XML response the "item" tag encloses the information as to whom the encoded free/busy information applies, and the "fbdata" encloses the free/busy map. The "item" is enclosed in "recipient" tags and both the free/busy map ("fbdata") and "recipient" are enclosed in "response" tags. Each character in the "fbdata" represents an interval of the prescribed length. A value of "0" indicates that the interval is free while a value of "2" is used by ZideStore to indicate that the interval is busy. According to the specification (Microsoft article 813268) this is not entirely correct as "2" should indicate tentative and "1" should indicate busy ("3" indicates "Out Of Office" and "4" indicates "Data not available").

The username for a free/busy request must be the first or primary e-mail address ("email1"). For example my "email1" is "adam@morrison-ind.com" and my "email2" is "awilliam@whitemice.org". Requesting "name=adam&server=morrison-ind.com" or "u=adam@morrison-ind.com" works while "name=awilliam&server=whitemice.org" or "u=awilliam@whitemice.org" does not.

If the "u" parameter or "name" and "server" parameters do not resolve to a known user an error does not occur, but either a 'blank' VFREEBUSY (no FREEBUSY lines) or entirely free fbdata map is returned. An incorrectly structured URL where the server cannot determine the username to search for results in XML format free/busy information for the currently authenticated user. For example both "?user=fred&server=morrison-ind.com&start=2005-12-01&end=2006-01-15" ("user" instead of "name") or "ud=fred@morrison-ind.com&start=2005-12-01&end=2006-01-15" ("ud" instead of "u") will result in XML free/busy data for the currently authenticated user.

Note:This document is derived from Helge Hess' Free/Busy page in the OpenGroupware documentation plone.


Reading an XML attribute via BIE's "Assign" action

You can use the "Assign" action in BIE to retrieve the contents of an element or attribute of an XML document (or "message" in BIE-speak). But if you try to retrieve the value of an element in a document like -

<root attribute="value"><parameter name="id">1</parameter></root>

- via the obvious XPath of "/root/@attribute" you will get a "BIE INTERNAL ERROR". The workaround is to do something like this: "concat(/root/@attribute, '')".

According to Mr. Fruetel it seems as though the "Assign" action gets confused with attributes and doesn't know whether to return text or an XMLNode; by doing the "concat" operation the result is forced to be text and everything works as expected.

Note: This situation and example is taken from a thread on the bie-developer list.


The Hypersonic Client

Within BIE is an internal Hypersonic database that contains configuration, state, and audit information. The actual messages and data used by workflows is stored in an internal eXist database. It is occasionally useful to access the internal Hypersonic database to perform maintenance or correct an error; fortunately BIE contains an embedded GUI Hypersonic client.

Before starting the database client you should shut down BIE. Hypersonic in BIE operates in an in-memory mode and does not support multiple connections. Then to start the client -

$ export BIE_HOME=/usr/local/BIE
$ java -Xmx1536m -cp $BIE_HOME/services/jboss/server/default/lib/hsqldb.jar \

The client requires a GUI display so if you are accessing the server via SSH remember to include the -X option unless you have X11 forwarding enabled by default. The -Xmx1536m parameter specifies that the JVM can allocate up to 1,536 megabytes of RAM. If your Hypersonic database is very large you may need to allocate a significant amount of RAM in order not to encounter out-of-memory type errors during operation.

Note: If you are accessing the server from an M$-Windows client you are out of luck as Microsoft has chosen not to support the ubiquitous and extremely useful X11 protocol or display technology - so you will not be able to use the client. Please install a real operating system.

Once the client starts you must enter the connection information so that the client can locate the database. The login dialog looks like this.

Type: “HSQL Database Engine In-Memory”
Driver: org.hsqldb.jdbcDriver
URL: jdbc:hsqldb:/usr/local/BIE/services/hypersonic/BIE
User: sa
Password: BIE

Note: The URL of the database depends on where you installed BIE. This string is really $BIE_HOME/services/hypersonic/BIE.

If the parameters you entered were correct then the Hypersonic client window should appear. if the Hypersonic database is very large it may take a few minutes for the window to become responsive even on a very powerful machine - Hypersonic does not seem to deal well with very large datasets.

Compacting the database
A very common use of the client is in order to compact the database. If the BIE database gets large you will notice that the $BIE_HOME/services/hypersonic/BIE.data file does not reduce in size even if routine maintenance is in place. Hypersonic, much like other databases, does not release allocated space back to the filesystem even if the amount of data in a table or database is reduced. But you can instruct Hypersonic to reogranize the database with a SHUTDOWN COMPACT command from the client. This should reduce the size of BIE.data.

Note: You must do this while the BIE service is stopped.

A guide to Hypersonic's SQL syntax is available here.


Using LDAP's extensibleMatch

One of the beauties of LDAP is how simply it lets you perform searching. The various attribute hint how to intelligenly perform searches such as case sensitivity with strings, wether dashes should be treated as relevant characters in the case of phone numbers, etc... But sometimes you might need to override this intelligence and make your search more or less strict, like as in the case of case sensitivity of a string. That is the purpose of the extensibleMatch.

Look at this bit of schema:

attributetype ( NAME 'name'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX{32768} )
attributetype ( NAME ( 'sn' 'surname' )
DESC 'RFC2256: last (family) name(s) for which the entity is known by'
SUP name )

The "caseIgnoreMatch" means that searches on attribute "name", or its descendent "sn" (as in inetOrgPerson), are performed in a case insensitive manner. So...

estate1:~ # ldapsearch -Y DIGEST-MD5 -U awilliam sn=williams dn
SASL/DIGEST-MD5 authentication started
Please enter your password:
SASL username: awilliam
SASL installing layers
# Adam Williams, People, Entities, SAM, whitemice.org
dn: cn=Adam Williams,ou=People,ou=Entities,ou=SAM,dc=whitemice,dc=org
# Michelle Williams, People, Entities, SAM, whitemice.org
dn: cn=Michelle Williams,ou=People,ou=Entities,ou=SAM,dc=whitemice,dc=org

... this search returns two objects where the sn value is "Williams" even though the search string was "williams".

But if for some reason we want to match just the string "Williams", and not the string "williams" we can use the extensibleMatch syntax.

estate1:~ # ldapsearch -Y DIGEST-MD5 -U awilliam "(sn:caseExactMatch:=Williams)" dn
SASL/DIGEST-MD5 authentication started
Please enter your password:
SASL username: awilliam
# Adam Williams, People, Entities, SAM, whitemice.org
dn: cn=Adam Williams,ou=People,ou=Entities,ou=SAM,dc=whitemice,dc=org
# Michelle Williams, People, Entities, SAM, whitemice.org
dn: cn=Michelle Williams,ou=People,ou=Entities,ou=SAM,dc=whitemice,dc=org
search: 3
result: 0 Success
estate1:~ # ldapsearch -Y DIGEST-MD5 -U awilliam "(sn:caseExactMatch:=williams)" dn
SASL/DIGEST-MD5 authentication started
Please enter your password:
SASL username: awilliam
search: 3
result: 0 Success
estate1:~ #

So we were able to match the value of "sn" with our own preference as to case sensitivity. The system for an extensibleMatch is "({attributename}:{matchingrule}:{filterspec})". This can be used inside a normal LDAP filter along with 'normal' matching expressions.

For more information on extensibleMatch see RFC2252 and your DSA's documentation.