Showing posts with label jasig. Show all posts
Showing posts with label jasig. Show all posts

Wednesday, May 22, 2013

Fixing ICS Time Zone

I was getting my agenda setup for the upcoming 2013 Apereo conference in San Diego and was excited to see their scheduling app let you select presentations and export a .ics file. Yay, something easy to import into Google Calendar and I'll have my whole schedule right on my phone!

Well, that was the case until I imported the events and had no attached time-zone information ... boo!

So here is the quick-and-dirty hack to add time-zone information to your .ics file.

Add a VTIMEZONE Block

These go right above the first BEGIN:VEVENT block in your ics file. You only need to add time-zone definitions for the time zones you want to reference in your events. At the bottom of the post are more timezone blocks
BEGIN:VTIMEZONE
TZID:America/Los_Angeles
X-LIC-LOCATION:America/Los_Angeles
BEGIN:DAYLIGHT
TZOFFSETFROM:-0800
TZOFFSETTO:-0700
TZNAME:PDT
DTSTART:19700308T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0700
TZOFFSETTO:-0800
TZNAME:PST
DTSTART:19701101T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
END:STANDARD
END:VTIMEZONE

Update DTSTART and DTEND

For each VEVENT you want to set a timezone for update the DTSTART and DTEND to include a timezone reference.
Before:
DTSTART:20130602T130000
DTEND:20130602T160000
After:
DTSTART;TZID=America/Los_Angeles:20130602T130000
DTEND;TZID=America/Los_Angeles:20130602T160000

US VTIMEZONE List

Below are VTIMEZONE blocks for: Pacific, Mountain, Mountain - Arizona, Central, and Eastern time zones.

BEGIN:VTIMEZONE
TZID:America/Los_Angeles
X-LIC-LOCATION:America/Los_Angeles
BEGIN:DAYLIGHT
TZOFFSETFROM:-0800
TZOFFSETTO:-0700
TZNAME:PDT
DTSTART:19700308T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0700
TZOFFSETTO:-0800
TZNAME:PST
DTSTART:19701101T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
END:STANDARD
END:VTIMEZONE
BEGIN:VTIMEZONE
TZID:America/Phoenix
X-LIC-LOCATION:America/Phoenix
BEGIN:STANDARD
TZOFFSETFROM:-0700
TZOFFSETTO:-0700
TZNAME:MST
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
BEGIN:VTIMEZONE
TZID:America/Chicago
X-LIC-LOCATION:America/Chicago
BEGIN:DAYLIGHT
TZOFFSETFROM:-0600
TZOFFSETTO:-0500
TZNAME:CDT
DTSTART:19700308T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0500
TZOFFSETTO:-0600
TZNAME:CST
DTSTART:19701101T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
END:STANDARD
END:VTIMEZONE
BEGIN:VTIMEZONE
TZID:America/New_York
X-LIC-LOCATION:America/New_York
BEGIN:DAYLIGHT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
TZNAME:EDT
DTSTART:19700308T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
TZNAME:EST
DTSTART:19701101T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
END:STANDARD
END:VTIMEZONE

Monday, July 14, 2008

Unit testing Spring-LDAP code with ApacheDS

The Spring LDAP framework is a great library to assist in working with LDAP servers through a more manageable API. It provides the niceties that the DataSource interface does for JDBC along with support similar to the Spring JDBC framework. One area that has been lacking though is testing. With JDBC based code it is easy enough to use HSQLDB to provide an in-memory database to test against. With LDAP based code there hasn't been a good solution, until the Apache Directory project came along.

Apache Directory is a 100% Java LDAP implementation and includes support for in-memory LDAP instances for unit testing. Using this support plus a few helper classes to bridge the gap to Spring LDAP providing unit tests for LDAP related code is easy.

First add the necessary dependencies. If you are using Maven your project needs to depend on the following for testing:


Second, add AbstractDirContextTest.java and SingleContextSource.java to your project.

