Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Adding a MailRouter concept, which takes an email and processes it. H…

…ooking it up to the DATA part of our SmtpHandler.
  • Loading branch information...
commit a4b7c06b573564ddc67b5ff0452e367faeaf8f47 1 parent 7b101a0
@stevejwriter stevejwriter authored
View
4 ivy/ivy.xml
@@ -2,7 +2,7 @@
<!-- CONFIG: net.lag.example is the example project we're going to setup" -->
<!-- CONFIG: testclass is your test runner -->
<!-- CONFIG: jarclassname is the name of your main class to run via java -jar -->
- <!-- CONFIG: thriftpackage is where generated thrift classes go.
+ <!-- CONFIG: thriftpackage is where generated thrift classes go.
Only matters if you're using thrift. -->
<info organisation="com.saladwithsteve"
module="mailslot"
@@ -38,5 +38,7 @@
<dependency org="net.lag" name="naggati" rev="0.6" />
<dependency org="org.apache.mina" name="mina-core" rev="2.0.0-M4" />
<dependency org="org.slf4j" name="slf4j-jdk14" rev="1.5.2" />
+ <dependency org="javax.activation" name="activation" rev="1.1" />
+ <dependency org="javax.mail" name="mail" rev="1.4" />
</dependencies>
</ivy-module>
View
2  ivy/ivysettings.xml
@@ -16,8 +16,8 @@
<ibiblio name="scala-tools.org" m2compatible="true" root="http://scala-tools.org/repo-releases/" />
<ibiblio name="scala-tools.org-snapshots" m2compatible="true" root="http://scala-tools.org/repo-snapshots/" changingPattern=".*-SNAPSHOT" />
<!-- for smack, smackx -->
- <ibiblio name="reucon" m2compatible="true" root="http://maven.reucon.com/public/" />
<ibiblio name="maven2" m2compatible="true" />
+ <ibiblio name="reucon" m2compatible="true" root="http://maven.reucon.com/public/" />
<!-- for oauth -->
<ibiblio name="oauth.net" m2compatible="true" root="http://oauth.googlecode.com/svn/code/maven" />
<ibiblio name="download.java.net" m2compatible="true" root="http://download.java.net/maven/2/" />
View
27 src/main/scala/com/saladwithsteve/mailslot/MailRouter.scala
@@ -0,0 +1,27 @@
+/** Copyright 2009 Steve Jenson, under the Apache 2.0 License */
+package com.saladwithsteve.mailslot
+
+import java.io.ByteArrayInputStream
+import javax.mail.internet.MimeBodyPart
+
+object EmailBuilder {
+ def apply(buf: Array[Byte]): MimeBodyPart = {
+ val inputStream = new ByteArrayInputStream(buf)
+ new MimeBodyPart(inputStream)
+ }
+}
+
+/**
+ * A MailRouter takes all of the To: and Cc: headers and routes the email to correct destination.
+ *
+ */
+trait MailRouter {
+ def apply(email: MimeBodyPart)
+}
+
+
+class NoOpMailRouter(routeMap: Map[String, (MimeBodyPart) => Unit]) extends MailRouter {
+ def apply(email: MimeBodyPart) {
+ println("email: %s".format(email))
+ }
+}
View
6 src/main/scala/com/saladwithsteve/mailslot/Main.scala
@@ -30,6 +30,9 @@ object MailSlot {
val listenAddress = config.getString("listen_host", "0.0.0.0")
val listenPort = config.getInt("listen_port", 10025)
+ // FIXME: make this configurable via Configgy
+ val noop = new NoOpMailRouter(Map.empty)
+
acceptorExecutor = Executors.newCachedThreadPool()
acceptor = new NioSocketAcceptor(acceptorExecutor, new NioProcessor(acceptorExecutor))
@@ -39,7 +42,7 @@ object MailSlot {
acceptor.getSessionConfig.setTcpNoDelay(true)
acceptor.getFilterChain.addLast("codec", new ProtocolCodecFilter(smtp.Codec.encoder,
smtp.Codec.decoder))
- acceptor.setHandler(new IoHandlerActorAdapter(session => new SmtpHandler(session, config)))
+ acceptor.setHandler(new IoHandlerActorAdapter(session => new SmtpHandler(session, config, noop)))
acceptor.bind(new InetSocketAddress(listenAddress, listenPort))
log.info("Listening on port %s", listenPort)
@@ -47,6 +50,5 @@ object MailSlot {
actor {
deathSwitch.await
}
-
}
}
View
8 src/main/scala/com/saladwithsteve/mailslot/SmtpHandler.scala
@@ -10,7 +10,7 @@ import scala.actors.Actor
import scala.actors.Actor._
-class SmtpHandler(val session: IoSession, val config: Config) extends Actor {
+class SmtpHandler(val session: IoSession, val config: Config, val router: MailRouter) extends Actor {
private val log = Logger.get
val serverName = config.getString("server-name", "localhost")
@@ -100,6 +100,12 @@ class SmtpHandler(val session: IoSession, val config: Config) extends Actor {
writeResponse("354 Ok\r\n")
// FIXME: the client actually sends the body _after_ we send the 354 header so this code won't work.
writeResponse("250 Safely handled. %s".format(txnId))
+
+ // Once we've read the email, it's time to parse this with JavaMail and pass it along to the registered handler.
+ req.data match {
+ case Some(bytes) => router(EmailBuilder(bytes))
+ case None => log.warning("cannot route email with no data")
+ }
}
def vrfy(req: smtp.Request) {
Please sign in to comment.
Something went wrong with that request. Please try again.