Author: btellier
Date: Thu Dec 17 14:53:00 2015
New Revision: 1720566
URL: http://svn.apache.org/viewvc?rev=1720566&view=rev
Log:
JAMES-1618 Write a ManageSieve server
Added:
james/project/trunk/server/protocols/protocols-managesieve/
james/project/trunk/server/protocols/protocols-managesieve/pom.xml
james/project/trunk/server/protocols/protocols-managesieve/src/
james/project/trunk/server/protocols/protocols-managesieve/src/main/
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ChannelManageSieveResponseWriter.java
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveChannelUpstreamHandler.java
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServer.java
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServerFactory.java
Modified:
james/project/trunk/server/pom.xml
Modified: james/project/trunk/server/pom.xml
URL:
http://svn.apache.org/viewvc/james/project/trunk/server/pom.xml?rev=1720566&r1=1720565&r2=1720566&view=diff
==============================================================================
--- james/project/trunk/server/pom.xml (original)
+++ james/project/trunk/server/pom.xml Thu Dec 17 14:53:00 2015
@@ -94,6 +94,7 @@
<module>protocols/jmap-integration-testing</module>
<module>protocols/protocols-library</module>
<module>protocols/protocols-lmtp</module>
+ <module>protocols/protocols-managesieve</module>
<module>protocols/protocols-pop3</module>
<module>protocols/protocols-smtp</module>
Added: james/project/trunk/server/protocols/protocols-managesieve/pom.xml
URL:
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/protocols-managesieve/pom.xml?rev=1720566&view=auto
==============================================================================
--- james/project/trunk/server/protocols/protocols-managesieve/pom.xml (added)
+++ james/project/trunk/server/protocols/protocols-managesieve/pom.xml Thu Dec
17 14:53:00 2015
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>james-server</artifactId>
+ <groupId>org.apache.james</groupId>
+ <version>3.0.0-beta5-SNAPSHOT</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>james-server-protocols-managesieve</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.james</groupId>
+ <artifactId>james-server-protocols-library</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.james</groupId>
+ <artifactId>james-server-filesystem-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.james.protocols</groupId>
+ <artifactId>protocols-managesieve</artifactId>
+ <version>${protocols.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.james.protocols</groupId>
+ <artifactId>protocols-netty</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-configuration</groupId>
+ <artifactId>commons-configuration</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-annotation_1.1_spec</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.inject</groupId>
+ <artifactId>javax.inject</artifactId>
+ </dependency>
+ </dependencies>
+
+
+</project>
\ No newline at end of file
Added:
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ChannelManageSieveResponseWriter.java
URL:
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ChannelManageSieveResponseWriter.java?rev=1720566&view=auto
==============================================================================
---
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ChannelManageSieveResponseWriter.java
(added)
+++
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ChannelManageSieveResponseWriter.java
Thu Dec 17 14:53:00 2015
@@ -0,0 +1,43 @@
+/****************************************************************
+ * 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.managesieveserver.netty;
+
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.handler.stream.ChunkedStream;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+
+public class ChannelManageSieveResponseWriter {
+ private final Channel channel;
+
+ public ChannelManageSieveResponseWriter(Channel channel) {
+ this.channel = channel;
+ }
+
+ public void write(String response) throws IOException {
+ if (channel.isConnected()) {
+ InputStream in = new
ByteArrayInputStream(response.getBytes(StandardCharsets.UTF_8));
+ channel.write(new ChunkedStream(in));
+ }
+ }
+}
Added:
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveChannelUpstreamHandler.java
URL:
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveChannelUpstreamHandler.java?rev=1720566&view=auto
==============================================================================
---
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveChannelUpstreamHandler.java
(added)
+++
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveChannelUpstreamHandler.java
Thu Dec 17 14:53:00 2015
@@ -0,0 +1,102 @@
+/****************************************************************
+ * 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.managesieveserver.netty;
+
+import org.apache.james.managesieve.api.Session;
+import org.apache.james.managesieve.transcode.ManageSieveProcessor;
+import org.apache.james.managesieve.util.SettableSession;
+import org.apache.james.protocols.api.logger.ProtocolLoggerAdapter;
+import org.apache.james.protocols.api.logger.ProtocolSessionLogger;
+import org.apache.james.protocols.lib.Slf4jLoggerAdapter;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelFutureListener;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ChannelLocal;
+import org.jboss.netty.channel.ChannelStateEvent;
+import org.jboss.netty.channel.ExceptionEvent;
+import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
+import org.jboss.netty.handler.codec.frame.TooLongFrameException;
+import org.slf4j.Logger;
+
+import java.net.InetSocketAddress;
+
+public class ManageSieveChannelUpstreamHandler extends
SimpleChannelUpstreamHandler {
+
+ private final Logger logger;
+ private final ChannelLocal<Session> attributes;
+ private final ManageSieveProcessor manageSieveProcessor;
+
+ public ManageSieveChannelUpstreamHandler(ManageSieveProcessor
manageSieveProcessor, Logger logger) {
+ this.logger = logger;
+ this.attributes = new ChannelLocal<Session>();
+ this.manageSieveProcessor = manageSieveProcessor;
+ }
+
+ @Override
+ public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
throws Exception {
+ String request = (String) e.getMessage();
+ Session manageSieveSession = attributes.get(ctx.getChannel());
+ String responseString =
manageSieveProcessor.handleRequest(manageSieveSession, request);
+
((ChannelManageSieveResponseWriter)ctx.getAttachment()).write(responseString);
+ }
+
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
throws Exception {
+ getLogger(ctx.getChannel()).warn("Error while processing imap request:
" + e.getCause().getClass().getName() + " - " + e.getCause().getMessage());
+ getLogger(ctx.getChannel()).debug("Error while processing imap
request", e.getCause());
+
+ if (e.getCause() instanceof TooLongFrameException) {
+ // Max line length exceeded
+ //
+ // See also JAMES-1190
+ ((ChannelManageSieveResponseWriter)ctx.getAttachment()).write("NO
Maximum command line length exceeded");
+ } else {
+ // logout on error not sure if that is the best way to handle it
+ attributes.remove(ctx.getChannel());
+
+ // Make sure we close the channel after all the buffers were
flushed out
+ Channel channel = ctx.getChannel();
+ if (channel.isConnected()) {
+
channel.write(ChannelBuffers.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
+ }
+ }
+ }
+
+ @Override
+ public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent
e) throws Exception {
+ attributes.set(ctx.getChannel(), new SettableSession());
+ ctx.setAttachment(new
ChannelManageSieveResponseWriter(ctx.getChannel()));
+ super.channelBound(ctx, e);
+ }
+
+ @Override
+ public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
throws Exception {
+ InetSocketAddress address = (InetSocketAddress)
ctx.getChannel().getRemoteAddress();
+ getLogger(ctx.getChannel()).info("Connection closed for " +
address.getAddress().getHostAddress());
+ attributes.remove(ctx.getChannel());
+ super.channelClosed(ctx, e);
+ }
+
+ private Logger getLogger(Channel channel) {
+ return new Slf4jLoggerAdapter(new ProtocolSessionLogger("" +
channel.getId(), new ProtocolLoggerAdapter(logger)));
+ }
+}
Added:
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServer.java
URL:
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServer.java?rev=1720566&view=auto
==============================================================================
---
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServer.java
(added)
+++
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServer.java
Thu Dec 17 14:53:00 2015
@@ -0,0 +1,131 @@
+/****************************************************************
+ * 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.managesieveserver.netty;
+
+import org.apache.james.managesieve.transcode.ManageSieveProcessor;
+import org.apache.james.protocols.api.Encryption;
+import org.apache.james.protocols.lib.netty.AbstractConfigurableAsyncServer;
+import org.apache.james.protocols.netty.ChannelGroupHandler;
+import org.apache.james.protocols.netty.ConnectionLimitUpstreamHandler;
+import org.apache.james.protocols.netty.ConnectionPerIpLimitUpstreamHandler;
+import org.jboss.netty.channel.ChannelPipeline;
+import org.jboss.netty.channel.ChannelPipelineFactory;
+import org.jboss.netty.channel.ChannelUpstreamHandler;
+import org.jboss.netty.channel.group.ChannelGroup;
+import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
+import org.jboss.netty.handler.codec.frame.Delimiters;
+import org.jboss.netty.handler.codec.string.StringDecoder;
+import org.jboss.netty.handler.codec.string.StringEncoder;
+import org.jboss.netty.handler.execution.ExecutionHandler;
+import org.jboss.netty.handler.ssl.SslHandler;
+import org.jboss.netty.handler.stream.ChunkedWriteHandler;
+import org.jboss.netty.util.CharsetUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.net.ssl.SSLEngine;
+
+import static org.jboss.netty.channel.Channels.pipeline;
+
+public class ManageSieveServer extends AbstractConfigurableAsyncServer {
+
+ private static final Logger LOGGER =
LoggerFactory.getLogger(ManageSieveServer.class);
+
+ final static String SSL_HANDLER = "sslHandler";
+ final static String FRAMER = "framer";
+ final static String CORE_HANDLER = "coreHandler";
+ final static String GROUP_HANDLER = "groupHandler";
+ final static String CONNECTION_LIMIT_HANDLER = "connectionLimitHandler";
+ final static String CONNECTION_LIMIT_PER_IP_HANDLER =
"connectionPerIpLimitHandler";
+ final static String CONNECTION_COUNT_HANDLER = "connectionCountHandler";
+ final static String CHUNK_WRITE_HANDLER = "chunkWriteHandler";
+ final static String EXECUTION_HANDLER = "executionHandler";
+
+
+ private int maxLineLength;
+ private ManageSieveProcessor manageSieveProcessor;
+
+ public ManageSieveServer(int maxLineLength, ManageSieveProcessor
manageSieveProcessor) {
+ this.maxLineLength = maxLineLength;
+ this.manageSieveProcessor = manageSieveProcessor;
+ }
+
+ @Override
+ protected int getDefaultPort() {
+ return 4190;
+ }
+
+ @Override
+ protected String getDefaultJMXName() {
+ return "managesieveserver";
+ }
+
+ @Override
+ protected ChannelUpstreamHandler createCoreHandler() {
+ return new ManageSieveChannelUpstreamHandler(manageSieveProcessor,
LOGGER);
+ }
+
+ @Override
+ protected ChannelPipelineFactory createPipelineFactory(final ChannelGroup
group) {
+
+ return new ChannelPipelineFactory() {
+
+ private final ChannelGroupHandler groupHandler = new
ChannelGroupHandler(group);
+
+ public ChannelPipeline getPipeline() throws Exception {
+ ChannelPipeline pipeline = pipeline();
+ Encryption secure = getEncryption();
+ if (secure != null && !secure.isStartTLS()) {
+ // We need to set clientMode to false.
+ // See https://issues.apache.org/jira/browse/JAMES-1025
+ SSLEngine engine = secure.getContext().createSSLEngine();
+ engine.setUseClientMode(false);
+ pipeline.addFirst(SSL_HANDLER, new SslHandler(engine));
+
+ }
+ pipeline.addLast(GROUP_HANDLER, groupHandler);
+ pipeline.addLast(CONNECTION_LIMIT_HANDLER, new
ConnectionLimitUpstreamHandler(ManageSieveServer.this.connectionLimit));
+ pipeline.addLast(CONNECTION_LIMIT_PER_IP_HANDLER, new
ConnectionPerIpLimitUpstreamHandler(ManageSieveServer.this.connPerIP));
+ // Add the text line decoder which limit the max line length,
+ // don't strip the delimiter and use CRLF as delimiter
+ // Use a SwitchableDelimiterBasedFrameDecoder, see JAMES-1436
+ pipeline.addLast(FRAMER, new
DelimiterBasedFrameDecoder(maxLineLength, false, Delimiters.lineDelimiter()));
+ pipeline.addLast(CONNECTION_COUNT_HANDLER,
getConnectionCountHandler());
+ pipeline.addLast(CHUNK_WRITE_HANDLER, new
ChunkedWriteHandler());
+
+ ExecutionHandler ehandler = getExecutionHandler();
+ if (ehandler != null) {
+ pipeline.addLast(EXECUTION_HANDLER, ehandler);
+
+ }
+ pipeline.addLast("stringDecoder", new
StringDecoder(CharsetUtil.UTF_8));
+ pipeline.addLast(CORE_HANDLER, createCoreHandler());
+ pipeline.addLast("stringEncoder", new
StringEncoder(CharsetUtil.UTF_8));
+ return pipeline;
+ }
+
+ };
+ }
+
+ @Override
+ public String getServiceType() {
+ return "Manage Sieve Service";
+ }
+}
Added:
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServerFactory.java
URL:
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServerFactory.java?rev=1720566&view=auto
==============================================================================
---
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServerFactory.java
(added)
+++
james/project/trunk/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServerFactory.java
Thu Dec 17 14:53:00 2015
@@ -0,0 +1,76 @@
+/****************************************************************
+ * 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.managesieveserver.netty;
+
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.james.filesystem.api.FileSystem;
+import org.apache.james.managesieve.transcode.ManageSieveProcessor;
+import org.apache.james.protocols.lib.netty.AbstractConfigurableAsyncServer;
+import org.apache.james.protocols.lib.netty.AbstractServerFactory;
+import org.apache.james.sieverepository.api.SieveRepository;
+import org.apache.james.user.api.UsersRepository;
+import org.slf4j.Logger;
+
+import javax.inject.Inject;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ManageSieveServerFactory extends AbstractServerFactory {
+
+ private SieveRepository sieveRepository;
+ private UsersRepository usersRepository;
+ private FileSystem fileSystem;
+ private ManageSieveProcessor manageSieveProcessor;
+
+ public ManageSieveServerFactory() {
+ this.manageSieveProcessor = new ManageSieveProcessor();
+ }
+
+ @Inject
+ public void setSieveRepository(SieveRepository sieveRepository) {
+ this.sieveRepository = sieveRepository;
+ }
+
+ @Inject
+ public void setUsersRepository(UsersRepository usersRepository) {
+ this.usersRepository = usersRepository;
+ }
+
+ @Inject
+ public void setFileSystem(FileSystem fileSystem) {
+ this.fileSystem = fileSystem;
+ }
+
+ @Override
+ protected List<AbstractConfigurableAsyncServer> createServers(Logger log,
HierarchicalConfiguration config) throws Exception {
+ List<AbstractConfigurableAsyncServer> servers = new
ArrayList<AbstractConfigurableAsyncServer>();
+ List<HierarchicalConfiguration> configs =
config.configurationsAt("managesieveserver");
+
+ for (HierarchicalConfiguration serverConfig: configs) {
+ ManageSieveServer server = new ManageSieveServer(8000,
manageSieveProcessor);
+ server.setLog(log);
+ server.setFileSystem(fileSystem);
+ server.configure(serverConfig);
+ servers.add(server);
+ }
+
+ return servers;
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]