Finally extend AbstractDirContextTest for your LDAP code test class.


Your test class needs to provide a partition name, which is the root of the DN for the server to test against, and a Resource array of ldiff files to load into the LDAP server. For the test above the ldiff file looke like:

Saturday, June 7, 2008

Apple's JDK6 Broke My Scripting!

uPortal 3 uses the new (JDK5+) Java scripting APIs via Cernunnos, the scripting language used in the data import/export scripts. This has been working great and is a huge step forward for the uPortal project. I've been building uPortal 3 on my Apple computer since development started and it has been working great.


Until I installed the Apple JDK6 Update.


Now I've been itching for JDK6 on my Mac for a while. I have little interest in the OS integration Apple does with the JDKs since I don't use it to develop code for OS X. I develop server-side web applications, all I need is the base JDK. So finally, around a year after Sun released JDK6, Apple gets their version out. I eagerly install the update, Eclipse still works, Tomcat starts and uP3 runs, we're all happy.

A few days later I grab the latest updates from the uPortal trunk and go to re-build and re-initialize the portal's database. It fails importing the data .... didn't this just work at the office? Didn't this just work here a few days ago?

Wondering if this is a new issue or not I grab the 3.0.0 release package and run initportal, it fails there too! All my attempts to run any of the Cernunnos scripts fail with the following stack trace:



So the next question is what the heck does uP3 depend on that is compiled to the JDK6 .class file format? Of course the UnsupportedClassVersionError is useless since it doesn't tell you what class file is bad or where it is loading it from!

The next step is adding the -verbose:class option to the Ant script that runs the Cernunnos scripts. This makes the JVM print out each class and the file it is loaded from, thats a lot of text but the only way to track this down. Re-running the script with the verbose option yields the culprit:

apple.applescript.AppleScriptEngineFactory

What the heck? Apple includes a scripting library for JDK6 only in the classpath for JDK5? They do this by default after installing their JDK6 update? This is not cool. The class is in the /System/Library/Java/Extensions/AppleScriptEngine.jar file which is added in the system's JDK extensions folder, apparently ALL Apple JDKs load ALL the jars from this directory. That makes it a bad place for a .jar that isn't compatible with all the JDKs on the system.

The solution I ended up coming up with is to move the AppleScriptEngine.jar into the JDK6 extensions directory:



This move fixed the problem and all is happy (mostly) in the land of Java on the Mac.

Wednesday, March 26, 2008

Java SQLException Chaining

In JDK 1.4 chained Throwables were added and made logging and tracing exceptions much easier. Being able to create a new exception and specify the causing exception in a standard way, tied to JVM printing out the stack chain, was a big boost to tracking down problems in an application.

There are still some exceptions that do not use this standard chaining mechanism and one of the most frustraiting cases in SQLException. It provides a getNextException() method which returns the next SQLException related to the failed operation. The problem here is without special handling code these nextExceptions just get lost in log messages.

A general solution to this problem is to add an Aspect that either logs the results of getNextException or adds them to the exception chain.



This aspect class can be used via Spring's AOP support with the following context configuration:

Sunday, February 24, 2008

PostgreSQL Backups

While shell scripting is not my strong suit I put this together to do automatic backups of the Postgres database that backs the ja-sig.org services. The script will vacuum each database, do a full dump of each database, do a dump of each schema and do a global meta-data backup. All the dumps are compressed with bzip2 and date/time stamped. Logs and backups older than 7 days are removed.

The results get stored in a date-stamped directory and all actions are logged into a date/time stamped log file.

The script can be easily customized using the variables at the top of the file and should work on any PostgreSQL database.

Tuesday, January 15, 2008

Using Ant with a Maven project

I recently had to take a Maven 2 WAR project and make it buildable on a system that did not have Maven available. Not being one to duplicate configuration I put together an Ant build script that, when Maven is available, can be used to pull the dependencies into the project file structure in an organized fashion and write out properties about the maven project for use by the script.

