Wednesday, July 16, 2008

Cometd, Tomcat and Jetty - the road to server push

I have managed to "Hello world" the cometd Java implementation following this guide and hacking away. No it didn't work out of the box, if you want to get it working also look at the comments and specifically the one made by "erkulas" (me).

I just had to implement a ultra-simple chat application as soon as I got things working. In fact it took about 3 lines of Javascript code and a Cometd server running on Jetty running in Tomcat. Thats actually very impressive IMHO. With just basic knowledge of Eclipse/Java and a few JAR-s you can make a chat application that runs directly in browser with 5 lines of Javascript code and within 5 minutes.

The the demo that I prepared is here . Just launch 2 or more different browsers (IE and Firefox and Opera) and go to this URL. Everything you type in one browser will be visible in another with Cometd pushing the data to every browser.

Friday, July 4, 2008

Struts 2 anemic domain models with POJOs

The other day I was integrating Easydealer.net PHP code and Java modules. The goal is to gradually move most Easydealer core code to Java (Struts 2, Spring, Hibernate). But since there is a lot of legacy code written in PHP we must be able to code some stuff also in PHP.

Since the browser is the user interface we had a simple solution - make two logins and create user sessions with Java and PHP backends with one login form. Then we can decide with any click if we want to code it in Java or PHP. No problem - said, done (with Iframe btw.).

Now I was modifying the same database tables with Java and PHP. In PHP we use PEAR_DB for databse abstraction and PEAR_DB has its own sequence schema for primary keys. It keeps the last sequence number for a table in a little table named "tablename_seq". Now if I needed to insert data from Struts I had to generate the primary key with the same schema as PEAR_DB . OK. No problem here, we just code it in our service layer.

But wait! That way I'll have to specifically code it for all the tables I am inserting in all the service classes that deal with database insert/update. That sucks. Should'nt all the domain classes just "know" about their primary keys? It makes no sence for the service layer to tell the domain classes about their identity. This code should be in our domain model!

So alternatively I could program the code that deals with PEAR_DB "_seq" tables in getters/setters of the domain model classes. And that brings us to the subject. The simplest struts 2 domain model objects contain fieldnames, getters/setters and some annotations for relations. But all that information can be as well described in a list or map . In our PHP code all the database model is described in one big array. Ok some getters/setters have a little business logic in them. But that's it. So i have ended up with an anemic domain model, wich is basically a description of my database structure in POJO-s. That's not my goal!

While searching for alternatives I found this little gem . It is a bit dated, but there are practically all the alternatives analysed. And the conclusion should be - pick your poison :) .

CentOS Xen domU image resize

The impatient ones can find the clean solution with Linux commands at the end of this post. For the inquiring minds, here we go.

I've been struggling with our CentOS Xen install problems for months now. The server is running on HP Proliant DL380 G5 with two 86 GB SAS discs in RAID 1 (full mirroring).

Since we had so limited HDD space capacity (my bad when ordering the server), I had to limit the space allocated to Xen domU-s . Each got about 6-10 GB . Now we are running into space problems on these domU-s. As it turns out there is NO straightforward procedure for resizing domU disks on Xen and Redhat (um. i meant CentOS :-P ).

We installed domU-s by accessing install media through HTTP (Apache on dom0). This post is not about domU installation so I'll refrain from describing the procedures with detail. But this had a small but VERY SIGNIFICANT consequence. Installing domU-s this way we had an ordinary CentOS install going on in dom0 and resulting in new domU . All fine and dandy, right? NOT!

This procedure ended up with an image file on dom0 containing two partitions (small one for kernel and a LVM) . Now since all the userland data is on our LVM LV (LVM Logical Volume) we wanted to add space to that. So in order to do that we needed:

1. add "physical" space to the image file from dom0
2. add/allocate that space to our LVM PV (Physical Volumn) volume inside the image file
3. add/allocate space to LVM LV (Logical Volume) inside LVM PV

Should be piece of cake ... well not quite.

Point 1 is no problem, we use "dd" on the image file dom0 and you don't even need to shutdown the domU. One possibility for points 2 and 3 would be to shutdown domU, mount it's image in dom0 and resize the LVM. BUT, our install procedure above resulted in the LVM descriptors (ID-s) of dom0 and domU LVM discs to be EXACTLY the same. So we have NO WAY of altering the LVM on domU images from dom0 because the system could only identify dom0 LVM disks. We have a chicken and an egg problem, because we can't even change the ID-s on the same system. Ok, so alternatively we will try to resize the LVM PV and LV in domU - to no avail. The "pvextend" and "lvextend" end up with error messages about not being able to modify the volumes (even on runlevel 1).

At the end of the day the only solution was to create a new primary partitition on domU (with fdisk), create a new PV and extend LV with it. Here is the trace:
---------------------------------------------------------
Dom0:
dd if=/dev/zero bs=2G count=1 >> IMAGE_FILE

DomU:
[root@mail ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
7.2G 6.0G 851M 88% /
/dev/xvda1 99M 18M 76M 20% /boot
tmpfs 500M 0 500M 0% /dev/shm
[root@mail ~]# pvs -o +dev_size --units h
PV VG Fmt Attr PSize PFree DevSize
/dev/xvda2 VolGroup00 lvm2 a- 9.31G 32.00M 9.32G

------ fdisk (make primary partitition /dev/xvda3 on disk from free space) ------

[root@mail ~]# pvcreate /dev/xvda3 Physical volume "/dev/xvda3" successfully created [root@mail ~]# vgextend VolGroup00 /dev/xvda3 Volume group "VolGroup00" successfully extended [root@mail ~]# lvextend -L+608M /dev/VolGroup00/LogVol00 Extending logical volume LogVol00 to 17.34 GB Logical volume LogVol00 successfully resized [root@mail ~]# resize2fs /dev/VolGroup00/LogVol00 resize2fs 1.39 (29-May-2006) Filesystem at /dev/VolGroup00/LogVol00 is mounted on /; on-line resizing required Performing an on-line resize of /dev/VolGroup00/LogVol00 to 4702208 (4k) blocks. The filesystem on /dev/VolGroup00/LogVol00 is now 4702208 blocks long. [root@mail ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/VolGroup00-LogVol00 18G 6.0G 11G 36% / /dev/xvda1 99M 18M 76M 20% /boot tmpfs 500M 0 500M 0% /dev/shm
---------------------------------------------------------

PS: you should be able to do this without a domU shutdown. Use it at your own risk tho.