/* * Copyright (C) Scott Cranton, Jakub Korab, and Christian Posta * https://github.com/CamelCookbook * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.camelcookbook.transactions.fileconsumption; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.mock.MockEndpoint; import org.apache.camel.test.junit4.CamelTestSupport; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Demonstrates the use of a Synchronization to change state depending on whether an Exchange completed or failed. */ public class FileConsumptionTest extends CamelTestSupport { private static Logger log = LoggerFactory.getLogger(FileConsumptionTest.class); public static final String TARGET_TEMP = "target/temp/"; public static final String TARGET_IN = "target/in/"; public static final String TARGET_OUT = "target/out/"; public static final String TARGET_ERRORS = "target/errors/"; @Override protected RouteBuilder createRouteBuilder() throws Exception { createTargetDirectories(); return new FileConsumptionRouteBuilder(TARGET_IN, TARGET_OUT, TARGET_ERRORS); } @Test public void testFileLocationOnError() throws IOException, InterruptedException { String text = "This message will explode"; MockEndpoint mockExplosion = getMockEndpoint("mock:explosion"); mockExplosion.expectedMessageCount(1); mockExplosion.message(0).body().isEqualTo(text); String fileName = "expectedToFail.txt"; safelyWriteFile(fileName, text); Thread.sleep(2000); // give the route a bit of time to work assertMockEndpointsSatisfied(); // check that the message never got to the output directory, and is in the errors directory assertTrue(!new File(TARGET_OUT + fileName).exists()); assertTrue(new File(TARGET_ERRORS + fileName).exists()); } @Test public void testFileLocationOnSuccess() throws IOException, InterruptedException { String fileName = "expectedToPass.txt"; String text = "This message should be written out with no problems"; MockEndpoint mockExplosion = getMockEndpoint("mock:explosion"); mockExplosion.expectedMessageCount(0); safelyWriteFile(fileName, text); Thread.sleep(2000); // give the route a bit of time to work assertMockEndpointsSatisfied(); // check that the message got to the output directory, and is not in the errors directory assertTrue(new File(TARGET_OUT + fileName).exists()); assertTrue(!new File(TARGET_ERRORS + fileName).exists()); } private void createTargetDirectories() { createIfNotExists(TARGET_TEMP); createIfNotExists(TARGET_IN); createIfNotExists(TARGET_OUT); createIfNotExists(TARGET_ERRORS); } private void createIfNotExists(String location) { File file = new File(location); if (file.exists()) { // delete it to make sure that any files from a previous run have been destroyed log.info("Deleting {}", file.getAbsolutePath()); delete(file); } if (!file.mkdirs()) { throw new IllegalStateException("Could not create " + file.getAbsolutePath() + ". Check your directory permissions."); } } private void delete(File file) { if (file.isDirectory()) { for (File child : file.listFiles()) { delete(child); } } if (!file.delete()) { throw new IllegalStateException("Failed to delete file: " + file); } } private void safelyWriteFile(String fileName, String text) throws IOException { File outputFile = new File(TARGET_TEMP + fileName); log.info("Writing temporary file: {}", outputFile.getAbsolutePath()); BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile)); writer.append(text); writer.close(); // move the file - the Camel file consumer doesn't like files being written at the same time File destination = new File(TARGET_IN + fileName); log.info("Moving temporary file to: {}", destination.getAbsolutePath()); outputFile.renameTo(destination); } }