Building uPortal from source

Posted & filed under howTo.

This document describes how to build and install uPortal 2.5.1 from source and link it to PostgresSQL 8.1.3 and deploy it on Tomcat 5.5.16 with JDK 1.5.0.

The first thing you need to do is download the uPortal source code. Download the uPortal-only package : get it here

Once you’ve got it, unpack it. I’ll assume you’ve unpacked it to /usr/local/src to get:

/usr/local/src/uPortal_rel-2-5-1

We’ll call this UP_HOME from now on.

Next you have to configure uPortal to work with postgres. For this, you’ll need the 8.1.3 JDBC driver : get it here

Download the 8.1 Build 405 driver and put the jar file, postgresql-8.1-405.jdbc3.jar in UP_HOME/lib

Now, edit UP_HOME/build.properties. My tomcat is in /usr/local/apache-tomcat-5.5.16 so I set this:

server.home=/usr/local/apache-tomcat-5.5.16

Locate the section that starts:

#==================== External Dependencies ===========================

comment out the current database driver:

#jdbcDriver.jar=${lib.path}/hsqldb.jar

and add the line:

jdbcDriver.jar=${lib.path}/postgresql-8.1-405.jdbc3.jar

Now open the file UP_HOME/properties/rdbm.properties and edit the postgres JDBC section:

##### PostgreSQL – example
jdbcDriver=org.postgresql.Driver
jdbcUrl=jdbc:postgresql://localhost:5432/uportal
jdbcUser=postgres
jdbcPassword=x

make sure you use your own database!

Now, before you can build from source, you have to add type mappings for postgres 8.1.3. Open the file UP_HOME/properties/db/dbloader.xml and add a type mapping for postgres 8.1.3:

<db-type-mapping>
<db-name>PostgreSQL</db-name>
<db-version>8.1.3</db-version>
<driver-name>PostgreSQL Native Driver</driver-name>
<driver-version>PostgreSQL 8.1 JDBC3 with SSL (build 405)</driver-version>
<type><generic>LONGVARCHAR</generic><local>TEXT</local></type>
<type><generic>VARCHAR</generic><local>VARCHAR</local></type>
<type><generic>LONGVARBINARY</generic><local>BYTEA</local></type>
<type><generic>VARBINARY</generic><local>BYTEA</local></type>
<type><generic>INTEGER</generic>< <local>integer</local></type>
</db-type-mapping>

If you don't add the type mapping exactly as above, for the driver you just downloaded, you'll get the database error:

Your database driver, 'PostgreSQL Native Driver', version 'PostgreSQL 8.1 JDBC3 with SSL (build 405)', was unable to find a local type name that matches the generic type name, 'LONGVARCHAR'.
Please add a mapped type for database 'PostgreSQL', version '8.1.3' inside 'file:/usr/local/src/uPortal_rel-2-5-1/build/WEB-INF/classes/properties/db/dbloader.xml' and run this program again.

If you're using a different version of postgres, make sure you match the driver version string from any error you get with the type mappings you add. Also, don't pay any attention to the file location - update the one in properties/db/dbloader.xml.
Now, create the uPortal database you'll use:

su postgres
createdb uportal

Now, you're ready to build. I built using JDK 1.5 as then you don't have to bother with the endorsed libraries. I also have JDK 1.4 installed so I have to specify which one to use at build time:

export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home
ant initportal

My Tomcat directory is writeable to my user but if your's isn't, you'll have to prefix the ant command with sudo.

This will build, initialise the database, install uPortal and deploy the portlets to /usr/local/apache-tomcat-5.5.16/webapps/uPortal. It also copies the configuration fragment:

/usr/local/apache-tomcat-5.5.16/conf/Catalina/localhost/uPortal.xml

However, before you can start it up, you have to fix a bug. uPortal doesn't work with Tomcat 5.5 due to JNDI Datasource configuration changes. In Tomcat 4.x/5.0.x this is used by uPortal in uPortal.xml:

<Resource name="jdbc/PortalDb" auth="Container" type="javax.sql.DataSource" />
<ResourceParams name="jdbc/PortalDb">

i.e. the Resource is named and then configured separately via a ResourceParams element. In Tomcat 5.5.x, this has changed and ResourceParams is no longer used. Instead, the configuration is specified in the Resource element. So you should replace the two Resource elements in uPortal.xml with the new format:

<Resource name="jdbc/PortalDb" auth="Container" type="javax.sql.DataSource" driverClassName="org.postgresql.Driver" url="jdbc:postgresql://localhost:5432/uportal" username="postgres" password="x" maxActive="20" maxIdle="10" maxWait="-1" />

<Resource name="jdbc/PersonDb" auth="Container" type="javax.sql.DataSource" driverClassName="org.postgresql.Driver" url="jdbc:postgresql://localhost:5432/uportal" username="postgres" password="x" maxActive="20" maxIdle="10" maxWait="-1" />

If you don't do this, you'll see this error in the logs:

Cannot create JDBC driver of class '' for connect URL 'null'