Currently the script provides support for doing the equivalent of 'mvn clean package' on a simple Maven managed WAR project.



As you can see at the end of the script it depends on Ant Contrib and Maven Ant Tasks.

Wednesday, December 12, 2007

Spring 2.5 Module Contents

The 2.5 release of the Spring Framework re-organized many packages and classes in the specific module JARs. Moving from Spring 2.0 to 2.5 introduces some pain in figuring out what moved where and I couldn't find anything detailing which packages reside in which module JARs. So after a few lines of shell-fu I produced the following to help with the upgrades:

spring-jms.jar

META-INF/
org/
org/springframework/
org/springframework/jms/
org/springframework/jms/config/
org/springframework/jms/connection/
org/springframework/jms/core/
org/springframework/jms/core/support/
org/springframework/jms/listener/
org/springframework/jms/listener/adapter/
org/springframework/jms/listener/endpoint/
org/springframework/jms/listener/serversession/
org/springframework/jms/remoting/
org/springframework/jms/support/
org/springframework/jms/support/converter/
org/springframework/jms/support/destination/

spring-core.jar

META-INF/
org/
org/springframework/
org/springframework/asm/
org/springframework/asm/commons/
org/springframework/asm/signature/
org/springframework/core/
org/springframework/core/annotation/
org/springframework/core/enums/
org/springframework/core/io/
org/springframework/core/io/support/
org/springframework/core/style/
org/springframework/core/task/
org/springframework/core/task/support/
org/springframework/core/type/
org/springframework/core/type/classreading/
org/springframework/core/type/filter/
org/springframework/metadata/
org/springframework/metadata/commons/
org/springframework/util/
org/springframework/util/comparator/
org/springframework/util/xml/

spring-web.jar

META-INF/
org/
org/springframework/
org/springframework/remoting/
org/springframework/remoting/caucho/
org/springframework/remoting/httpinvoker/
org/springframework/remoting/jaxrpc/
org/springframework/remoting/jaxrpc/support/
org/springframework/remoting/jaxws/
org/springframework/web/
org/springframework/web/bind/
org/springframework/web/bind/annotation/
org/springframework/web/bind/support/
org/springframework/web/context/
org/springframework/web/context/request/
org/springframework/web/context/support/
org/springframework/web/filter/
org/springframework/web/jsf/
org/springframework/web/jsf/el/
org/springframework/web/multipart/
org/springframework/web/multipart/commons/
org/springframework/web/multipart/support/
org/springframework/web/util/

spring-aop.jar

META-INF/
org/
org/springframework/
org/springframework/aop/
org/springframework/aop/aspectj/
org/springframework/aop/aspectj/annotation/
org/springframework/aop/aspectj/autoproxy/
org/springframework/aop/config/
org/springframework/aop/framework/
org/springframework/aop/framework/adapter/
org/springframework/aop/framework/autoproxy/
org/springframework/aop/framework/autoproxy/target/
org/springframework/aop/interceptor/
org/springframework/aop/scope/
org/springframework/aop/support/
org/springframework/aop/support/annotation/
org/springframework/aop/target/
org/springframework/aop/target/dynamic/

spring-webmvc-portlet.jar

META-INF/
org/
org/springframework/
org/springframework/web/
org/springframework/web/portlet/
org/springframework/web/portlet/bind/
org/springframework/web/portlet/context/
org/springframework/web/portlet/handler/
org/springframework/web/portlet/multipart/
org/springframework/web/portlet/mvc/
org/springframework/web/portlet/mvc/annotation/
org/springframework/web/portlet/util/

spring-tx.jar

META-INF/
org/
org/springframework/
org/springframework/dao/
org/springframework/dao/annotation/
org/springframework/dao/support/
org/springframework/jca/
org/springframework/jca/cci/
org/springframework/jca/cci/connection/
org/springframework/jca/cci/core/
org/springframework/jca/cci/core/support/
org/springframework/jca/cci/object/
org/springframework/jca/context/
org/springframework/jca/endpoint/
org/springframework/jca/support/
org/springframework/jca/work/
org/springframework/transaction/
org/springframework/transaction/annotation/
org/springframework/transaction/config/
org/springframework/transaction/interceptor/
org/springframework/transaction/jta/
org/springframework/transaction/support/

