1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.server.tools;
21
22
23 import java.util.Hashtable;
24
25 import javax.naming.directory.SearchControls;
26 import javax.naming.event.EventContext;
27 import javax.naming.event.NamingExceptionEvent;
28 import javax.naming.ldap.InitialLdapContext;
29 import javax.naming.ldap.LdapContext;
30 import javax.naming.ldap.UnsolicitedNotification;
31 import javax.naming.ldap.UnsolicitedNotificationEvent;
32 import javax.naming.ldap.UnsolicitedNotificationListener;
33
34 import org.apache.commons.cli.CommandLine;
35 import org.apache.commons.cli.Option;
36 import org.apache.commons.cli.Options;
37 import org.apache.directory.daemon.AvailablePortFinder;
38 import org.apache.directory.shared.asn1.codec.DecoderException;
39 import org.apache.directory.shared.ldap.message.extended.GracefulDisconnect;
40 import org.apache.directory.shared.ldap.message.extended.NoticeOfDisconnect;
41
42
43
44
45
46
47
48
49
50
51 public class DisconnectNotificationCommand extends ToolCommand implements UnsolicitedNotificationListener
52 {
53 UnsolicitedNotification notification;
54 boolean canceled = false;
55 private String host = "localhost";
56 private int port = 10389;
57 private String bindDn = "uid=admin,ou=system";
58 private String password = "secret";
59
60
61
62
63
64
65 protected DisconnectNotificationCommand()
66 {
67 super( "notifications" );
68 }
69
70
71 public void notificationReceived( UnsolicitedNotificationEvent evt )
72 {
73 notification = evt.getNotification();
74
75 if ( notification.getID().equals( NoticeOfDisconnect.EXTENSION_OID ) )
76 {
77 System.out.println( "\nRecieved NoticeOfDisconnect: " + NoticeOfDisconnect.EXTENSION_OID );
78 System.out.println( "Expect to loose this connection without further information." );
79 canceled = true;
80 }
81 else if ( notification.getID().equals( GracefulDisconnect.EXTENSION_OID ) )
82 {
83 System.out.println( "Recieved GracefulDisconnect: " + GracefulDisconnect.EXTENSION_OID );
84 GracefulDisconnect gd = null;
85
86 try
87 {
88 gd = new GracefulDisconnect( notification.getEncodedValue() );
89 }
90 catch ( DecoderException de )
91 {
92
93 de.printStackTrace();
94 }
95
96 System.out.println( "LDAP server will shutdown in " + gd.getDelay() + " seconds." );
97 System.out.println( "LDAP server will be back online in " + gd.getTimeOffline() + " minutes." );
98
99 if ( gd.getDelay() > 0 )
100 {
101 Thread t = new Thread( new Counter( gd.getDelay() ) );
102 t.start();
103 }
104 }
105 else
106 {
107 System.out.println( "Unknown event recieved with OID: " + evt.getNotification().getID() );
108 }
109 }
110
111
112 public void namingExceptionThrown( NamingExceptionEvent evt )
113 {
114 canceled = true;
115 System.out.println( "Got an excption event: " + evt.getException().getMessage() );
116 System.out.println( "Process shutting down abruptly." );
117 System.exit( 1 );
118 }
119
120 class Counter implements Runnable
121 {
122 int delay;
123
124
125 Counter( int delay )
126 {
127 this.delay = delay;
128 }
129
130
131 public void run()
132 {
133 System.out.println( "Starting countdown until server shutdown:" );
134 System.out.print( "[" );
135 long delayMillis = delay * 1000 - 1000;
136 long startTime = System.currentTimeMillis();
137 while ( System.currentTimeMillis() - startTime < delayMillis && !canceled )
138 {
139 try
140 {
141 Thread.sleep( 1000 );
142 }
143 catch ( InterruptedException e )
144 {
145 }
146 System.out.print( "." );
147 }
148
149 if ( canceled )
150 {
151 System.out.println( " -- countdown canceled -- " );
152 }
153 else
154 {
155 System.out.println( "]" );
156 System.out.println( "Client shutting down gracefully." );
157 System.exit( 0 );
158 }
159 }
160 }
161
162
163 public void execute( CommandLine cmd ) throws Exception
164 {
165 processOptions( cmd );
166
167 Hashtable env = new Hashtable();
168 env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" );
169 env.put( "java.naming.provider.url", "ldap://" + host + ":" + port );
170 env.put( "java.naming.security.principal", bindDn );
171 env.put( "java.naming.security.credentials", password );
172 env.put( "java.naming.security.authentication", "simple" );
173
174 LdapContext ctx = new InitialLdapContext( env, null );
175 ctx = ctx.newInstance( null );
176 UnsolicitedNotificationListener listener = new DisconnectNotificationCommand();
177 ( ( EventContext ) ctx ).addNamingListener( "", SearchControls.SUBTREE_SCOPE, listener );
178
179 System.out.println( "Listening for notifications." );
180 System.out.println( "Press any key to terminate." );
181 System.in.read();
182 ctx.close();
183 System.out.println( "Process terminated!!!" );
184 }
185
186
187 private void processOptions( CommandLine cmd )
188 {
189 if ( isDebugEnabled() )
190 {
191 System.out.println( "Processing options for disconnect notifications ..." );
192 }
193
194
195
196
197
198 if ( cmd.hasOption( 'p' ) )
199 {
200 String val = cmd.getOptionValue( 'p' );
201 try
202 {
203 port = Integer.parseInt( val );
204 }
205 catch ( NumberFormatException e )
206 {
207 System.err.println( "port value of '" + val + "' is not a number" );
208 System.exit( 1 );
209 }
210
211 if ( port > AvailablePortFinder.MAX_PORT_NUMBER )
212 {
213 System.err.println( "port value of '" + val + "' is larger than max port number: "
214 + AvailablePortFinder.MAX_PORT_NUMBER );
215 System.exit( 1 );
216 }
217 else if ( port < AvailablePortFinder.MIN_PORT_NUMBER )
218 {
219 System.err.println( "port value of '" + val + "' is smaller than the minimum port number: "
220 + AvailablePortFinder.MIN_PORT_NUMBER );
221 System.exit( 1 );
222 }
223
224 if ( isDebugEnabled() )
225 {
226 System.out.println( "port overriden by -p option: " + port );
227 }
228 }
229 else if ( getApacheDS() != null )
230 {
231 port = getApacheDS().getLdapService().getIpPort();
232
233 if ( isDebugEnabled() )
234 {
235 System.out.println( "port overriden by server.xml configuration: " + port );
236 }
237 }
238 else if ( isDebugEnabled() )
239 {
240 System.out.println( "port set to default: " + port );
241 }
242
243
244
245
246
247 if ( cmd.hasOption( 'h' ) )
248 {
249 host = cmd.getOptionValue( 'h' );
250
251 if ( isDebugEnabled() )
252 {
253 System.out.println( "host overriden by -h option: " + host );
254 }
255 }
256 else if ( isDebugEnabled() )
257 {
258 System.out.println( "host set to default: " + host );
259 }
260
261
262
263
264
265 if ( cmd.hasOption( 'w' ) )
266 {
267 password = cmd.getOptionValue( 'w' );
268
269 if ( isDebugEnabled() )
270 {
271 System.out.println( "password overriden by -w option: " + password );
272 }
273 }
274 else if ( isDebugEnabled() )
275 {
276 System.out.println( "password set to default: " + password );
277 }
278
279
280
281
282
283 if ( cmd.hasOption( 'u' ) )
284 {
285 bindDn = cmd.getOptionValue( 'u' );
286
287 if ( isDebugEnabled() )
288 {
289 System.out.println( "binddn overriden by -u option: " + bindDn );
290 }
291 }
292 else if ( isDebugEnabled() )
293 {
294 System.out.println( "binddn set to default: " + bindDn );
295 }
296 }
297
298
299 public Options getOptions()
300 {
301 Options opts = new Options();
302 Option op = new Option( "h", "host", true, "server host: defaults to localhost" );
303 op.setRequired( false );
304 opts.addOption( op );
305 op = new Option( "p", "port", true, "server port: defaults to 10389 or server.xml specified port" );
306 op.setRequired( false );
307 opts.addOption( op );
308 op = new Option( "w", "password", true, "the apacheds administrator's password: defaults to secret" );
309 op.setRequired( false );
310 opts.addOption( op );
311 op = new Option( "u", "binddn", true, "an apacheds user's dn: defaults to " + bindDn );
312 op.setRequired( false );
313 opts.addOption( op );
314 op = new Option( "i", "install-path", true, "path to apacheds installation directory" );
315 op.setRequired( false );
316 opts.addOption( op );
317 return opts;
318 }
319 }