1+ package org .tron .core .config .args ;
2+
3+ import static org .apache .commons .lang3 .StringUtils .isNoneBlank ;
4+
5+ import com .typesafe .config .Config ;
6+ import java .io .File ;
7+ import java .io .IOException ;
8+ import java .net .InetAddress ;
9+ import java .net .InetSocketAddress ;
10+ import java .nio .file .FileSystems ;
11+ import java .nio .file .Path ;
12+ import java .nio .file .StandardWatchEventKinds ;
13+ import java .nio .file .WatchEvent ;
14+ import java .nio .file .WatchKey ;
15+ import java .nio .file .WatchService ;
16+ import java .util .List ;
17+ import lombok .extern .slf4j .Slf4j ;
18+ import org .springframework .stereotype .Component ;
19+ import org .tron .common .parameter .CommonParameter ;
20+ import org .tron .core .Constant ;
21+ import org .tron .core .config .Configuration ;
22+ import org .tron .core .net .TronNetService ;
23+
24+
25+ @ Slf4j (topic = "app" )
26+ @ Component
27+ public class DynamicArgs {
28+ private final CommonParameter parameter = Args .getInstance ();
29+
30+ private volatile boolean shutdown = false ;
31+
32+ public void init () {
33+ if (parameter .isDynamicConfigEnable ()) {
34+ new Thread (this ::start , "DynamicArgs" ).start ();
35+ }
36+ }
37+
38+ public void start () {
39+ WatchService watchService ;
40+ Path path ;
41+ String confFileName ;
42+ try {
43+ logger .info ("Start the dynamic loading configuration service" );
44+ String confFile ;
45+ if (isNoneBlank (parameter .getShellConfFileName ())) {
46+ confFile = parameter .getShellConfFileName ();
47+ } else {
48+ confFile = Constant .TESTNET_CONF ;
49+ //
50+ //logger.warn("Configuration path is required!");
51+ //return;
52+ }
53+
54+ File confDir = new File (confFile );
55+ confFileName = confDir .getName ();
56+ if (confFile .contains (File .separator )) {
57+ path = FileSystems .getDefault ().getPath (confDir .getPath ()).getParent ();
58+ } else {
59+ File directory = new File ("" );
60+ path = FileSystems .getDefault ().getPath (directory .getAbsolutePath ());
61+ }
62+
63+ logger .info ("confDirString = {}" , confDir );
64+ watchService = FileSystems .getDefault ().newWatchService ();
65+ path .register (watchService , StandardWatchEventKinds .ENTRY_MODIFY );
66+ logger .info ("watch path : {}" , path .toString ());
67+ } catch (Exception e ) {
68+ logger .error ("Exception caught when register the watch key" , e .getCause ());
69+ return ;
70+ }
71+
72+ while (!shutdown ) {
73+ try {
74+ WatchKey wk = watchService .take ();
75+ long changeCount = 0 ;
76+ for (WatchEvent <?> event : wk .pollEvents ()) {
77+ final Path changed = (Path )event .context ();
78+ if (changed .endsWith (confFileName )) {
79+ reload ();
80+ logger .info ("Config was modify and we reload it" );
81+ }
82+ changeCount ++;
83+ }
84+ logger .info ("change count : {}" , changeCount );
85+
86+ boolean valid = wk .reset ();
87+ if (!valid ) {
88+ path .register (watchService , StandardWatchEventKinds .ENTRY_MODIFY );
89+ }
90+ } catch (InterruptedException e ) {
91+ logger .warn ("" );
92+ break ;
93+ } catch (IOException e ) {
94+ break ;
95+ }
96+ }
97+ }
98+
99+ public void reload () {
100+ logger .info ("reloading ... " );
101+ Config config = Configuration .getByFileName (parameter .getShellConfFileName (),
102+ Constant .TESTNET_CONF );
103+
104+ updateActiveNodes (config );
105+
106+ updateTrustNodes (config );
107+ }
108+
109+ private void updateActiveNodes (Config config ) {
110+ if (parameter .isWitness () || parameter .isFastForward ()) {
111+ return ;
112+ }
113+
114+ List <InetSocketAddress > lastActiveNodes = parameter .getActiveNodes ();
115+ List <InetSocketAddress > newActiveNodes =
116+ Args .getInetSocketAddress (config , Constant .NODE_ACTIVE );
117+ parameter .setActiveNodes (newActiveNodes );
118+ parameter .getActiveNodes ().forEach (n -> {
119+ logger .info ("active node : {}" , n .toString ());
120+ if (!lastActiveNodes .contains (n )) {
121+ TronNetService .getP2pConfig ().getActiveNodes ().add (n );
122+ if (!TronNetService .getP2pConfig ().getTrustNodes ().contains (n .getAddress ())) {
123+ TronNetService .getP2pConfig ().getTrustNodes ().add (n .getAddress ());
124+ }
125+ }
126+ });
127+
128+ lastActiveNodes .forEach (ln -> {
129+ if (!parameter .getActiveNodes ().contains (ln )) {
130+ TronNetService .getP2pConfig ().getActiveNodes ().remove (ln );
131+ TronNetService .getP2pConfig ().getTrustNodes ().remove (ln .getAddress ());
132+ }
133+ });
134+ }
135+
136+ private void updateTrustNodes (Config config ) {
137+ if (parameter .isWitness () || parameter .isFastForward ()) {
138+ return ;
139+ }
140+
141+ List <InetAddress > lastPassiveNodes = parameter .getPassiveNodes ();
142+ List <InetAddress > newPassiveNodes = Args .getInetAddress (config , Constant .NODE_PASSIVE );
143+ parameter .setPassiveNodes (newPassiveNodes );
144+ parameter .getPassiveNodes ().forEach (n -> {
145+ logger .info ("passive node : {}" , n .toString ());
146+ if (!lastPassiveNodes .contains (n )
147+ || !TronNetService .getP2pConfig ().getTrustNodes ().contains (n )) {
148+ TronNetService .getP2pConfig ().getTrustNodes ().add (n );
149+ }
150+ });
151+
152+ lastPassiveNodes .forEach (ln -> {
153+ if (!parameter .getPassiveNodes ().contains (ln )) {
154+ TronNetService .getP2pConfig ().getTrustNodes ().remove (ln );
155+ }
156+ });
157+ }
158+
159+ public void close () {
160+ logger .info ("Closing watchService ..." );
161+ shutdown = true ;
162+ }
163+ }
0 commit comments