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:

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();
	// 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");
	// start the server
	server = serverFactory.createServer();

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

	// check if ftp is available
	FTPClient ftpClient = new FTPClient();
	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");
	userManagerFactory.setPasswordEncryptor(new SaltedPasswordEncryptor());
	UserManager um = userManagerFactory.createUserManager();

	BaseUser user = new BaseUser();

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

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

I’m using JUnit to build my integration tests, because I’m lazy and got used to running my tests with the junit view in Eclipse. 🙂 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, so no suprises on that end.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.