You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by no...@apache.org on 2009/10/15 16:18:20 UTC
svn commit: r825502 - in
/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/mina:
AbstractAsyncServer.java AsyncSMTPServer.java
Author: norman
Date: Thu Oct 15 14:18:19 2009
New Revision: 825502
URL: http://svn.apache.org/viewvc?rev=825502&view=rev
Log:
Factor out base functions for providing an NIO based Server
Added:
james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/mina/AbstractAsyncServer.java
Modified:
james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/mina/AsyncSMTPServer.java
Added: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/mina/AbstractAsyncServer.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/mina/AbstractAsyncServer.java?rev=825502&view=auto
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/mina/AbstractAsyncServer.java (added)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/mina/AbstractAsyncServer.java Thu Oct 15 14:18:19 2009
@@ -0,0 +1,478 @@
+/****************************************************************
+ * 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.smtpserver.mina;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+
+import javax.annotation.Resource;
+
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.LogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.impl.AvalonLogger;
+import org.apache.james.Constants;
+import org.apache.james.api.dnsservice.DNSService;
+import org.apache.james.api.kernel.LoaderService;
+import org.apache.james.services.FileSystem;
+import org.apache.james.services.MailServer;
+import org.apache.james.smtpserver.mina.filter.ConnectionFilter;
+import org.apache.mailet.MailetContext;
+import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
+import org.apache.mina.core.service.IoHandler;
+import org.apache.mina.core.session.IdleStatus;
+import org.apache.mina.filter.codec.ProtocolCodecFilter;
+import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
+import org.apache.mina.filter.ssl.BogusTrustManagerFactory;
+import org.apache.mina.filter.ssl.KeyStoreFactory;
+import org.apache.mina.filter.ssl.SslContextFactory;
+import org.apache.mina.transport.socket.SocketAcceptor;
+import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
+
+/**
+ * Abstract base class for Servers which want to use async io
+ *
+ */
+public abstract class AbstractAsyncServer implements LogEnabled, Initializable, Serviceable, Configurable{
+ /**
+ * The default value for the connection backlog.
+ */
+ private static final int DEFAULT_BACKLOG = 5;
+
+ /**
+ * The default value for the connection timeout.
+ */
+ private static final int DEFAULT_TIMEOUT = 5* 60 * 1000;
+
+ /**
+ * The name of the parameter defining the connection timeout.
+ */
+ private static final String TIMEOUT_NAME = "connectiontimeout";
+
+ /**
+ * The name of the parameter defining the connection backlog.
+ */
+ private static final String BACKLOG_NAME = "connectionBacklog";
+
+ /**
+ * The name of the parameter defining the service hello name.
+ */
+ public static final String HELLO_NAME = "helloName";
+
+
+ /**
+ * The mailet context - we access it here to set the hello name for the Mailet API
+ */
+ private MailetContext mailetcontext;
+
+ private FileSystem fileSystem;
+
+ /**
+ * The internal mail server service.
+ */
+ private MailServer mailServer;
+
+ /** Loads instances */
+ private LoaderService loader;
+
+ private Logger logger;
+
+ private DNSService dns;
+
+ private boolean enabled;
+
+ private int connPerIP;
+
+ private boolean useStartTLS;
+
+ private int connectionLimit;
+
+ private String helloName;
+
+ private String keystore;
+
+ private String secret;
+
+ private int backlog;
+
+ private InetAddress bindTo;
+
+ private int port;
+
+ private int timeout;
+
+ private SslContextFactory contextFactory;;
+
+ /**
+ * Gets the current instance loader.
+ * @return the loader
+ */
+ public final LoaderService getLoader() {
+ return loader;
+ }
+
+ /**
+ * Sets the loader to be used for instances.
+ * @param loader the loader to set, not null
+ */
+ @Resource(name="org.apache.james.LoaderService")
+ public final void setLoader(LoaderService loader) {
+ this.loader = loader;
+ }
+
+ public void setDNSService(DNSService dns) {
+ this.dns = dns;
+ }
+
+ public void setFileSystem(FileSystem filesystem) {
+ this.fileSystem = filesystem;
+ }
+
+ public void setMailServer(MailServer mailServer) {
+ this.mailServer = mailServer;
+ }
+
+ public void setMailetContext(MailetContext mailetcontext) {
+ this.mailetcontext = mailetcontext;
+ }
+
+
+ /**
+ * @see org.apache.avalon.framework.logger.LogEnabled#enableLogging(org.apache.avalon.framework.logger.Logger)
+ */
+ public void enableLogging(Logger logger) {
+ this.logger = logger;
+ }
+
+ /**
+ * @see org.apache.avalon.framework.activity.Initializable#initialize()
+ */
+ public void initialize() throws Exception {
+ preInit();
+ buildSSLContextFactory();
+ SocketAcceptor acceptor = new NioSocketAcceptor();
+ acceptor.setFilterChainBuilder(createIoFilterChainBuilder());
+ acceptor.setBacklog(backlog);
+ acceptor.setReuseAddress(true);
+ acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, timeout );
+ acceptor.setHandler(createIoHandler());
+ acceptor.bind(new InetSocketAddress(bindTo,port));
+ }
+
+ /**
+ * This method is called on init of the Server. Subclasses should override this method to init stuff
+ * @throws Exception
+ */
+ protected void preInit() throws Exception {
+ // TODO Auto-generated method stub
+
+ }
+
+ protected DNSService getDNSService() {
+ return dns;
+ }
+
+ protected MailServer getMailServer() {
+ return mailServer;
+ }
+
+ protected MailetContext getMailetContext() {
+ return mailetcontext;
+ }
+
+ protected FileSystem getFileSystem() {
+ return fileSystem;
+ }
+ /**
+ * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+ */
+ public void service( final ServiceManager manager ) throws ServiceException {
+ setMailetContext((MailetContext) manager.lookup("org.apache.mailet.MailetContext"));
+ setMailServer((MailServer) manager.lookup(MailServer.ROLE));
+ setDNSService((DNSService) manager.lookup(DNSService.ROLE));
+ setFileSystem((FileSystem) manager.lookup(FileSystem.ROLE));
+ }
+
+ /**
+ * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+ */
+ public void configure(Configuration configuration) throws ConfigurationException {
+ enabled = configuration.getAttributeAsBoolean("enabled", true);
+ final Logger logger = getLogger();
+ if (!enabled) {
+ logger.info(getServiceType() + " disabled by configuration");
+ return;
+ }
+
+ Configuration handlerConfiguration = configuration.getChild("handler");
+
+
+ /*
+ boolean streamdump=handlerConfiguration.getChild("streamdump").getAttributeAsBoolean("enabled", false);
+ String streamdumpDir=streamdump ? handlerConfiguration.getChild("streamdump").getAttribute("directory", null) : null;
+ setStreamDumpDir(streamdumpDir);
+ */
+
+ port = configuration.getChild("port").getValueAsInteger(getDefaultPort());
+
+
+
+ StringBuilder infoBuffer;
+
+
+ try {
+ final String bindAddress = configuration.getChild("bind").getValue(null);
+ if( null != bindAddress ) {
+ bindTo = InetAddress.getByName(bindAddress);
+ infoBuffer =
+ new StringBuilder(64)
+ .append(getServiceType())
+ .append(" bound to: ")
+ .append(bindTo);
+ logger.info(infoBuffer.toString());
+ }
+ }
+ catch( final UnknownHostException unhe ) {
+ throw new ConfigurationException( "Malformed bind parameter in configuration of service " + getServiceType(), unhe );
+ }
+
+ configureHelloName(handlerConfiguration);
+
+ timeout = handlerConfiguration.getChild(TIMEOUT_NAME).getValueAsInteger(DEFAULT_TIMEOUT);
+
+ infoBuffer =
+ new StringBuilder(64)
+ .append(getServiceType())
+ .append(" handler connection timeout is: ")
+ .append(timeout);
+ logger.info(infoBuffer.toString());
+
+ backlog = configuration.getChild(BACKLOG_NAME).getValueAsInteger(DEFAULT_BACKLOG);
+
+ infoBuffer =
+ new StringBuilder(64)
+ .append(getServiceType())
+ .append(" connection backlog is: ")
+ .append(backlog);
+ logger.info(infoBuffer.toString());
+
+
+ String connectionLimitString = configuration.getChild("connectionLimit").getValue(null);
+ if (connectionLimitString != null) {
+ try {
+ connectionLimit = new Integer(connectionLimitString);
+ } catch (NumberFormatException nfe) {
+ logger.error("Connection limit value is not properly formatted.", nfe);
+ }
+ if (connectionLimit < 0) {
+ logger.error("Connection limit value cannot be less than zero.");
+ throw new ConfigurationException("Connection limit value cannot be less than zero.");
+ } else if (connectionLimit > 0){
+ infoBuffer = new StringBuilder(128)
+ .append(getServiceType())
+ .append(" will allow a maximum of ")
+ .append(connectionLimitString)
+ .append(" connections.");
+ logger.info(infoBuffer.toString());
+ }
+ }
+
+ String connectionLimitPerIP = handlerConfiguration.getChild("connectionLimitPerIP").getValue(null);
+ if (connectionLimitPerIP != null) {
+ try {
+ connPerIP = new Integer(connectionLimitPerIP).intValue();
+ } catch (NumberFormatException nfe) {
+ logger.error("Connection limit per IP value is not properly formatted.", nfe);
+ }
+ if (connPerIP < 0) {
+ logger.error("Connection limit per IP value cannot be less than zero.");
+ throw new ConfigurationException("Connection limit value cannot be less than zero.");
+ } else if (connPerIP > 0){
+ infoBuffer = new StringBuilder(128)
+ .append(getServiceType())
+ .append(" will allow a maximum of ")
+ .append(connPerIP)
+ .append(" per IP connections for " +getServiceType());
+ logger.info(infoBuffer.toString());
+ }
+ }
+
+
+ Configuration tlsConfig = configuration.getChild("startTLS");
+ if (tlsConfig != null) {
+ useStartTLS = tlsConfig.getAttributeAsBoolean("enable", false);
+
+ if (useStartTLS) {
+ keystore = tlsConfig.getChild("keystore").getValue(null);
+ if (keystore == null) {
+ throw new ConfigurationException("keystore needs to get configured");
+ }
+ secret = tlsConfig.getChild("secret").getValue("");
+ }
+ }
+
+ helloName = (String) mailetcontext.getAttribute(Constants.HELLO_NAME);
+ }
+
+
+ private void configureHelloName(Configuration handlerConfiguration) {
+ StringBuilder infoBuffer;
+ String hostName = null;
+ try {
+ hostName = dns.getHostName(dns.getLocalHost());
+ } catch (UnknownHostException ue) {
+ hostName = "localhost";
+ }
+
+ infoBuffer =
+ new StringBuilder(64)
+ .append(getServiceType())
+ .append(" is running on: ")
+ .append(hostName);
+ getLogger().info(infoBuffer.toString());
+
+ Configuration helloConf = handlerConfiguration.getChild(HELLO_NAME);
+
+ if (helloConf != null) {
+ boolean autodetect = helloConf.getAttributeAsBoolean("autodetect", true);
+ if (autodetect) {
+ helloName = hostName;
+ } else {
+ // Should we use the defaultdomain here ?
+ helloName = helloConf.getValue("localhost");
+ }
+ } else {
+ helloName = null;
+ }
+ infoBuffer =
+ new StringBuilder(64)
+ .append(getServiceType())
+ .append(" handler hello name is: ")
+ .append(helloName);
+ getLogger().info(infoBuffer.toString());
+ }
+
+ /**
+ * Return the port this server will listen on
+ *
+ * @return port
+ */
+ public int getPort() {
+ return port;
+ }
+
+ /**
+ * Return the logger
+ *
+ * @return logger
+ */
+ protected Logger getLogger() {
+ return logger;
+ }
+
+ /**
+ * Return if the server is enabled by the configuration
+ *
+ * @return enabled
+ */
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ /**
+ * Return helloName for this server
+ *
+ * @return helloName
+ */
+ public String getHelloName() {
+ return helloName;
+ }
+
+
+ /**
+ * Return if startTLS is supported by this server
+ *
+ * @return startTlsSupported
+ */
+ protected boolean isStartTLSSupported() {
+ return useStartTLS;
+ }
+
+ private void buildSSLContextFactory() throws Exception{
+ if (useStartTLS) {
+ KeyStoreFactory kfactory = new KeyStoreFactory();
+ kfactory.setDataFile(fileSystem.getFile(keystore));
+ kfactory.setPassword(secret);
+
+ contextFactory = new SslContextFactory();
+ contextFactory.setKeyManagerFactoryKeyStore(kfactory.newInstance());
+ contextFactory.setKeyManagerFactoryAlgorithm("SunX509");
+ contextFactory.setTrustManagerFactory(new BogusTrustManagerFactory());
+ contextFactory.setKeyManagerFactoryKeyStorePassword(secret);
+ }
+ }
+
+ /**
+ * Createh IoHandler to use by this Server implementation
+ *
+ * @return ioHandler
+ */
+ protected abstract IoHandler createIoHandler();
+
+ /**
+ * Return the SslContextFactory which was created for this service.
+ *
+ * @return contextFactory
+ */
+ protected SslContextFactory getSslContextFactory() {
+ return contextFactory;
+ }
+
+ protected DefaultIoFilterChainBuilder createIoFilterChainBuilder() {
+ ProtocolCodecFilter codecFactory = new ProtocolCodecFilter(new TextLineCodecFactory());
+ Log cLogger = new AvalonLogger(getLogger());
+
+ DefaultIoFilterChainBuilder builder = new DefaultIoFilterChainBuilder();
+ builder.addLast("protocolCodecFactory", codecFactory);
+ builder.addLast("connectionFilter", new ConnectionFilter(cLogger, connectionLimit, connPerIP));
+ return builder;
+ }
+
+ /**
+ * Return the default port which will get used for this server if non is specify in the configuration
+ *
+ * @return port
+ */
+ protected abstract int getDefaultPort();
+
+ /**
+ * Return textual representation of the service this server provide
+ *
+ * @return serviceType
+ */
+ protected abstract String getServiceType();
+}
Modified: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/mina/AsyncSMTPServer.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/mina/AsyncSMTPServer.java?rev=825502&r1=825501&r2=825502&view=diff
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/mina/AsyncSMTPServer.java (original)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/mina/AsyncSMTPServer.java Thu Oct 15 14:18:19 2009
@@ -21,45 +21,19 @@
package org.apache.james.smtpserver.mina;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-
-import javax.annotation.Resource;
-
-import org.apache.avalon.framework.activity.Initializable;
-import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
-import org.apache.avalon.framework.logger.AbstractLogEnabled;
-import org.apache.avalon.framework.logger.Logger;
-import org.apache.avalon.framework.service.ServiceException;
-import org.apache.avalon.framework.service.ServiceManager;
-import org.apache.avalon.framework.service.Serviceable;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.impl.AvalonLogger;
-import org.apache.james.Constants;
-import org.apache.james.api.dnsservice.DNSService;
import org.apache.james.api.dnsservice.util.NetMatcher;
-import org.apache.james.api.kernel.LoaderService;
-import org.apache.james.services.FileSystem;
-import org.apache.james.services.MailServer;
-import org.apache.james.smtpserver.mina.filter.ConnectionFilter;
import org.apache.james.smtpserver.mina.filter.RequestValidationFilter;
import org.apache.james.smtpserver.mina.filter.SMTPResponseFilter;
import org.apache.james.smtpserver.protocol.SMTPConfiguration;
import org.apache.james.smtpserver.protocol.SMTPHandlerChain;
import org.apache.james.smtpserver.protocol.SMTPServerMBean;
import org.apache.james.socket.configuration.JamesConfiguration;
-import org.apache.mailet.MailetContext;
-import org.apache.mina.core.session.IdleStatus;
-import org.apache.mina.filter.codec.ProtocolCodecFilter;
-import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
-import org.apache.mina.filter.ssl.BogusTrustManagerFactory;
-import org.apache.mina.filter.ssl.KeyStoreFactory;
-import org.apache.mina.filter.ssl.SslContextFactory;
-import org.apache.mina.transport.socket.SocketAcceptor;
-import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
+import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
+import org.apache.mina.core.service.IoHandler;
/**
* <p>Accepts SMTP connections on a server socket and dispatches them to SMTPHandlers.</p>
@@ -72,32 +46,8 @@
* IMPORTANT: SMTPServer extends AbstractJamesService. If you implement ANY
* lifecycle methods, you MUST call super.<method> as well.
*/
-public class AsyncSMTPServer extends AbstractLogEnabled implements SMTPServerMBean, Serviceable, Initializable, Configurable {
- /**
- * The default value for the connection backlog.
- */
- protected static final int DEFAULT_BACKLOG = 5;
-
- /**
- * The default value for the connection timeout.
- */
- protected static final int DEFAULT_TIMEOUT = 5* 60 * 1000;
-
- /**
- * The name of the parameter defining the connection timeout.
- */
- protected static final String TIMEOUT_NAME = "connectiontimeout";
-
- /**
- * The name of the parameter defining the connection backlog.
- */
- protected static final String BACKLOG_NAME = "connectionBacklog";
-
- /**
- * The name of the parameter defining the service hello name.
- */
- public static final String HELLO_NAME = "helloName";
-
+public class AsyncSMTPServer extends AbstractAsyncServer implements SMTPServerMBean {
+
/**
* The handler chain - SMTPhandlers can lookup handlerchain to obtain
* Command handlers , Message handlers and connection handlers
@@ -105,21 +55,7 @@
*/
private SMTPHandlerChain handlerChain;
- /**
- * The mailet context - we access it here to set the hello name for the Mailet API
- */
- private MailetContext mailetcontext;
-
- private FileSystem fileSystem;
-
- /**
- * The internal mail server service.
- */
- private MailServer mailServer;
-
- /** Loads instances */
- private LoaderService loader;
-
+
/** Cached configuration data for handler */
private Configuration handlerConfiguration;
@@ -169,196 +105,14 @@
private boolean addressBracketsEnforcement = true;
- private DNSService dns;
-
- public String helloName;
-
- private boolean enabled;
-
- private int port;
-
- private InetAddress bindTo;
-
- private int timeout;
-
- private int backlog;
- private int connectionLimit = 0;
- private int connPerIP = 0;
-
- private boolean useStartTLS;
-
- private String keystore;
-
- private String secret;
-
-
- /**
- * Gets the current instance loader.
- * @return the loader
- */
- public final LoaderService getLoader() {
- return loader;
- }
-
- /**
- * Sets the loader to be used for instances.
- * @param loader the loader to set, not null
- */
- @Resource(name="org.apache.james.LoaderService")
- public final void setLoader(LoaderService loader) {
- this.loader = loader;
- }
-
- public void setDNSService(DNSService dns) {
- this.dns = dns;
- }
-
- public void setFileSystem(FileSystem filesystem) {
- this.fileSystem = filesystem;
- }
-
- public void setMailServer(MailServer mailServer) {
- this.mailServer = mailServer;
- }
-
- public void setMailetContext(MailetContext mailetcontext) {
- this.mailetcontext = mailetcontext;
- }
-
- /**
- * @see org.apache.avalon.framework.service.Serviceable#service(ServiceManager)
- */
- public void service( final ServiceManager manager ) throws ServiceException {
- setMailetContext((MailetContext) manager.lookup("org.apache.mailet.MailetContext"));
- setMailServer((MailServer) manager.lookup(MailServer.ROLE));
- setDNSService((DNSService) manager.lookup(DNSService.ROLE));
- setFileSystem((FileSystem) manager.lookup(FileSystem.ROLE));
- }
/**
* @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
*/
public void configure(final Configuration configuration) throws ConfigurationException {
- enabled = configuration.getAttributeAsBoolean("enabled", true);
- final Logger logger = getLogger();
- if (!enabled) {
- logger.info(getServiceType() + " disabled by configuration");
- return;
- }
-
- Configuration handlerConfiguration = configuration.getChild("handler");
-
-
- /*
- boolean streamdump=handlerConfiguration.getChild("streamdump").getAttributeAsBoolean("enabled", false);
- String streamdumpDir=streamdump ? handlerConfiguration.getChild("streamdump").getAttribute("directory", null) : null;
- setStreamDumpDir(streamdumpDir);
- */
-
- port = configuration.getChild("port").getValueAsInteger(25);
-
-
-
- StringBuilder infoBuffer;
-
-
- try {
- final String bindAddress = configuration.getChild("bind").getValue(null);
- if( null != bindAddress ) {
- bindTo = InetAddress.getByName(bindAddress);
- infoBuffer =
- new StringBuilder(64)
- .append(getServiceType())
- .append(" bound to: ")
- .append(bindTo);
- logger.info(infoBuffer.toString());
- }
- }
- catch( final UnknownHostException unhe ) {
- throw new ConfigurationException( "Malformed bind parameter in configuration of service " + getServiceType(), unhe );
- }
-
- configureHelloName(handlerConfiguration);
-
- timeout = handlerConfiguration.getChild(TIMEOUT_NAME).getValueAsInteger(DEFAULT_TIMEOUT);
-
- infoBuffer =
- new StringBuilder(64)
- .append(getServiceType())
- .append(" handler connection timeout is: ")
- .append(timeout);
- logger.info(infoBuffer.toString());
-
- backlog = configuration.getChild(BACKLOG_NAME).getValueAsInteger(DEFAULT_BACKLOG);
-
- infoBuffer =
- new StringBuilder(64)
- .append(getServiceType())
- .append(" connection backlog is: ")
- .append(backlog);
- logger.info(infoBuffer.toString());
-
-
- String connectionLimitString = configuration.getChild("connectionLimit").getValue(null);
- if (connectionLimitString != null) {
- try {
- connectionLimit = new Integer(connectionLimitString);
- } catch (NumberFormatException nfe) {
- logger.error("Connection limit value is not properly formatted.", nfe);
- }
- if (connectionLimit < 0) {
- logger.error("Connection limit value cannot be less than zero.");
- throw new ConfigurationException("Connection limit value cannot be less than zero.");
- } else if (connectionLimit > 0){
- infoBuffer = new StringBuilder(128)
- .append(getServiceType())
- .append(" will allow a maximum of ")
- .append(connectionLimitString)
- .append(" connections.");
- logger.info(infoBuffer.toString());
- }
- }
-
- String connectionLimitPerIP = handlerConfiguration.getChild("connectionLimitPerIP").getValue(null);
- if (connectionLimitPerIP != null) {
- try {
- connPerIP = new Integer(connectionLimitPerIP).intValue();
- } catch (NumberFormatException nfe) {
- logger.error("Connection limit per IP value is not properly formatted.", nfe);
- }
- if (connPerIP < 0) {
- logger.error("Connection limit per IP value cannot be less than zero.");
- throw new ConfigurationException("Connection limit value cannot be less than zero.");
- } else if (connPerIP > 0){
- infoBuffer = new StringBuilder(128)
- .append(getServiceType())
- .append(" will allow a maximum of ")
- .append(connPerIP)
- .append(" per IP connections for " +getServiceType());
- logger.info(infoBuffer.toString());
- }
- }
-
-
- Configuration tlsConfig = configuration.getChild("startTLS");
- if (tlsConfig != null) {
- useStartTLS = tlsConfig.getAttributeAsBoolean("enable", false);
-
- if (useStartTLS) {
- keystore = tlsConfig.getChild("keystore").getValue(null);
- if (keystore == null) {
- throw new ConfigurationException("keystore needs to get configured");
- }
- secret = tlsConfig.getChild("secret").getValue("");
- }
- }
-
- String hello = (String) mailetcontext.getAttribute(Constants.HELLO_NAME);
-
- if (configuration.getAttributeAsBoolean("enabled")) {
- // TODO Remove this in next not backwards compatible release!
- if (hello == null) mailetcontext.setAttribute(Constants.HELLO_NAME, helloName);
-
+ super.configure(configuration);
+ if (isEnabled()) {
+ System.out.println("HELLO");
handlerConfiguration = configuration.getChild("handler");
String authRequiredString = handlerConfiguration.getChild("authRequired").getValue("false").trim().toLowerCase();
if (authRequiredString.equals("true")) authRequired = AUTH_REQUIRED;
@@ -396,7 +150,7 @@
String addr = st.nextToken();
networks.add(addr);
}
- authorizedNetworks = new NetMatcher(networks, dns);
+ authorizedNetworks = new NetMatcher(networks, getDNSService());
}
if (authorizedNetworks != null) {
@@ -428,53 +182,18 @@
smtpGreeting = handlerConfiguration.getChild("smtpGreeting").getValue(null);
addressBracketsEnforcement = handlerConfiguration.getChild("addressBracketsEnforcement").getValueAsBoolean(true);
- } else {
- // TODO Remove this in next not backwards compatible release!
- if (hello == null) mailetcontext.setAttribute(Constants.HELLO_NAME, "localhost");
}
-
- this.handlerConfiguration = handlerConfiguration;
}
- private void configureHelloName(Configuration handlerConfiguration) {
- StringBuilder infoBuffer;
- String hostName = null;
- try {
- hostName = dns.getHostName(dns.getLocalHost());
- } catch (UnknownHostException ue) {
- hostName = "localhost";
- }
-
- infoBuffer =
- new StringBuilder(64)
- .append(getServiceType())
- .append(" is running on: ")
- .append(hostName);
- getLogger().info(infoBuffer.toString());
-
- Configuration helloConf = handlerConfiguration.getChild(HELLO_NAME);
-
- if (helloConf != null) {
- boolean autodetect = helloConf.getAttributeAsBoolean("autodetect", true);
- if (autodetect) {
- helloName = hostName;
- } else {
- // Should we use the defaultdomain here ?
- helloName = helloConf.getValue("localhost");
- }
- } else {
- helloName = null;
- }
- infoBuffer =
- new StringBuilder(64)
- .append(getServiceType())
- .append(" handler hello name is: ")
- .append(helloName);
- getLogger().info(infoBuffer.toString());
- }
+
+ /**
+ * Prepare the handlerchain
+ *
+ * @throws Exception
+ */
private void prepareHandlerChain() throws Exception {
- handlerChain = loader.load(SMTPHandlerChain.class);
-
+ handlerChain = getLoader().load(SMTPHandlerChain.class);
+
//set the logger
handlerChain.setLog(new AvalonLogger(getLogger()));
@@ -484,7 +203,16 @@
/**
- * @see org.apache.james.core.AbstractProtocolServer#getDefaultPort()
+ * @see org.apache.james.smtpserver.mina.AbstractAsyncServer#preInit()
+ */
+ protected void preInit() throws Exception {
+ prepareHandlerChain();
+ }
+
+
+
+ /**
+ * @see org.apache.james.smtpserver.mina.AbstractAsyncServer#getDefaultPort()
*/
protected int getDefaultPort() {
return 25;
@@ -507,10 +235,10 @@
* @see org.apache.james.smtpserver.protocol.SMTPConfiguration#getHelloName()
*/
public String getHelloName() {
- if (AsyncSMTPServer.this.helloName == null) {
- return AsyncSMTPServer.this.mailServer.getHelloName();
+ if (AsyncSMTPServer.this.getHelloName() == null) {
+ return AsyncSMTPServer.this.getMailServer().getHelloName();
} else {
- return AsyncSMTPServer.this.helloName;
+ return AsyncSMTPServer.this.getHelloName();
}
}
@@ -561,6 +289,9 @@
return AsyncSMTPServer.this.addressBracketsEnforcement;
}
+ /**
+ * @see org.apache.james.smtpserver.protocol.SMTPConfiguration#isAuthRequired(java.lang.String)
+ */
public boolean isAuthRequired(String remoteIP) {
if (AsyncSMTPServer.this.authRequired == AUTH_ANNOUNCE) return true;
boolean authRequired = AsyncSMTPServer.this.authRequired != AUTH_DISABLED;
@@ -570,51 +301,17 @@
return authRequired;
}
+ /**
+ * @see org.apache.james.smtpserver.protocol.SMTPConfiguration#isStartTLSSupported()
+ */
public boolean isStartTLSSupported() {
- return useStartTLS;
+ return AsyncSMTPServer.this.isStartTLSSupported();
}
//TODO: IF we create here an interface to get DNSServer
// we should access it from the SMTPHandlers
}
-
- /**
- * @see org.apache.avalon.framework.activity.Initializable#initialize()
- */
- public void initialize() throws Exception {
- prepareHandlerChain();
- Log logger = new AvalonLogger(getLogger());
- ProtocolCodecFilter codecFactory = new ProtocolCodecFilter(new TextLineCodecFactory());
- SocketAcceptor acceptor = new NioSocketAcceptor();
- acceptor.setHandler(new SMTPIoHandler(handlerChain, theConfigData,logger,buildSSLContextFactory()));
-
- acceptor.getFilterChain().addLast("protocolCodecFactory", codecFactory);
- acceptor.getFilterChain().addLast("connectionFilter", new ConnectionFilter(logger, connectionLimit, connPerIP));
- acceptor.getFilterChain().addLast("smtpResponseFilter", new SMTPResponseFilter());
- acceptor.getFilterChain().addLast("requestValidationFilter", new RequestValidationFilter(new AvalonLogger(getLogger())));
- acceptor.setBacklog(backlog);
- acceptor.setReuseAddress(true);
- acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, timeout );
- acceptor.bind(new InetSocketAddress(bindTo,port));
- }
-
- private SslContextFactory buildSSLContextFactory() throws Exception{
- SslContextFactory contextFactory = null;
- if (useStartTLS) {
- KeyStoreFactory kfactory = new KeyStoreFactory();
- kfactory.setDataFile(fileSystem.getFile(keystore));
- kfactory.setPassword(secret);
-
- contextFactory = new SslContextFactory();
- contextFactory.setKeyManagerFactoryKeyStore(kfactory.newInstance());
- contextFactory.setKeyManagerFactoryAlgorithm("SunX509");
- contextFactory.setTrustManagerFactory(new BogusTrustManagerFactory());
- contextFactory.setKeyManagerFactoryKeyStorePassword(secret);
- }
-
- return contextFactory;
- }
/**
* (non-Javadoc)
@@ -626,26 +323,33 @@
/**
* (non-Javadoc)
- * @see org.apache.james.smtpserver.protocol.SMTPServerMBean#getPort()
+ * @see org.apache.james.smtpserver.protocol.SMTPServerMBean#getSocketType()
*/
- public int getPort() {
- return port;
+ public String getSocketType() {
+ return "plain";
}
+
/**
- * (non-Javadoc)
- * @see org.apache.james.smtpserver.protocol.SMTPServerMBean#getSocketType()
+ * @see org.apache.james.smtpserver.mina.AbstractAsyncServer#createIoFilterChainBuilder()
*/
- public String getSocketType() {
- return "plain";
+ protected DefaultIoFilterChainBuilder createIoFilterChainBuilder() {
+ DefaultIoFilterChainBuilder builder = super.createIoFilterChainBuilder();
+
+ // response and validation filter to the chain
+ builder.addLast("smtpResponseFilter", new SMTPResponseFilter());
+ builder.addLast("requestValidationFilter", new RequestValidationFilter(new AvalonLogger(getLogger())));
+ return builder;
}
+
+
/**
- * (non-Javadoc)
- * @see org.apache.james.smtpserver.protocol.SMTPServerMBean#isEnabled()
+ * @see org.apache.james.smtpserver.mina.AbstractAsyncServer#createIoHandler()
*/
- public boolean isEnabled() {
- return enabled;
+ protected IoHandler createIoHandler() {
+ Log logger = new AvalonLogger(getLogger());
+ return new SMTPIoHandler(handlerChain, theConfigData,logger,getSslContextFactory());
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org