It took me ages to figure that one out.

You can forget about webapps/uPortal/META-INF/context.xml. Tomcat 5.5.x uses conf/Catalina/localhost/uPortal.xml to configure the datasources.

You can now start tomcat and access uPortal from:

http://localhost:8080/uPortal

References:

Tomcat 5.5.x JNDI Datasource HOW-TO

CLAN gets portalised

Posted & filed under CLAN.

I’ve been playing around with Jetspeed to see if I can turn Bodington into a portal thingy. Well, turns out it’s possible and Bodington is now running as a portlet application under jetspeed.

It has a MyModules portlet associated with it. Although it’s called MyModules, the modules won’t work just now so it just displays the groups for a user – in a portlet. More about that in a mo.

You can display this portlet in uPortal via WSRP presumably. In effect, each portlet associated with bod will expose a chunk of bod functionality in whatever portal container supports WSRP.

It’s the same concept as the Guanxi IdP. Bod is wrapped in portlets as well now. Where bod was IdPed without touching a line of code, it’s now portalised without touching a line of code.

Now, for the interesting news. MyModules doesn’t work in a portlet as it has the concept of current user. Portlets don’t have that – they’re “remote” from the application although they can access the bod context.

It could be fixed by changing Minerva to accept a user id instead of finding it from the context. Then the portlet could call Minerva directly and get the modules for a specific user. i.e, LDAP uPortal and use the novell ID of the user to get their modules direct from the CLAN portlet.

Most of the stuff in bod uses the context to get the current user so bod really isn’t ready for portalisation but it can be done. It actually works!

There’s another gotcha. Most of the stuff in bod writes directly to the HttpServletResponse but portlets use RenderResponse so it’s not just a case of sharing responses. There has to be some sort of munging.

No doubt there’s a way round the issues but it should be possible to take each tool in turn and change how it initialises. Abstract it away from the bod context and User objects and all that and make it almost standalone, like a plugin. That allows portlets to access it and it in effect becomes a gateway for portlets into the bodington system.

Questionnaire tool springs to mind. Abstract it out a bit, give it a portlet and import into uPortal and consume via WSRP.

So, on that news, I’m off to read up on portals, portlets and other such exotica :)

Well, I’ve read some more and here’s the result:

CLAN running in Jetspeed
Logging into CLAN to view your groups from within Jetspeed2 – click to enlarge

The above image shows two portlets within Jetspeed2 which are part of the Bodington portlet application. Each is linked to Bodington via the internal API. If you login in the top portlet, you’ll see your groups appear in the lower portlet. The authentication is handled by Bodington in the normal fashion, so if the underlying Bodington uses LDAP authentication, you use your LDAP credentials to login. After you authenticate, the login portlet communicates this to the groups portlet and it expands and displays the groups for the user.

I had to make one change to the Bodington source though. org.bodington.server.realm.LDAPAuthenticator. Normally, it relies on BuildingServlet.getBodingtonRoot() to find it’s ldap-authenticator.xml but when running as a portlet application, it doesn’t work and the LDAP module can’t config itself. The solution was to change it to load it’s config file from the CLASSPATH and put ldap-authenticator.xml in WEB-INF/classes.

CLANJetspeed2
Logged into CLAN and viewing your groups from within Jetspeed2 – click to enlarge

I’ve now got CLAN running under Jetspeed2 with inter-portlet communication. It doesn’t really do much at the moment apart from let you login and view your group memberships.

So, what can I do next?

Well, I added a profile portlet as well as portlet to display currently logged in users.

CLANJetspeed logged in users

CLAN profile and logged in users portlets within Jetspeed2 – click to enlarge

The logged in users portlet is a completely new implementation of this Bodington functionality. It uses the PortletContext to store logged in users information with the login portlet adding and removing them when the login and logout.
References

Dumping and restoring a postgres database

Posted & filed under howTo.

Dump the database to text file, without BLOBs:

pg_dump -f backup.sql DATABASE_NAME

Restore the database from text file without BLOBs:

pgsql -d DATABASE_NAME -f backup.sql

Dump the database with BLOBs:

pg_dump -Ft -b DATABASE_NAME > backup.tar

Restore the database with BLOBs:

pg_restore -d DATABASE_NAME backup.tar

Expanding users

Posted & filed under The Rantorium.

I saw it again, this time on a comment on the BBC page. That funny mix up between pressured and pressurised! It’s a hoot, I tell you:

“I didn’t want to do it but he pressurised me”
“I’m being pressurised into doing it”

“Pressurised”? Surely not. What, someone has stuck an airline up your bahookie and is pumping you up? Like a balloon? Nah! Really? puff puff puff…

Learn to speak – “pressured”! doh, I don’t know.

Next time you hear someone say this, just imagine them slowly inflating and flying off before your very eyes!

Installing Plone with LDAP

Posted & filed under howTo.

Python

First thing you need is Python : get it here
We’ll put it in /usr/local/python:

./configure –prefix=/usr/local/python
make
make install