spring-beans.jar

META-INF/
org/
org/springframework/
org/springframework/beans/
org/springframework/beans/annotation/
org/springframework/beans/factory/
org/springframework/beans/factory/access/
org/springframework/beans/factory/annotation/
org/springframework/beans/factory/config/
org/springframework/beans/factory/generic/
org/springframework/beans/factory/parsing/
org/springframework/beans/factory/serviceloader/
org/springframework/beans/factory/support/
org/springframework/beans/factory/wiring/
org/springframework/beans/factory/xml/
org/springframework/beans/propertyeditors/
org/springframework/beans/support/

spring-webmvc-struts.jar

META-INF/
org/
org/springframework/
org/springframework/web/
org/springframework/web/servlet/
org/springframework/web/servlet/view/
org/springframework/web/servlet/view/tiles/
org/springframework/web/struts/

spring-context-support.jar

META-INF/
org/
org/springframework/
org/springframework/cache/
org/springframework/cache/ehcache/
org/springframework/mail/
org/springframework/mail/javamail/
org/springframework/scheduling/
org/springframework/scheduling/commonj/
org/springframework/scheduling/quartz/
org/springframework/ui/
org/springframework/ui/freemarker/
org/springframework/ui/jasperreports/
org/springframework/ui/velocity/

spring-context.jar

META-INF/
org/
org/springframework/
org/springframework/context/
org/springframework/context/access/
org/springframework/context/annotation/
org/springframework/context/config/
org/springframework/context/event/
org/springframework/context/i18n/
org/springframework/context/support/
org/springframework/context/weaving/
org/springframework/ejb/
org/springframework/ejb/access/
org/springframework/ejb/config/
org/springframework/ejb/support/
org/springframework/instrument/
org/springframework/instrument/classloading/
org/springframework/instrument/classloading/glassfish/
org/springframework/instrument/classloading/oc4j/
org/springframework/instrument/classloading/weblogic/
org/springframework/jmx/
org/springframework/jmx/access/
org/springframework/jmx/export/
org/springframework/jmx/export/annotation/
org/springframework/jmx/export/assembler/
org/springframework/jmx/export/metadata/
org/springframework/jmx/export/naming/
org/springframework/jmx/export/notification/
org/springframework/jmx/support/
org/springframework/jndi/
org/springframework/jndi/support/
org/springframework/remoting/
org/springframework/remoting/rmi/
org/springframework/remoting/soap/
org/springframework/remoting/support/
org/springframework/scheduling/
org/springframework/scheduling/backportconcurrent/
org/springframework/scheduling/concurrent/
org/springframework/scheduling/support/
org/springframework/scheduling/timer/
org/springframework/scripting/
org/springframework/scripting/bsh/
org/springframework/scripting/config/
org/springframework/scripting/groovy/
org/springframework/scripting/jruby/
org/springframework/scripting/support/
org/springframework/stereotype/
org/springframework/ui/
org/springframework/ui/context/
org/springframework/ui/context/support/
org/springframework/validation/

spring-orm.jar

META-INF/
org/
org/springframework/
org/springframework/orm/
org/springframework/orm/hibernate3/
org/springframework/orm/hibernate3/annotation/
org/springframework/orm/hibernate3/support/
org/springframework/orm/ibatis/
org/springframework/orm/ibatis/support/
org/springframework/orm/jdo/
org/springframework/orm/jdo/support/
org/springframework/orm/jpa/
org/springframework/orm/jpa/persistenceunit/
org/springframework/orm/jpa/support/
org/springframework/orm/jpa/vendor/
org/springframework/orm/toplink/
org/springframework/orm/toplink/support/

spring-webmvc.jar

