J2ポータルをアップデートする方法

Jetspeedもいろいろと更新が入ったりするので、既に配備してあるものを更新したい場合、どうしたものかと、悩むこともあるだろう(っていうか、いつも困る)。というわけで、アップデートするスクリプトを簡単に書いてみる(結構、適当なので、参考程度に)。ただ、データベースのスキーマに変更が入ったりすると、これだけじゃ、データを移行しないとダメだと思うけど、まぁ、そこいらはだいぶ落ち着いてきているので、変更はなかなか入らんだろう(入ったら、シリアライザーでエクスポートしてインポートすればいいと思う)。

#!/bin/sh
# ex. $ portal_update.sh jetspeed <NEW_TOMCAT_ROOT> <OLD_TOMCAT_ROOT>
PORTAL_NAME=$1
NEW_PORTAL_PATH=$2
OLD_PORTAL_PATH=$3
echo "Portal Name: $PORTAL_NAME"
echo "New Portal Path: $NEW_PORTAL_PATH"
echo "Old Portal Path: $OLD_PORTAL_PATH"
rm -rf $OLD_PORTAL_PATH/webapps/$PORTAL_NAME/WEB-INF/lib
rm -rf $OLD_PORTAL_PATH/webapps/$PORTAL_NAME/WEB-INF/classes
rm -rf $OLD_PORTAL_PATH/webapps/$PORTAL_NAME/WEB-INF/templates
rm -rf $OLD_PORTAL_PATH/webapps/$PORTAL_NAME/decorations
rm -rf $OLD_PORTAL_PATH/webapps/$PORTAL_NAME/javascript
rm -rf $OLD_PORTAL_PATH/webapps/$PORTAL_NAME/images
for file in `find $NEW_PORTAL_PATH/webapps/$PORTAL_NAME -type f | sed -e "s,^$NEW_PORTAL_PATH/,," \
| grep -v "^webapps/$PORTAL_NAME/META-INF" \
| grep -v "^webapps/$PORTAL_NAME/logs" \
| grep -v "^webapps/$PORTAL_NAME/WEB-INF/pages" \
| grep -v "^webapps/$PORTAL_NAME/WEB-INF/min-pages" \
| grep -v "^webapps/$PORTAL_NAME/WEB-INF/deploy" \
` ; do
BASE_DIR="$OLD_PORTAL_PATH/"`dirname $file`
mkdir -p $BASE_DIR
cp $NEW_PORTAL_PATH/$file $OLD_PORTAL_PATH/$file
done
rm $OLD_PORTAL_PATH/shared/lib/j* $OLD_PORTAL_PATH/shared/lib/p*
cp $NEW_PORTAL_PATH/shared/lib/j* $OLD_PORTAL_PATH/shared/lib
cp $NEW_PORTAL_PATH/shared/lib/p* $OLD_PORTAL_PATH/shared/lib

第一引数に、ポータル名、つまり、jetspeed とか、第二引数が新しいポータルの場所(新しいTomcatルート)、第三引数が今動いているTomcatルート。実行すると、第三引数で与えた既存のポータルが更新される(実行する際には、Tomcatを停止する必要あり)。やっていることは、単純で、jar などなどのファイルの書き換え。ただ、ログやPSMLファイルおよびdeployディレクトリはコピーしない。confやspringのファイルを変更している場合は、上書きされるので、再度、設定する必要あり。まぁ、単純なものですが、参考までに・・・。

UserManagerをみる

数万ユーザーの現実的な管理に向けて、調べ始める。Jetspeed API の UserManager から見ていく。見ていくと、いかような感じで呼ばれていく。

./components/security/src/java/org/apache/jetspeed/security/impl/UserManagerImpl.java:
public Iterator getUsers(String filter) throws SecurityException
{
List users = new LinkedList();
Iterator userPrincipals = atnProviderProxy.getUserPrincipals(filter)
.iterator();
while (userPrincipals.hasNext())
{
String username = ((Principal) userPrincipals.next()).getName();
User user = getUser(username);
users.add(user);
}
return users.iterator();
}
./components/security/src/java/org/apache/jetspeed/security/impl/AuthenticationProviderProxyImpl.java
public List getUserPrincipals(String filter)
{
List userPrincipals = new LinkedList();
for (int i = 0; i < authenticationProviders.size(); i++)
{
userPrincipals.addAll(((AuthenticationProvider)authenticationProviders.get(i)).getUserSecurityHandler().getUserPrincipals(filter));
}
return userPrincipals;
}
./components/security/src/java/org/apache/jetspeed/security/spi/impl/DefaultUserSecurityHandler.java:
public List getUserPrincipals(String filter)
{
List userPrincipals = new LinkedList();
Iterator result = securityAccess.getInternalUserPrincipals(filter);
while (result.hasNext())
{
InternalUserPrincipal internalUser = (InternalUserPrincipal) result.next();
String path = internalUser.getFullPath();
if (path == null)
{
continue;
}
userPrincipals.add(new UserPrincipalImpl(UserPrincipalImpl.getPrincipalNameFromFullPath(internalUser.getFullPath())));
}
return userPrincipals;
}
./components/security/src/java/org/apache/jetspeed/security/spi/impl/SecurityAccessImpl.java
public Iterator getInternalUserPrincipals(String filter)
{
Criteria queryCriteria = new Criteria();
queryCriteria.addEqualTo("isMappingOnly", new Boolean(false));
queryCriteria.addLike("fullPath", UserPrincipal.PREFS_USER_ROOT + filter + "%");
Query query = QueryFactory.newQuery(InternalUserPrincipalImpl.class, queryCriteria);
Iterator result = getPersistenceBrokerTemplate().getIteratorByQuery(query);
return result;
}

と言う感じで、OJBを呼んでいる(UserManager に渡すフィルタは、ユーザー名に含まれる文字列じゃなくて、フィルタの文字列で始まるユーザー名を引っ張ってくるのね)。で、OJBでページングができれば、問題解決なのだが、OJBのFAQを見ると、できんと言っている。IteratorかCollectionで取得して、自分で取り出せという感じみたい。うーん・・・、別な方法を考えよっと・・・。

http://db.apache.org/ojb/docu/faq.html

追記:Jetspeedで使っているOJBのバージョンは、1.0.3だけど、そのソースコードを見ると、QueryにsetStartAtIndexとsetEndAtIndexみたいのがあることに気がつく。その周辺のコードをみても、それらを使えば、良さそうな気がしてくる。というわけで、これで試してみよう。

emptySessionPath=”true”

ポータルでTomcatを利用するときには、この設定が必須な気がするけど、AJP 1.3 ConnectorでApache経由でTomcatにアクセスするためには、

<Connector port="8009"
emptySessionPath="true"
enableLookups="false" redirectPort="8443" protocol="AJP/1.3" />

と言う感じで、conf/server.xmlに入れておく必要がある。これしないと、ポートレットアプリケーション側にセッションを渡せない。まぁ、ポータル(ポートレット)側からアプリケーション側にセッションを渡すようなポートレットが1つもなければ、必要はないと思うけど、そういうケースは少ないような気もする。