Taxifahrer und ich

Gestern war es mal wieder so weit: Ich musste vom Flughafen zurück ein Taxi bemühen, da die Busverbindungen am späten Abend doch etwas zu zäh sind und ich langsam ins Bett wollte. Also ab ins Taxi, am Flughafen stehen ja immer genug rum. Und dann fragt mich der Taxifahrer (und er ist nicht der erste), wo ich zu meinem Ziel langfahren will.

Was soll ich da sagen? Eine detaillierte Route, inklusive Strassennamen? Ich habe kein Auto, also kenne ich die Strassennamen auch nur von Bushaltestellenschildern oder gar nicht. Oder soll ich sagen: Hau mich nicht über’s Ohr, fahr die beste Strecke? Wieso fährt er nicht einfach die günstigste Strecke, oder vielleicht die schnellste Strecke.

Und wenn man gar nichts sagt, ist es sowieso immer die längste Strecke – nicht die schnellste, nicht die billigste…

Embedding the Apache Mina ftp server in your tests

Every once in a while you need some service running while executing your integration tests. Today I needed a running FTP server to test a new route in my [JBoss ESB][0] that has a [NotificationList (basically a recipient list pattern][1] with a NotifyFTP action as last action in my action pipeline, that pushes the message as a file onto an FTP server.

I already configured this notification target for a local FTP server during deployment, but I because I tried to create a chain of services which all modified the XML message going through my ESB I needed a way to verify the end result of that chain. After a quick search I found [Apache Mina][3] which has an FTP Server component that is embeddable in java applications. It looked easy enough to just start the FTP server, so I added the following code to my test class:

@BeforeClass
public static void setUpFtpServer() throws Exception {
	// make sure jboss ftp localdir exists
	new File("c:/tmp").mkdirs();
	// set up embedded ftp to receive files
	FtpServerFactory serverFactory = new FtpServerFactory();
	ListenerFactory factory = new ListenerFactory();
	factory.setPort(21);
	// replace the default listener
	Listener listener = factory.createListener();
	serverFactory.addListener("default", listener);
	String ftproot = File.createTempFile("ftp", ".txt").getParent();
	logger.info(">>> ftproot: " + ftproot);
	serverFactory.setUserManager(addUser("testuser", "testuser", ftproot));
	// create necessary structure
	outputDir = new File(ftproot + "/scmp_tes_dir/hoi/out");
	outputDir.mkdirs();
	// start the server
	server = serverFactory.createServer();
	server.start();
}


@Before
public void setUp() throws Exception {
	// remove all files that might exist in FTP directory before running anything
	for (File file : outputDir.listFiles()) {
		file.delete();
	}

	// check if ftp is available
	FTPClient ftpClient = new FTPClient();
	ftpClient.connect("127.0.0.1");
	boolean loggedIn = ftpClient.login("testuser", "testuser");
	if (loggedIn) {
		logger.info(">>> FTP running");
	} else {
		throw new RuntimeException(">>> FTP failed");
	}

	//... other setup tasks
}

public static UserManager addUser(final String username, final String password, final String ftproot)
		throws IOException {
	PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
	File userFile = new File("jbossusers.properties");
	userFile.createNewFile();
	userManagerFactory.setFile(userFile);
	userManagerFactory.setPasswordEncryptor(new SaltedPasswordEncryptor());
	UserManager um = userManagerFactory.createUserManager();

	BaseUser user = new BaseUser();
	user.setName(username);
	user.setPassword(password);
	user.setHomeDirectory(ftproot);

	List authorities = new ArrayList();
	authorities.add(new WritePermission());
	user.setAuthorities(authorities);

	try {
		um.save(user);
	} catch (FtpException e) {
		logger.error("Can not save FTP user", e);
	}
	return um;
}
</pre>

I'm using [JUnit][4] to build my integration tests, because I'm lazy and got used to running my tests with the junit view in [Eclipse][5]. :-) The `@BeforeClass` method first creates a directory that JBoss relies on (I still don't know what it's doing in `c:/tmp` when creating the `NotifyFTP`...), then starts a new FTP server with *FTP_ROOT* set to my temp directory. I don't care where that directory is, so I'm just creating a temporary file and get the parent path from that.

After that I add a new user with the method `addUser(username, password, directory)` with the previously created directory as her ftp home directory. After that I create some required directory inside my *FTP_ROOT* where *JBoss ESB* wants to place the result files.

This way whenever I run the test, I have a local FTP server running and accepting files with a user that matches the setup in my locally configured *JBoss ESB*, but I can just run the test and see if it is good or not. Validating the XML files in the FTP directory is just a matter of comparing the result with a predefined XML file via [XMLUnit][6], so no suprises on that end.

[0]: https://www.jboss.org/jbossesb/
[1]: http://www.enterpriseintegrationpatterns.com/RecipientList.html
[3]: http://mina.apache.org/ftpserver-project/index.html
[4]: http://junit.org/
[5]: http://eclipse.org/
[6]: http://xmlunit.sourceforge.net/

Owncloud Plugin to view GPX files

Today I decided to create a plugin for Owncloud which displays GPX files directly in your browser. For the plugin I used the great leaflet library and the GPX plugin by Maxime Petazzoni. The plugin will display all files with a mimetype of text/gpx or application/gpx+xml on a map in your browser when you click them while browsing your owncloud folders.

If you want to try the plugin, head over to the github repository files_gpxviewer and clone the repository into the folder OWNCLOUD/apps/. You can also download a ZIP with all the files.

If you find any issues, please help me improve the plugin by creating a new issue.