/* * 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 com.ok2c.lightmtp.examples; import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.channels.ReadableByteChannel; import java.nio.charset.CharsetDecoder; import java.nio.charset.CoderResult; import java.util.concurrent.Future; import org.apache.http.concurrent.BasicFuture; import org.apache.http.concurrent.FutureCallback; import org.apache.http.impl.nio.reactor.IOReactorConfig; import com.ok2c.lightmtp.SMTPCode; import com.ok2c.lightmtp.SMTPCodes; import com.ok2c.lightmtp.SMTPConsts; import com.ok2c.lightmtp.SMTPReply; import com.ok2c.lightmtp.agent.MailServerTransport; import com.ok2c.lightmtp.impl.agent.LocalMailServerTransport; import com.ok2c.lightmtp.impl.protocol.DefaultIdGenerator; import com.ok2c.lightmtp.message.SMTPContent; import com.ok2c.lightmtp.protocol.BasicDeliveryResult; import com.ok2c.lightmtp.protocol.DeliveryHandler; import com.ok2c.lightmtp.protocol.DeliveryRequest; import com.ok2c.lightmtp.protocol.DeliveryResult; import com.ok2c.lightmtp.protocol.EnvelopValidator; import com.ok2c.lightmtp.protocol.RemoteAddressValidator; import com.ok2c.lightmtp.util.InetAddressRange; public class LocalMailServerTransportExample { public static void main(final String[] args) throws Exception { File workingDir = new File("."); IOReactorConfig config = IOReactorConfig.custom() .setIoThreadCount(1) .build(); final MailServerTransport mta = new LocalMailServerTransport(workingDir, config); InetSocketAddress sockaddress = new InetSocketAddress("localhost", 2525); InetAddressRange iprange = new InetAddressRange(InetAddress.getByName("127.0.0.0"), 8); mta.start( new DefaultIdGenerator(), new MyRemoteAddressValidator(iprange), new MyEnvelopValidator(), new MyDeliveryHandler()); mta.listen(sockaddress); System.out.println("LMTP server listening on " + sockaddress); Runtime runtime = Runtime.getRuntime(); runtime.addShutdownHook(new Thread() { @Override public void run() { try { mta.shutdown(); } catch (IOException ex) { mta.forceShutdown(); } } }); } static class MyRemoteAddressValidator implements RemoteAddressValidator { private final InetAddressRange iprange; public MyRemoteAddressValidator(final InetAddressRange iprange) { super(); this.iprange = iprange; } @Override public boolean validateAddress(final InetAddress address) { return this.iprange.contains(address); } } static class MyEnvelopValidator implements EnvelopValidator { @Override public Future<SMTPReply> validateRecipient( final InetAddress client, final String recipient, final FutureCallback<SMTPReply> callback) { BasicFuture<SMTPReply> future = new BasicFuture<SMTPReply>(callback); SMTPReply reply = new SMTPReply(SMTPCodes.OK, new SMTPCode(2, 1, 5), "recipient <" + recipient + "> ok"); future.completed(reply); return future; } @Override public Future<SMTPReply> validateSender( final InetAddress client, final String sender, final FutureCallback<SMTPReply> callback) { BasicFuture<SMTPReply> future = new BasicFuture<SMTPReply>(callback); SMTPReply reply = new SMTPReply(SMTPCodes.OK, new SMTPCode(2, 1, 0), "originator <" + sender + "> ok"); future.completed(reply); return future; } } static class MyDeliveryHandler implements DeliveryHandler { @Override public Future<DeliveryResult> handle( final String messageId, final DeliveryRequest request, final FutureCallback<DeliveryResult> callback) { BasicFuture<DeliveryResult> future = new BasicFuture<DeliveryResult>(callback); try { System.out.println("====================================="); System.out.println("Mail from " + request.getSender() + " to " + request.getRecipients()); System.out.println("====================================="); System.out.println(readAsString(request.getContent())); System.out.println("====================================="); SMTPReply reply = new SMTPReply(SMTPCodes.OK, new SMTPCode(2, 1, 0), "ok"); BasicDeliveryResult result = new BasicDeliveryResult(reply); future.completed(result); } catch (IOException ex) { future.failed(ex); } return future; } private String readAsString( final SMTPContent<ReadableByteChannel> content) throws IOException { StringBuilder buffer = new StringBuilder(); ReadableByteChannel channel = content.channel(); try { CharsetDecoder decoder = SMTPConsts.ASCII.newDecoder(); ByteBuffer dst = ByteBuffer.allocate(1024); CharBuffer chars = CharBuffer.allocate(1024); int len; while ((len = channel.read(dst)) != -1) { dst.flip(); CoderResult result = decoder.decode(dst, chars, len == -1); if (result.isError()) { result.throwException(); } dst.compact(); chars.flip(); buffer.append(chars); chars.compact(); } } finally { content.reset(); } return buffer.toString(); } } }