META-INF/
org/
org/springframework/
org/springframework/web/
org/springframework/web/servlet/
org/springframework/web/servlet/handler/
org/springframework/web/servlet/handler/metadata/
org/springframework/web/servlet/i18n/
org/springframework/web/servlet/mvc/
org/springframework/web/servlet/mvc/annotation/
org/springframework/web/servlet/mvc/multiaction/
org/springframework/web/servlet/mvc/support/
org/springframework/web/servlet/mvc/throwaway/
org/springframework/web/servlet/support/
org/springframework/web/servlet/tags/
org/springframework/web/servlet/tags/form/
org/springframework/web/servlet/theme/
org/springframework/web/servlet/view/
org/springframework/web/servlet/view/document/
org/springframework/web/servlet/view/freemarker/
org/springframework/web/servlet/view/jasperreports/
org/springframework/web/servlet/view/tiles2/
org/springframework/web/servlet/view/velocity/
org/springframework/web/servlet/view/xslt/

spring-test.jar

META-INF/
org/
org/springframework/
org/springframework/mock/
org/springframework/mock/jndi/
org/springframework/mock/web/
org/springframework/mock/web/portlet/
org/springframework/test/
org/springframework/test/annotation/
org/springframework/test/context/
org/springframework/test/context/junit38/
org/springframework/test/context/junit4/
org/springframework/test/context/support/
org/springframework/test/context/testng/
org/springframework/test/context/transaction/
org/springframework/test/jdbc/
org/springframework/test/jpa/
org/springframework/test/util/
org/springframework/test/web/

spring-jdbc.jar

META-INF/
org/
org/springframework/
org/springframework/jdbc/
org/springframework/jdbc/core/
org/springframework/jdbc/core/metadata/
org/springframework/jdbc/core/namedparam/
org/springframework/jdbc/core/simple/
org/springframework/jdbc/core/support/
org/springframework/jdbc/datasource/
org/springframework/jdbc/datasource/lookup/
org/springframework/jdbc/object/
org/springframework/jdbc/support/
org/springframework/jdbc/support/incrementer/
org/springframework/jdbc/support/lob/
org/springframework/jdbc/support/nativejdbc/
org/springframework/jdbc/support/rowset/

Tuesday, October 30, 2007

Poor Man's TimeMachine: rsync

The shell script on the computer being backed up, needs a no-password ssh key to work.

#!/bin/bash

BACKUP_HOST=user@host
SSH_KEY=/home/user/.ssh/host_rsa

LOG_DIR=~/logs
LOG_FILE=$LOG_DIR/backup.`date +%Y%m%d_%H%M`.log

SRC_DIR=/home/user/
DEST_BASE_DIR=/home/user/backups/localhost
DEST_DIR_NAME=backup_`date +%Y.%m.%d_%H.%M.%S`
PREV_DIR_NAME=previous

DEST_DIR=$DEST_BASE_DIR/$DEST_DIR_NAME
PREV_DIR=$DEST_BASE_DIR/$PREV_DIR_NAME

mkdir -p $LOG_DIR

nice -10 /usr/bin/rsync --rsh="ssh -i $SSH_KEY" \
--checksum --archive --compress --human-readable --progress --recursive \
--link-dest=$PREV_DIR \
--filter='merge /home/user/backup/backup.filterrules' $SRC_DIR \
$BACKUP_HOST:$DEST_DIR >> $LOG_FILE 2>&1

ssh -i $SSH_KEY $BACKUP_HOST "link $PREV_DIR $DEST_DIR" >> $LOG_FILE 2>&1

bzip2 $LOG_FILE


A Ruby script that I use with the password-less ssh key on the server side to reduce chances of it being abused. Just add command="~/bin/backup-wrapper.rb" before your key in .ssh/authorized_keys



I'm sure there is a way to do what the wrapper does in bash but I happen to be more comfortable with ruby doing the string parsing. If anyone wants to provide a bash script for doing the same thing I'd be more than happy to see it.