package com.oreilly.springdata.hadoop.filepolling; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Collection; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mortbay.log.Log; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.hadoop.fs.FsShell; import org.springframework.integration.Message; import org.springframework.integration.MessageHandlingException; import org.springframework.integration.channel.QueueChannel; import org.springframework.integration.message.GenericMessage; import org.springframework.integration.support.MessageBuilder; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.util.FileCopyUtils; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:/META-INF/spring/hadoop-context.xml" }) public class FsShellWritingMessageHandlerTests { static final String DEFAULT_ENCODING = "UTF-8"; static final String SAMPLE_CONTENT = "HelloWorld"; private File sourceFile; private FsShellWritingMessageHandler handler; private String outputDirectory = "/user/mpollack/tmp/output"; @Autowired private Configuration configuration; private FsShell fsShell; @Rule public TemporaryFolder temp = new TemporaryFolder() { public void create() throws IOException { super.create(); sourceFile = temp.newFile("sourceFile.txt"); Log.info("Generated source file = " + sourceFile); FileCopyUtils.copy(SAMPLE_CONTENT.getBytes(DEFAULT_ENCODING), new FileOutputStream(sourceFile, false)); } }; @Before public void init() { // TODO need to create a way to get a tmp directory in HDFS handler = new FsShellWritingMessageHandler(outputDirectory, configuration); fsShell = new FsShell(configuration); fsShell.rmr(outputDirectory); } @Test(expected = MessageHandlingException.class) public void unsupportedType() throws Exception { handler.handleMessage(new GenericMessage<Integer>(99)); Collection<FileStatus> fileStatusCollection = fsShell .ls(outputDirectory); assertTrue(fileStatusCollection.isEmpty()); } @Test public void filePayloadCopiedToNewFile() throws Exception { Message<?> message = MessageBuilder.withPayload(sourceFile).build(); QueueChannel output = new QueueChannel(); handler.setOutputChannel(output); handler.handleMessage(message); Message<?> result = output.receive(0); assertFileContentIsMatching(result); } @Test public void deleteFilesFalseByDefault() throws Exception { QueueChannel output = new QueueChannel(); handler.setOutputChannel(output); Message<?> message = MessageBuilder.withPayload(sourceFile).build(); handler.handleMessage(message); Message<?> result = output.receive(0); assertFileContentIsMatching(result); assertTrue(sourceFile.exists()); } @Test public void deleteFilesTrueWithFilePayload() throws Exception { QueueChannel output = new QueueChannel(); handler.setDeleteSourceFiles(true); handler.setOutputChannel(output); Message<?> message = MessageBuilder.withPayload(sourceFile).build(); handler.handleMessage(message); Message<?> result = output.receive(0); assertFileContentIsMatching(result); assertFalse(sourceFile.exists()); } void assertFileContentIsMatching(Message<?> result) throws IOException, UnsupportedEncodingException { assertThat(result, is(notNullValue())); assertThat(result.getPayload(), is(instanceOf(Path.class))); Path destFile = (Path) result.getPayload(); assertNotSame(destFile, sourceFile); String uri = destFile.toUri().toString(); assertThat(fsShell.test(uri), is(true)); FileSystem hdpFileSystem = destFile.getFileSystem(configuration); assertThat(hdpFileSystem.isFile(destFile), is(true)); Collection<String> content = fsShell.text(uri); assertThat(content.isEmpty(), is(false)); assertThat(content.iterator().next(), is(SAMPLE_CONTENT)); } }