1515 * limitations under the License.
1616 */
1717package org .apache .rocketmq .proxy .service .cert ;
18-
19- import java .io .InputStream ;
20- import java .nio .charset .StandardCharsets ;
21- import java .util .ArrayList ;
22- import java .util .List ;
23- import org .apache .commons .io .IOUtils ;
2418import org .apache .rocketmq .common .constant .LoggerName ;
2519import org .apache .rocketmq .common .utils .StartAndShutdown ;
2620import org .apache .rocketmq .logging .org .slf4j .Logger ;
2721import org .apache .rocketmq .logging .org .slf4j .LoggerFactory ;
2822import org .apache .rocketmq .proxy .config .ConfigurationManager ;
23+ import org .apache .rocketmq .remoting .netty .TlsSystemConfig ;
24+ import org .apache .rocketmq .srvutil .FileWatchService ;
25+ import java .util .ArrayList ;
26+ import java .util .List ;
2927
30- public class TlsCertificateManager implements StartAndShutdown , CertChangeSource . ChangeListener {
28+ public class TlsCertificateManager implements StartAndShutdown {
3129 private static final Logger log = LoggerFactory .getLogger (LoggerName .PROXY_LOGGER_NAME );
3230
33- private final CertChangeSource certChangeSource ;
31+ private final FileWatchService fileWatchService ;
3432 private final List <TlsContextReloadListener > reloadListeners = new ArrayList <>();
3533
36- private boolean certChanged = false ;
37- private boolean keyChanged = false ;
34+ public TlsCertificateManager () {
35+ try {
36+ this .fileWatchService = new FileWatchService (
37+ new String [] {
38+ ConfigurationManager .getProxyConfig ().getTlsCertPath (),
39+ ConfigurationManager .getProxyConfig ().getTlsKeyPath ()
40+ },
41+ new CertKeyFileWatchListener (),
42+ 60 * 60 * 1000 /* 1 hour */
43+ );
44+ } catch (Exception e ) {
45+ log .error ("Failed to initialize TLS certificate watch service" , e );
46+ throw new RuntimeException ("Failed to initialize TLS certificate manager" , e );
47+ }
48+ }
3849
39- public TlsCertificateManager (CertChangeSource source ) {
40- this .certChangeSource = source ;
41- source .setListener (this );
50+ public FileWatchService getFileWatchService () {
51+ return this .fileWatchService ;
4252 }
4353
4454 public void registerReloadListener (TlsContextReloadListener listener ) {
@@ -53,58 +63,59 @@ public void unregisterReloadListener(TlsContextReloadListener listener) {
5363 }
5464 }
5565
66+ public List <TlsContextReloadListener > getReloadListeners () {
67+ return this .reloadListeners ;
68+ }
69+
5670 @ Override
5771 public void start () throws Exception {
58- certChangeSource .start ();
59- log .info ("TLS certificate manager started successfully" );
72+ this .fileWatchService .start ();
73+ log .info ("TLS certificate manager started successfully, start watching: {} {}" ,
74+ ConfigurationManager .getProxyConfig ().getTlsCertPath (),
75+ ConfigurationManager .getProxyConfig ().getTlsKeyPath ()
76+ );
6077 }
6178
6279 @ Override
6380 public void shutdown () throws Exception {
64- certChangeSource .shutdown ();
81+ this . fileWatchService .shutdown ();
6582 log .info ("TLS certificate manager shutdown successfully" );
6683 }
6784
68- @ Override
69- public void onCertChanged (List <CertChangeEvent > events ) {
70- log .info ("cert changed: {}" , events );
71- if (events .size () == 1 && events .get (0 ).getSourceType () == CertChangeEvent .SourceType .FILE ) {
72- CertChangeEvent event = events .get (0 );
73- if (event .getValue () == null ) {
74- log .warn ("cert path is empty, ignore" );
75- return ;
76- }
77- String path = event .getValue ();
78- if (path .equals (ConfigurationManager .getProxyConfig ().getTlsCertPath ())) {
85+ private class CertKeyFileWatchListener implements FileWatchService .Listener {
86+ private boolean certChanged = false ;
87+ private boolean keyChanged = false ;
88+
89+ @ Override
90+ public void onChanged (String path ) {
91+ log .info ("File changed: {}" , path );
92+ if (path .equals (TlsSystemConfig .tlsServerCertPath )) {
7993 certChanged = true ;
80- } else if (path .equals (ConfigurationManager . getProxyConfig (). getTlsKeyPath () )) {
94+ } else if (path .equals (TlsSystemConfig . tlsServerKeyPath )) {
8195 keyChanged = true ;
8296 }
8397
8498 if (certChanged && keyChanged ) {
85- log .info ("The certificate and private key changed, reload the SSLContext from file" );
86- for (TlsContextReloadListener listener : reloadListeners ) {
87- listener .onTlsContextReload (null , null );
88- }
99+ log .info ("The certificate and private key changed, reload the ssl context" );
100+ notifyContextReload ();
89101 certChanged = false ;
90102 keyChanged = false ;
91103 }
92- } else if (events .size () == 2 && events .get (0 ).getSourceType () == CertChangeEvent .SourceType .INLINE ) {
93- if (events .get (0 ).getValue () == null || events .get (1 ).getValue () == null ) {
94- log .warn ("cert or key value is empty, ignore" );
95- return ;
96- }
104+ }
105+
106+ private void notifyContextReload () {
97107 for (TlsContextReloadListener listener : reloadListeners ) {
98- listener .onTlsContextReload (
99- IOUtils .toInputStream (events .get (0 ).getValue (), StandardCharsets .UTF_8 ),
100- IOUtils .toInputStream (events .get (1 ).getValue (), StandardCharsets .UTF_8 )
101- );
108+ try {
109+ listener .onTlsContextReload ();
110+ } catch (Exception e ) {
111+ log .error ("Failed to notify TLS context reload to listener: " + listener , e );
112+ }
102113 }
103114 }
104115 }
105116
106117 // Interface for listeners interested in TLS context reload events
107118 public interface TlsContextReloadListener {
108- void onTlsContextReload (InputStream certInputStream , InputStream keyInputStream );
119+ void onTlsContextReload ();
109120 }
110121}
0 commit comments