private void loadRoutesDefinition( InputStream resourceAsStream, CamelContext context, String commandName) throws Exception { SmtpServer smtpd = mailMock.getSmtp(); ImapServer imapd = mailMock.getImap(); Map<String, Object> values = MapBuilder.<String, Object>newMapBuilder() .put("imaphost", imapd.getBindTo()) .put("imapport", imapd.getPort()) .put("commandname", commandName) .put("command", "D1=true;A2=123") .put("smtphost", smtpd.getBindTo()) .put("smtpport", smtpd.getPort()) .build(); String xml = replacePlaceHolders(toString(resourceAsStream), values); InputStream is = new ByteArrayInputStream(xml.getBytes()); try { context.addRouteDefinitions(context.loadRoutesDefinition(is).getRoutes()); } finally { is.close(); } }
/** * [ardulinktitle] [ardulinkversion] * * <p>project Ardulink http://www.ardulink.org/ * * <p>[adsense] */ public class ArdulinkMailOnCamelIntegrationTest { private static final String mockURI = "ardulink://mock"; private static final Map<? extends String, ? extends Object> IMAP_DEFAULTS = MapBuilder.<String, Object>newMapBuilder() .put("host", "localhost") .put("port", 143) .put("folderName", "INBOX") .put("unseen", true) .build(); private Link link; @Rule public GreenMailRule mailMock = new GreenMailRule(SMTP_IMAP); @Rule public Timeout timeout = new Timeout(10, SECONDS); @Before public void setup() throws URISyntaxException, Exception { link = Links.getLink(new URI(mockURI)); } @After public void tearDown() throws IOException { link.close(); } @Test public void canProcessViaImap() throws Exception { final String receiver = "*****@*****.**"; createMailUser(receiver, "loginIdReceiver", "secretOfReceiver"); String validSender = "*****@*****.**"; sendMailTo(receiver).from(validSender).withSubject(anySubject()).andText("usedScenario"); final String to = makeURI( mockURI, newMapBuilder() .put("validfroms", validSender) .put("scenario.xxx", "D13=false;A2=42") .put("scenario.usedScenario", "D13=true;A2=123") .put("scenario.yyy", "D13=false;A2=21") .build()); CamelContext context = new DefaultCamelContext(); context.addRoutes( new RouteBuilder() { @Override public void configure() { from(localImap(receiver)).to(to); } }); context.start(); waitUntilMailWasFetched(); context.stop(); Link mock = getMock(); verify(mock).switchDigitalPin(digitalPin(13), true); verify(mock).switchAnalogPin(analogPin(2), 123); verify(mock).close(); verifyNoMoreInteractions(mock); } private String localImap(String receiver) { ImapServer imapd = mailMock.getImap(); return makeURI( "imap://" + receiver, newMapBuilder() .putAll(IMAP_DEFAULTS) .put("username", "loginIdReceiver") .put("password", "secretOfReceiver") .put("port", imapd.getPort()) .put("unseen", true) .put("delete", true) .put("consumer.delay", MINUTES.toMillis(10)) .build()); } @Test public void canProcessMultipleLinks() throws Exception { final String receiver = "*****@*****.**"; createMailUser(receiver, "loginIdReceiver", "secretOfReceiver"); String validSender = "*****@*****.**"; sendMailTo(receiver).from(validSender).withSubject(anySubject()).andText("usedScenario"); Link link1 = Links.getLink(new URI(mockURI + "?num=1&foo=bar")); Link link2 = Links.getLink(new URI(mockURI + "?num=2&foo=bar")); final String to1 = makeURI( mockURI, newMapBuilder() .put("linkparams", encode("num=1&foo=bar")) .put("validfroms", validSender) .put("scenario.usedScenario", "D11=true;A12=11") .build()); final String to2 = makeURI( mockURI, newMapBuilder() .put("linkparams", encode("num=2&foo=bar")) .put("validfroms", validSender) .put("scenario.usedScenario", "D21=true;A22=23") .build()); try { CamelContext context = new DefaultCamelContext(); context.addRoutes( new RouteBuilder() { @Override public void configure() { from(localImap(receiver)) .multicast() .setAggregationStrategy(new UseOriginalAggregationStrategy()) .to(to1, to2); } }); context.start(); waitUntilMailWasFetched(); context.stop(); Link mock1 = getMock(link1); verify(mock1).switchDigitalPin(digitalPin(11), true); verify(mock1).switchAnalogPin(analogPin(12), 11); verify(mock1).close(); verifyNoMoreInteractions(mock1); Link mock2 = getMock(link2); verify(mock2).switchDigitalPin(digitalPin(21), true); verify(mock2).switchAnalogPin(analogPin(22), 23); verify(mock2).close(); verifyNoMoreInteractions(mock2); } finally { link1.close(); link2.close(); } } @Test public void canProcessMultipleLinksWhenCommandNotKnownOnLink2() throws Exception { final String receiver = "*****@*****.**"; createMailUser(receiver, "loginIdReceiver", "secretOfReceiver"); String validSender = "*****@*****.**"; sendMailTo(receiver).from(validSender).withSubject(anySubject()).andText("usedScenario"); Link link1 = Links.getLink(new URI(mockURI + "?num=1&foo=bar")); Link link2 = Links.getLink(new URI(mockURI + "?num=2&foo=bar")); final String to1 = makeURI( mockURI, newMapBuilder() .put("linkparams", encode("num=1&foo=bar")) .put("validfroms", validSender) .put("scenario.usedScenario", "D11=true;A12=11") .build()); final String to2 = makeURI( mockURI, newMapBuilder() .put("linkparams", encode("num=2&foo=bar")) .put("validfroms", validSender) .build()); try { CamelContext context = new DefaultCamelContext(); context.addRoutes( new RouteBuilder() { @Override public void configure() { from(localImap(receiver)) .multicast() .setAggregationStrategy(new UseOriginalAggregationStrategy()) .to(to1, to2); } }); context.start(); waitUntilMailWasFetched(); context.stop(); Link mock1 = getMock(link1); verify(mock1).switchDigitalPin(digitalPin(11), true); verify(mock1).switchAnalogPin(analogPin(12), 11); verify(mock1).close(); verifyNoMoreInteractions(mock1); Link mock2 = getMock(link2); verify(mock2).close(); verifyNoMoreInteractions(mock2); } finally { link1.close(); link2.close(); } } @Test public void writesResultToMock() throws Exception { final String receiver = "*****@*****.**"; createMailUser(receiver, "loginIdReceiver", "secretOfReceiver"); String validSender = "*****@*****.**"; createMailUser(validSender, "loginIdSender", "secretOfSender"); sendMailTo(receiver).from(validSender).withSubject(anySubject()).andText("usedScenario"); final String ardulink = makeURI( mockURI, newMapBuilder() .put("validfroms", validSender) .put("scenario.usedScenario", "D1=true") .build()); CamelContext context = new DefaultCamelContext(); final MockEndpoint mockEndpoint = context.getEndpoint("mock:result", MockEndpoint.class); context.addRoutes( new RouteBuilder() { @Override public void configure() { from(localImap(receiver)).to(ardulink).to(mockEndpoint); } }); context.start(); try { mockEndpoint.expectedMessageCount(1); mockEndpoint.expectedBodiesReceived("SwitchDigitalPinCommand " + "[pin=1, value=true]=OK"); mockEndpoint.assertIsSatisfied(); } finally { context.stop(); } } @Test public void writesResultToSender() throws Exception { final String receiver = "*****@*****.**"; createMailUser(receiver, "loginIdReceiver", "secretOfReceiver"); String validSender = "*****@*****.**"; createMailUser(validSender, "loginIdSender", "secretOfSender"); sendMailTo(receiver).from(validSender).withSubject(anySubject()).andText("usedScenario"); final String ardulink = makeURI( mockURI, newMapBuilder() .put("validfroms", validSender) .put("scenario.usedScenario", "D1=true;A2=123") .build()); SmtpServer smtpd = mailMock.getSmtp(); final String smtp = "smtp://" + smtpd.getBindTo() + ":" + smtpd.getPort() + "?username="******"loginIdReceiver" + "&password="******"secretOfReceiver" + "&debugMode=true"; CamelContext context = new DefaultCamelContext(); context.addRoutes( new RouteBuilder() { @Override public void configure() { from(localImap(receiver)) .to(ardulink) .setHeader("to", simple("${in.header.from}")) .setHeader("from", simple("${in.header.to}")) .to(smtp); } }); context.start(); try { assertThat( ((String) fetchMail("loginIdSender", "secretOfSender").getContent()), is( "SwitchDigitalPinCommand [pin=1, value=true]=OK\r\n" + "SwitchAnalogPinCommand [pin=2, value=123]=OK")); } finally { context.stop(); } } @Test public void writesResultToSender_ConfiguredViaXML() throws Exception { String receiver = "*****@*****.**"; createMailUser(receiver, "loginIdReceiver", "secretOfReceiver"); String validSender = "*****@*****.**"; createMailUser(validSender, "loginIdSender", "secretOfSender"); String commandName = "nameMe"; sendMailTo(receiver).from(validSender).withSubject(anySubject()).andText(commandName); InputStream is = getClass().getResourceAsStream("/ardulinkmail.xml"); try { CamelContext context = new DefaultCamelContext(); loadRoutesDefinition(is, context, commandName); context.start(); try { assertThat( ((String) fetchMail("loginIdSender", "secretOfSender").getContent()), is( "SwitchDigitalPinCommand [pin=1, value=true]=OK\r\n" + "SwitchAnalogPinCommand [pin=2, value=123]=OK")); } finally { context.stop(); } } finally { is.close(); } } private void loadRoutesDefinition( InputStream resourceAsStream, CamelContext context, String commandName) throws Exception { SmtpServer smtpd = mailMock.getSmtp(); ImapServer imapd = mailMock.getImap(); Map<String, Object> values = MapBuilder.<String, Object>newMapBuilder() .put("imaphost", imapd.getBindTo()) .put("imapport", imapd.getPort()) .put("commandname", commandName) .put("command", "D1=true;A2=123") .put("smtphost", smtpd.getBindTo()) .put("smtpport", smtpd.getPort()) .build(); String xml = replacePlaceHolders(toString(resourceAsStream), values); InputStream is = new ByteArrayInputStream(xml.getBytes()); try { context.addRouteDefinitions(context.loadRoutesDefinition(is).getRoutes()); } finally { is.close(); } } private static String replacePlaceHolders(String in, Map<?, ?> values) { StringBuilder builder = new StringBuilder(in); for (Entry<?, ?> entry : values.entrySet()) { String pattern = "${" + entry.getKey() + "}"; String value = entry.getValue().toString(); int start; while ((start = builder.indexOf(pattern)) != -1) { builder.replace(start, start + pattern.length(), value); } } return builder.toString(); } private static String toString(InputStream inputStream) { Scanner scanner = new Scanner(inputStream, "UTF-8"); try { return scanner.useDelimiter("\\A").next(); } finally { scanner.close(); } } private void createMailUser(String receiver, String id, String password) { mailMock.setUser(receiver, id, password); } private Message fetchMail(String loginId, String password) throws MessagingException, InterruptedException { ImapServer imapd = mailMock.getImap(); Message msg = null; while ((msg = retrieveViaImap(imapd.getBindTo(), imapd.getPort(), loginId, password)) == null) { MILLISECONDS.sleep(100); } return msg; } private Message retrieveViaImap(String host, int port, String user, String password) throws MessagingException { Properties props = new Properties(); props.setProperty("mail.store.protocol", "imap"); props.setProperty("mail.imap.port", String.valueOf(port)); Session session = Session.getInstance(props, null); Store store = session.getStore(); store.connect(host, user, password); Folder inbox = store.getFolder("INBOX"); inbox.open(Folder.READ_ONLY); int messageCount = inbox.getMessageCount(); return messageCount == 0 ? null : inbox.getMessage(1); } private String makeURI(String uri, Map<? extends Object, ? extends Object> kv) { return uri + "?" + Joiner.on("&").withKeyValueSeparator("=").join(kv); } private static String encode(String string) { return "RAW(" + string + ")"; } private String anySubject() { return "Subject"; } private void waitUntilMailWasFetched() throws InterruptedException { while (mailMock.getReceivedMessages().length > 0) { MILLISECONDS.sleep(50); } } private Link getMock() { return getMock(link); } private Link getMock(Link l) { return ((LinkDelegate) l).getDelegate(); } }