Java tutorial
/**************************************************************** * Licensed to the Apache Software Foundation (ASF) under one * * or more contributor license agreements. See the NOTICE file * * distributed with this work for additional information * * regarding copyright ownership. The ASF licenses this file * * to you 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.apache.james.protocols.lmtp; import static org.junit.Assert.*; import java.io.IOException; import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.net.smtp.RelayPath; import org.apache.commons.net.smtp.SMTPClient; import org.apache.commons.net.smtp.SMTPReply; import org.apache.james.protocols.api.Protocol; import org.apache.james.protocols.api.ProtocolServer; import org.apache.james.protocols.api.handler.ProtocolHandler; import org.apache.james.protocols.api.handler.WiringException; import org.apache.james.protocols.api.utils.MockLogger; import org.apache.james.protocols.api.utils.TestUtils; import org.apache.james.protocols.lmtp.hook.DeliverToRecipientHook; import org.apache.james.protocols.smtp.MailAddress; import org.apache.james.protocols.smtp.MailEnvelope; import org.apache.james.protocols.smtp.SMTPProtocol; import org.apache.james.protocols.smtp.AbstractSMTPServerTest; import org.apache.james.protocols.smtp.SMTPSession; import org.apache.james.protocols.smtp.hook.HookResult; import org.apache.james.protocols.smtp.hook.HookReturnCode; import org.apache.james.protocols.smtp.hook.MessageHook; import org.apache.james.protocols.smtp.utils.TestMessageHook; import org.junit.Test; public abstract class AbstractLMTPServerTest extends AbstractSMTPServerTest { @Override protected Protocol createProtocol(ProtocolHandler... handlers) throws WiringException { LMTPProtocolHandlerChain chain = new LMTPProtocolHandlerChain(); List<ProtocolHandler> hList = new ArrayList<ProtocolHandler>(); for (ProtocolHandler handler : handlers) { if (handler instanceof MessageHook) { handler = new MessageHookAdapter((MessageHook) handler); } hList.add(handler); } chain.addAll(0, hList); chain.wireExtensibleHandlers(); return new SMTPProtocol(chain, new LMTPConfigurationImpl(), new MockLogger()); } @Override public void testInvalidNoBracketsEnformance() throws Exception { // Disable } @Override public void testHeloEnforcement() throws Exception { // Disable } @Override public void testHeloEnforcementDisabled() throws Exception { // Disable } @Override public void testMailWithoutBrackets() throws Exception { TestMessageHook hook = new TestMessageHook(); InetSocketAddress address = new InetSocketAddress("127.0.0.1", TestUtils.getFreePort()); ProtocolServer server = null; try { server = createServer(createProtocol(hook), address); server.bind(); SMTPClient client = createClient(); client.connect(address.getAddress().getHostAddress(), address.getPort()); assertTrue(SMTPReply.isPositiveCompletion(client.getReplyCode())); client.helo("localhost"); assertTrue(SMTPReply.isPositiveCompletion(client.getReplyCode())); client.mail(SENDER); assertTrue("Reply=" + client.getReplyString(), SMTPReply.isPositiveCompletion(client.getReplyCode())); client.quit(); assertTrue("Reply=" + client.getReplyString(), SMTPReply.isPositiveCompletion(client.getReplyCode())); client.disconnect(); Iterator<MailEnvelope> queued = hook.getQueued().iterator(); assertFalse(queued.hasNext()); } finally { if (server != null) { server.unbind(); } } } @Override public void testRcptWithoutBrackets() throws Exception { TestMessageHook hook = new TestMessageHook(); InetSocketAddress address = new InetSocketAddress("127.0.0.1", TestUtils.getFreePort()); ProtocolServer server = null; try { server = createServer(createProtocol(hook), address); server.bind(); SMTPClient client = createClient(); client.connect(address.getAddress().getHostAddress(), address.getPort()); assertTrue(SMTPReply.isPositiveCompletion(client.getReplyCode())); client.helo("localhost"); assertTrue(SMTPReply.isPositiveCompletion(client.getReplyCode())); client.setSender(SENDER); assertTrue("Reply=" + client.getReplyString(), SMTPReply.isPositiveCompletion(client.getReplyCode())); client.rcpt(RCPT1); assertTrue("Reply=" + client.getReplyString(), SMTPReply.isPositiveCompletion(client.getReplyCode())); client.quit(); assertTrue("Reply=" + client.getReplyString(), SMTPReply.isPositiveCompletion(client.getReplyCode())); client.disconnect(); Iterator<MailEnvelope> queued = hook.getQueued().iterator(); assertFalse(queued.hasNext()); } finally { if (server != null) { server.unbind(); } } } @Test public void testEhloNotSupported() throws Exception { TestMessageHook hook = new TestMessageHook(); InetSocketAddress address = new InetSocketAddress("127.0.0.1", TestUtils.getFreePort()); ProtocolServer server = null; try { server = createServer(createProtocol(hook), address); server.bind(); SMTPClient client = createClient(); client.connect(address.getAddress().getHostAddress(), address.getPort()); assertTrue(SMTPReply.isPositiveCompletion(client.getReplyCode())); client.sendCommand("HELO localhost"); assertTrue(SMTPReply.isNegativePermanent(client.getReplyCode())); client.quit(); assertTrue("Reply=" + client.getReplyString(), SMTPReply.isPositiveCompletion(client.getReplyCode())); client.disconnect(); Iterator<MailEnvelope> queued = hook.getQueued().iterator(); assertFalse(queued.hasNext()); } finally { if (server != null) { server.unbind(); } } } @Test public void testDeliveryHook() throws Exception { TestDeliverHook deliverHook = new TestDeliverHook(); InetSocketAddress address = new InetSocketAddress("127.0.0.1", TestUtils.getFreePort()); ProtocolServer server = null; try { server = createServer(createProtocol(deliverHook), address); server.bind(); SMTPClient client = createClient(); client.connect(address.getAddress().getHostAddress(), address.getPort()); assertTrue(SMTPReply.isPositiveCompletion(client.getReplyCode())); client.helo("localhost"); assertTrue(SMTPReply.isPositiveCompletion(client.getReplyCode())); client.setSender(SENDER); assertTrue("Reply=" + client.getReplyString(), SMTPReply.isPositiveCompletion(client.getReplyCode())); client.addRecipient(RCPT1); assertTrue("Reply=" + client.getReplyString(), SMTPReply.isPositiveCompletion(client.getReplyCode())); client.addRecipient(RCPT2); assertTrue("Reply=" + client.getReplyString(), SMTPReply.isPositiveCompletion(client.getReplyCode())); assertTrue(client.sendShortMessageData(MSG1)); int[] replies = ((LMTPClient) client).getReplies(); assertEquals("Expected two replies", 2, replies.length); assertTrue(SMTPReply.isNegativePermanent(replies[0])); assertTrue(SMTPReply.isPositiveCompletion(replies[1])); client.quit(); assertTrue("Reply=" + client.getReplyString(), SMTPReply.isPositiveCompletion(client.getReplyCode())); client.disconnect(); Iterator<MailEnvelope> queued = deliverHook.getDelivered().iterator(); assertTrue(queued.hasNext()); MailEnvelope env = queued.next(); checkEnvelope(env, SENDER, Arrays.asList(RCPT1, RCPT2), MSG1); assertFalse(queued.hasNext()); } finally { if (server != null) { server.unbind(); } } } protected SMTPClient createClient() { return new LMTPClientImpl(); } private final class LMTPClientImpl extends SMTPClient implements LMTPClient { private final List<Integer> replies = new ArrayList<Integer>(); private int rcptCount = 0; @Override public boolean addRecipient(String address) throws IOException { boolean ok = super.addRecipient(address); if (ok) { rcptCount++; } return ok; } @Override public boolean addRecipient(RelayPath path) throws IOException { boolean ok = super.addRecipient(path); if (ok) { rcptCount++; } return ok; } /** * Issue the LHLO command */ @Override public int helo(String hostname) throws IOException { return sendCommand("LHLO", hostname); } public int[] getReplies() throws IOException { int[] codes = new int[replies.size()]; for (int i = 0; i < codes.length; i++) { codes[i] = replies.remove(0); } return codes; } @Override public boolean completePendingCommand() throws IOException { for (int i = 0; i < rcptCount; i++) { replies.add(getReply()); } for (int code : replies) { if (SMTPReply.isPositiveCompletion(code)) { return true; } } return false; } } private final class MessageHookAdapter implements DeliverToRecipientHook { private final MessageHook hook; private HookResult result; public MessageHookAdapter(MessageHook hook) { this.hook = hook; } /* * (non-Javadoc) * @see org.apache.james.protocols.lmtp.hook.DeliverToRecipientHook#deliver(org.apache.james.protocols.smtp.SMTPSession, org.apache.james.protocols.smtp.MailAddress, org.apache.james.protocols.smtp.MailEnvelope) */ public HookResult deliver(SMTPSession session, MailAddress recipient, MailEnvelope envelope) { if (result == null) { result = hook.onMessage(session, envelope); } return result; } @Override public void init(Configuration config) throws ConfigurationException { } @Override public void destroy() { } } private final class TestDeliverHook implements DeliverToRecipientHook { private final List<MailEnvelope> delivered = new ArrayList<MailEnvelope>(); /* * (non-Javadoc) * @see org.apache.james.protocols.lmtp.hook.DeliverToRecipientHook#deliver(org.apache.james.protocols.smtp.SMTPSession, org.apache.james.protocols.smtp.MailAddress, org.apache.james.protocols.smtp.MailEnvelope) */ public HookResult deliver(SMTPSession session, MailAddress recipient, MailEnvelope envelope) { if (RCPT1.equals(recipient.toString())) { return new HookResult(HookReturnCode.DENY); } else { delivered.add(envelope); return new HookResult(HookReturnCode.OK); } } public List<MailEnvelope> getDelivered() { return delivered; } @Override public void init(Configuration config) throws ConfigurationException { } @Override public void destroy() { } } }