The first you should do is make sure any previously installed Python interpreters are deleted. If you don’t, it’ll cause a lot of headache later on. There’s usually one at:
/usr/bin/python
so, do this to save your sanity:
cd /usr/bin
rm python
ln -s /usr/local/python/bin/python python

don’t forget to add /usr/local/python/bin to your PATH in /etc/profile, so that when you do:

which python

you’ll get:

/usr/local/python/bin/python

This is important to make sure Zope uses the python you just built and also that the LDAP lib you’re about to build uses it too.

openLDAP

A quick diversion here, as you’ll need to install openLDAP now, before building Python LDAP support. Get it here

Here’s how I normally configure openLDAP for an easy install:

export LIBS=-lresolv
./configure –prefix=/usr/local/openldap \
    –enable-ldbm=no \
    –enable-slapd=no \
    –with-tls

then do:

make
make install

and that’s you got openLDAP installed.

LDAP support for Python

You now need python-ldap : get it here
edit it’s setup.cfg for a nice easy install:

library_dirs = /usr/local/openldap/lib
include_dirs = /usr/local/openldap/include
libs = ldap

then just do:

python setup.py build
python setup.py install

If you get errors such as these:

file Lib/ldap.py (for module ldap) not found
file Lib/ldap/schema.py (for module ldap.schema) not found
file Lib/ldap.py (for module ldap) not found
file Lib/ldap/schema.py (for module ldap.schema) not found

don’t worry about them as apparently they’re normal! Read it here

To test that the LDAP build worked, go into a shell and do:

python -c “import ldap,ldap.schema;print ldap.__version__”

You should get the version number displayed. If you get:

ImportError: No module named ldap

then you’ve most probably not got rid of the previously installed Python interpreter which lurks in /usr/bin

Zope

Zope now : get it here

Nice easy configure:

./configure –prefix=/usr/local/zope \
    –with-python=/usr/local/python/bin/python

–with-python is important as it makes sure Zope uses the Python you’ve just build and not one of the lurkers on the system. If you get an error such as:

make: execvp: /usr/local/python: Permission denied

then you’ve done –with-python=/usr/local/python instead.

OK, off we go again:

make
make install

and we have Zope in /usr/local/zope. The next step is to go to /usr/local/zope and type:

bin/mkzopeinstance.py

to create a new instance. I just called mine “test” and gave it an admin username and password. This gave me an instance in:

/usr/local/zope/test

The next step is important. Edit:

/usr/local/zope/test/etc/zope.conf

and change effective-user to be the uid of a system user to run the instance as, instead of root. Then make /usr/local/zope/test and all it’s subdirs writeable to that user:

effective-user wwwrun
chown -R wwwrun test

You’re now ready to start your new Zope instance:

/usr/local/zope/test/bin/zopectl start

if you want to see any errors, which don’t get logged BTW, do:

/usr/local/zope/bin/zopectl fg

You should be able to go to:

http://yourzope.com:8080/manage

for the root instance and

http://yoursite.com:8080/test/manage

for your test instance, logging in as the user you specified when running mkzopeinstance.py

If all is well, shut Zope down, for now we install Plone:

/usr/local/zope/test/bin/zopectl stop

Plone

Plone is a Zope Product, get it here
What you must do is create a Products directory for it under your “test” instance:

mkdir /usr/local/zope/test/Products

if it doesn’t already exist. Then just decompress the Plone tarball and copy all those file into the Products directory:

cd Plone-2.1.2
cp -r * /usr/local/zope/test/Products

That’s it for now. Let’s add LDAP support to Plone now.

LDAP support for Plone

We now need LDAPUserFolder for Zope, get it here
All you have to do is decompress it and copy the directory to your test Products directory:

cp -r LDAPUserFolder /usr/local/zope/test/Products

and now interactively restart your Zope instance:

/usr/local/zope/test/bin/zopectl fg

to test for LDAP loading errors such as:

File “<string>”, line 1, in ?
ImportError: No module named ldap

if you see this then Zope is not using the Python you LDAP enabled. Go back to the Python section and make sure you’ve got rid of all lurkers and you’ve built and installed python-ldap. If you don’t see any errors, then shut it down again:

/usr/local/zope/test/bin/zopectl stop

and start it in daemon mode:

/usr/local/zope/test/bin/zopectl start

Install your new Plone by logging in to your Zope root instance:

http://yourzope.com:8080/manage

and adding a “Plone Site” from the “Add” droplist when in the root menu. You can then login to your Plone:

http://yourzope.com:8080/test/manage

You now have an LDAP enabled Zope and Plone. To configure Plone to use LDAP, follow the instuctions here. This page might help too.

Webdav folder in Windows XP

Posted & filed under howTo.

This is how you publish to a webdav enabled website from Windows XP using My Network Places. If you’re out of the office you can set up a quick connection using Internet Explorer. I’ll explain that one later.

Publishing to your website from the desktop

Publishing to your website from Internet Explorer

In case you see a strange message such as “error 31 = ERROR_GEN_FAILURE” or similar, go to this Microsoft page