You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2023/06/14 06:59:34 UTC
[james-project] 12/28: JAMES-3906 Add hot reloading/updating of the certificate: new interface with reloadSSLCertificate() method; new abstract class AbstractServerRoutes with implementation for all available/known servers; fix issue with `ManageSieveServerFactory` not being singleton causing issues
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch 3.8.x
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 666e32e275a1c7d80800eb9f48a5c2c0ed2df659
Author: Wojciech Kapcia <wo...@tigase.org>
AuthorDate: Thu May 11 17:35:22 2023 -0400
JAMES-3906 Add hot reloading/updating of the certificate: new interface with reloadSSLCertificate() method; new abstract class AbstractServerRoutes with implementation for all available/known servers; fix issue with `ManageSieveServerFactory` not being singleton causing issues
---
.../james/modules/protocols/IMAPServerModule.java | 4 +++
.../james/modules/protocols/LMTPServerModule.java | 4 +++
.../modules/protocols/ManageSieveServerModule.java | 4 +++
.../james/modules/protocols/POP3ServerModule.java | 4 +++
.../james/modules/protocols/SMTPServerModule.java | 4 +++
.../james/imapserver/webadmin/ImapRoutes.java | 22 ++++++++++++
server/protocols/protocols-library/pom.xml | 4 +++
.../lib/netty/AbstractConfigurableAsyncServer.java | 9 ++++-
.../protocols/lib/netty/AbstractServerFactory.java | 2 ++
.../protocols/lib/netty/CertificateReloadable.java | 6 ++++
.../lib/webadmin/AbstractServerRoutes.java | 42 ++++++++++++++++++++++
.../james/lmtpserver/webadmin/LMTPRoutes.java | 21 +++++++++++
.../webadmin/ManageSieveRoutes.java | 21 +++++++++++
.../james/pop3server/webadmin/POP3Routes.java | 21 +++++++++++
.../james/smtpserver/webadmin/SmtpRoutes.java | 21 +++++++++++
15 files changed, 188 insertions(+), 1 deletion(-)
diff --git a/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/IMAPServerModule.java b/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/IMAPServerModule.java
index 082240b01e..0d84991d97 100644
--- a/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/IMAPServerModule.java
+++ b/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/IMAPServerModule.java
@@ -57,6 +57,7 @@ import org.apache.james.imap.processor.SelectProcessor;
import org.apache.james.imap.processor.base.AbstractProcessor;
import org.apache.james.imap.processor.base.UnknownRequestProcessor;
import org.apache.james.imapserver.netty.IMAPServerFactory;
+import org.apache.james.imapserver.webadmin.ImapRoutes;
import org.apache.james.lifecycle.api.ConfigurationSanitizer;
import org.apache.james.metrics.api.GaugeRegistry;
import org.apache.james.metrics.api.MetricFactory;
@@ -67,6 +68,7 @@ import org.apache.james.utils.GuiceProbe;
import org.apache.james.utils.InitializationOperation;
import org.apache.james.utils.InitilizationOperationBuilder;
import org.apache.james.utils.KeystoreCreator;
+import org.apache.james.webadmin.Routes;
import com.github.fge.lambdas.Throwing;
import com.google.common.collect.ImmutableList;
@@ -99,6 +101,8 @@ public class IMAPServerModule extends AbstractModule {
bind(MailboxTyper.class).to(DefaultMailboxTyper.class).in(Scopes.SINGLETON);
Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(ImapGuiceProbe.class);
+
+ Multibinder.newSetBinder(binder(), Routes.class).addBinding().to(ImapRoutes.class);
}
@Provides
diff --git a/server/container/guice/protocols/lmtp/src/main/java/org/apache/james/modules/protocols/LMTPServerModule.java b/server/container/guice/protocols/lmtp/src/main/java/org/apache/james/modules/protocols/LMTPServerModule.java
index 60ed8c28fd..168d2f7027 100644
--- a/server/container/guice/protocols/lmtp/src/main/java/org/apache/james/modules/protocols/LMTPServerModule.java
+++ b/server/container/guice/protocols/lmtp/src/main/java/org/apache/james/modules/protocols/LMTPServerModule.java
@@ -24,12 +24,14 @@ import org.apache.james.RunArguments;
import org.apache.james.filesystem.api.FileSystem;
import org.apache.james.lifecycle.api.ConfigurationSanitizer;
import org.apache.james.lmtpserver.netty.LMTPServerFactory;
+import org.apache.james.lmtpserver.webadmin.LMTPRoutes;
import org.apache.james.server.core.configuration.ConfigurationProvider;
import org.apache.james.util.LoggingLevel;
import org.apache.james.utils.GuiceProbe;
import org.apache.james.utils.InitializationOperation;
import org.apache.james.utils.InitilizationOperationBuilder;
import org.apache.james.utils.KeystoreCreator;
+import org.apache.james.webadmin.Routes;
import com.google.inject.AbstractModule;
import com.google.inject.Scopes;
@@ -42,6 +44,8 @@ public class LMTPServerModule extends AbstractModule {
bind(LMTPServerFactory.class).in(Scopes.SINGLETON);
Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(LmtpGuiceProbe.class);
+
+ Multibinder.newSetBinder(binder(), Routes.class).addBinding().to(LMTPRoutes.class);
}
@ProvidesIntoSet
diff --git a/server/container/guice/protocols/managedsieve/src/main/java/org/apache/james/modules/protocols/ManageSieveServerModule.java b/server/container/guice/protocols/managedsieve/src/main/java/org/apache/james/modules/protocols/ManageSieveServerModule.java
index 8c983e46da..9ec6101d8e 100644
--- a/server/container/guice/protocols/managedsieve/src/main/java/org/apache/james/modules/protocols/ManageSieveServerModule.java
+++ b/server/container/guice/protocols/managedsieve/src/main/java/org/apache/james/modules/protocols/ManageSieveServerModule.java
@@ -25,12 +25,14 @@ import org.apache.james.lifecycle.api.ConfigurationSanitizer;
import org.apache.james.managesieve.api.commands.CoreCommands;
import org.apache.james.managesieve.core.CoreProcessor;
import org.apache.james.managesieveserver.netty.ManageSieveServerFactory;
+import org.apache.james.managesieveserver.webadmin.ManageSieveRoutes;
import org.apache.james.server.core.configuration.ConfigurationProvider;
import org.apache.james.util.LoggingLevel;
import org.apache.james.utils.GuiceProbe;
import org.apache.james.utils.InitializationOperation;
import org.apache.james.utils.InitilizationOperationBuilder;
import org.apache.james.utils.KeystoreCreator;
+import org.apache.james.webadmin.Routes;
import com.google.inject.AbstractModule;
import com.google.inject.multibindings.Multibinder;
@@ -43,6 +45,8 @@ public class ManageSieveServerModule extends AbstractModule {
install(new SieveModule());
bind(CoreCommands.class).to(CoreProcessor.class);
Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(SieveProbeImpl.class);
+
+ Multibinder.newSetBinder(binder(), Routes.class).addBinding().to(ManageSieveRoutes.class);
}
@ProvidesIntoSet
diff --git a/server/container/guice/protocols/pop/src/main/java/org/apache/james/modules/protocols/POP3ServerModule.java b/server/container/guice/protocols/pop/src/main/java/org/apache/james/modules/protocols/POP3ServerModule.java
index bc00a306da..e22859ff34 100644
--- a/server/container/guice/protocols/pop/src/main/java/org/apache/james/modules/protocols/POP3ServerModule.java
+++ b/server/container/guice/protocols/pop/src/main/java/org/apache/james/modules/protocols/POP3ServerModule.java
@@ -26,11 +26,13 @@ import org.apache.james.lifecycle.api.ConfigurationSanitizer;
import org.apache.james.pop3server.mailbox.DefaultMailboxAdapterFactory;
import org.apache.james.pop3server.mailbox.MailboxAdapterFactory;
import org.apache.james.pop3server.netty.POP3ServerFactory;
+import org.apache.james.pop3server.webadmin.POP3Routes;
import org.apache.james.server.core.configuration.ConfigurationProvider;
import org.apache.james.utils.GuiceProbe;
import org.apache.james.utils.InitializationOperation;
import org.apache.james.utils.InitilizationOperationBuilder;
import org.apache.james.utils.KeystoreCreator;
+import org.apache.james.webadmin.Routes;
import com.google.inject.AbstractModule;
import com.google.inject.Scopes;
@@ -46,6 +48,8 @@ public class POP3ServerModule extends AbstractModule {
bind(MailboxAdapterFactory.class).to(DefaultMailboxAdapterFactory.class);
Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(Pop3GuiceProbe.class);
+
+ Multibinder.newSetBinder(binder(), Routes.class).addBinding().to(POP3Routes.class);
}
@ProvidesIntoSet
diff --git a/server/container/guice/protocols/smtp/src/main/java/org/apache/james/modules/protocols/SMTPServerModule.java b/server/container/guice/protocols/smtp/src/main/java/org/apache/james/modules/protocols/SMTPServerModule.java
index 22b541da5d..8ba9378900 100644
--- a/server/container/guice/protocols/smtp/src/main/java/org/apache/james/modules/protocols/SMTPServerModule.java
+++ b/server/container/guice/protocols/smtp/src/main/java/org/apache/james/modules/protocols/SMTPServerModule.java
@@ -26,10 +26,12 @@ import org.apache.james.lifecycle.api.ConfigurationSanitizer;
import org.apache.james.server.core.configuration.ConfigurationProvider;
import org.apache.james.smtpserver.SendMailHandler;
import org.apache.james.smtpserver.netty.SMTPServerFactory;
+import org.apache.james.smtpserver.webadmin.SmtpRoutes;
import org.apache.james.utils.GuiceProbe;
import org.apache.james.utils.InitializationOperation;
import org.apache.james.utils.InitilizationOperationBuilder;
import org.apache.james.utils.KeystoreCreator;
+import org.apache.james.webadmin.Routes;
import com.google.inject.AbstractModule;
import com.google.inject.Scopes;
@@ -43,6 +45,8 @@ public class SMTPServerModule extends AbstractModule {
bind(SMTPServerFactory.class).in(Scopes.SINGLETON);
Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(SmtpGuiceProbe.class);
+
+ Multibinder.newSetBinder(binder(), Routes.class).addBinding().to(SmtpRoutes.class);
}
@ProvidesIntoSet
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/webadmin/ImapRoutes.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/webadmin/ImapRoutes.java
new file mode 100644
index 0000000000..843106583c
--- /dev/null
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/webadmin/ImapRoutes.java
@@ -0,0 +1,22 @@
+package org.apache.james.imapserver.webadmin;
+
+import javax.inject.Inject;
+
+import org.apache.james.imapserver.netty.IMAPServerFactory;
+import org.apache.james.protocols.lib.webadmin.AbstractServerRoutes;
+
+public class ImapRoutes
+ extends AbstractServerRoutes {
+
+ public static final String BASE_PATH = "/imap";
+
+ @Inject
+ public ImapRoutes(IMAPServerFactory imapServerFactory) {
+ this.serverFactory = imapServerFactory;
+ }
+
+ @Override
+ public String getBasePath() {
+ return BASE_PATH;
+ }
+}
\ No newline at end of file
diff --git a/server/protocols/protocols-library/pom.xml b/server/protocols/protocols-library/pom.xml
index ffda3f0739..c527fe454d 100644
--- a/server/protocols/protocols-library/pom.xml
+++ b/server/protocols/protocols-library/pom.xml
@@ -52,6 +52,10 @@
</exclusion>
</exclusions>
</dependency>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
+ <artifactId>james-server-webadmin-core</artifactId>
+ </dependency>
<dependency>
<groupId>${james.groupId}</groupId>
<artifactId>metrics-api</artifactId>
diff --git a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java
index 76e8152a6b..b6ded174ed 100644
--- a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java
+++ b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java
@@ -61,7 +61,10 @@ import io.netty.util.concurrent.EventExecutorGroup;
/**
* Abstract base class for Servers for all James Servers
*/
-public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServer implements Configurable, ServerMBean {
+public abstract class AbstractConfigurableAsyncServer
+ extends AbstractAsyncServer
+ implements CertificateReloadable, Configurable, ServerMBean {
+
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractConfigurableAsyncServer.class);
/** The default value for the connection backlog. */
@@ -360,6 +363,10 @@ public abstract class AbstractConfigurableAsyncServer extends AbstractAsyncServe
}
}
+ public void reloadSSLCertificate() throws Exception {
+ buildSSLContext();
+ }
+
/**
* Return the default port which will get used for this server if non is
* specify in the configuration
diff --git a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractServerFactory.java b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractServerFactory.java
index bf672d5efa..1a9d3d202f 100644
--- a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractServerFactory.java
+++ b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractServerFactory.java
@@ -23,6 +23,7 @@ import java.util.List;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
+import javax.inject.Singleton;
import org.apache.commons.configuration2.HierarchicalConfiguration;
import org.apache.commons.configuration2.tree.ImmutableNode;
@@ -31,6 +32,7 @@ import org.apache.james.lifecycle.api.Configurable;
/**
* Abstract base class for Factories that need to create {@link AbstractConfigurableAsyncServer}'s via configuration files
*/
+@Singleton
public abstract class AbstractServerFactory implements Configurable {
private List<AbstractConfigurableAsyncServer> servers;
diff --git a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/CertificateReloadable.java b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/CertificateReloadable.java
new file mode 100644
index 0000000000..7ac6f2a44b
--- /dev/null
+++ b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/CertificateReloadable.java
@@ -0,0 +1,6 @@
+package org.apache.james.protocols.lib.netty;
+
+public interface CertificateReloadable {
+
+ void reloadSSLCertificate() throws Exception;
+}
diff --git a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/webadmin/AbstractServerRoutes.java b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/webadmin/AbstractServerRoutes.java
new file mode 100644
index 0000000000..baaa2d4606
--- /dev/null
+++ b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/webadmin/AbstractServerRoutes.java
@@ -0,0 +1,42 @@
+package org.apache.james.protocols.lib.webadmin;
+
+import org.apache.james.protocols.lib.netty.AbstractConfigurableAsyncServer;
+import org.apache.james.protocols.lib.netty.AbstractServerFactory;
+import org.apache.james.webadmin.Routes;
+import org.apache.james.webadmin.utils.ErrorResponder;
+import org.apache.james.webadmin.utils.Responses;
+import org.eclipse.jetty.http.HttpStatus;
+
+import com.google.common.base.Preconditions;
+
+import spark.Service;
+
+public abstract class AbstractServerRoutes
+ implements Routes {
+
+ protected AbstractServerFactory serverFactory;
+
+ @Override
+ public void define(Service service) {
+ service.post(getBasePath(), (request, response) -> {
+ Preconditions.checkArgument(request.queryParams().contains("reload-certificate"),
+ "'reload-certificate' query parameter shall be specified");
+
+ if (serverFactory.getServers() == null
+ || serverFactory.getServers().isEmpty()
+ || serverFactory.getServers().stream().noneMatch(AbstractConfigurableAsyncServer::isEnabled)) {
+ return ErrorResponder.builder()
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .type(ErrorResponder.ErrorType.NOT_FOUND)
+ .message("No servers configured, nothing to reload")
+ .haltError();
+ }
+
+ for (AbstractConfigurableAsyncServer server : serverFactory.getServers()) {
+ server.reloadSSLCertificate();
+ }
+
+ return Responses.returnNoContent(response);
+ });
+ }
+}
\ No newline at end of file
diff --git a/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/webadmin/LMTPRoutes.java b/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/webadmin/LMTPRoutes.java
new file mode 100644
index 0000000000..ac949aad95
--- /dev/null
+++ b/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/webadmin/LMTPRoutes.java
@@ -0,0 +1,21 @@
+package org.apache.james.lmtpserver.webadmin;
+
+import javax.inject.Inject;
+
+import org.apache.james.lmtpserver.netty.LMTPServerFactory;
+import org.apache.james.protocols.lib.webadmin.AbstractServerRoutes;
+
+public class LMTPRoutes extends AbstractServerRoutes {
+
+ public static final String BASE_PATH = "/lmtp";
+
+ @Inject
+ public LMTPRoutes(LMTPServerFactory lmtpServerFactory) {
+ this.serverFactory = lmtpServerFactory;
+ }
+
+ @Override
+ public String getBasePath() {
+ return BASE_PATH;
+ }
+}
\ No newline at end of file
diff --git a/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/webadmin/ManageSieveRoutes.java b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/webadmin/ManageSieveRoutes.java
new file mode 100644
index 0000000000..6aa01b7b27
--- /dev/null
+++ b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/webadmin/ManageSieveRoutes.java
@@ -0,0 +1,21 @@
+package org.apache.james.managesieveserver.webadmin;
+
+import javax.inject.Inject;
+
+import org.apache.james.managesieveserver.netty.ManageSieveServerFactory;
+import org.apache.james.protocols.lib.webadmin.AbstractServerRoutes;
+
+public class ManageSieveRoutes extends AbstractServerRoutes {
+
+ public static final String BASE_PATH = "/sieve";
+
+ @Inject
+ public ManageSieveRoutes(ManageSieveServerFactory manageSieveServerFactory) {
+ this.serverFactory = manageSieveServerFactory;
+ }
+
+ @Override
+ public String getBasePath() {
+ return BASE_PATH;
+ }
+}
\ No newline at end of file
diff --git a/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/webadmin/POP3Routes.java b/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/webadmin/POP3Routes.java
new file mode 100644
index 0000000000..7e41923ea4
--- /dev/null
+++ b/server/protocols/protocols-pop3/src/main/java/org/apache/james/pop3server/webadmin/POP3Routes.java
@@ -0,0 +1,21 @@
+package org.apache.james.pop3server.webadmin;
+
+import javax.inject.Inject;
+
+import org.apache.james.pop3server.netty.POP3ServerFactory;
+import org.apache.james.protocols.lib.webadmin.AbstractServerRoutes;
+
+public class POP3Routes extends AbstractServerRoutes {
+
+ public static final String BASE_PATH = "/pop3";
+
+ @Inject
+ public POP3Routes(POP3ServerFactory pop3ServerFactory) {
+ this.serverFactory = pop3ServerFactory;
+ }
+
+ @Override
+ public String getBasePath() {
+ return BASE_PATH;
+ }
+}
\ No newline at end of file
diff --git a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/webadmin/SmtpRoutes.java b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/webadmin/SmtpRoutes.java
new file mode 100644
index 0000000000..79d409cc86
--- /dev/null
+++ b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/webadmin/SmtpRoutes.java
@@ -0,0 +1,21 @@
+package org.apache.james.smtpserver.webadmin;
+
+import javax.inject.Inject;
+
+import org.apache.james.protocols.lib.webadmin.AbstractServerRoutes;
+import org.apache.james.smtpserver.netty.SMTPServerFactory;
+
+public class SmtpRoutes extends AbstractServerRoutes {
+
+ public static final String BASE_PATH = "/smtp";
+
+ @Inject
+ public SmtpRoutes(SMTPServerFactory imapServerFactory) {
+ this.serverFactory = imapServerFactory;
+ }
+
+ @Override
+ public String getBasePath() {
+ return BASE_PATH;
+ }
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org