1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.forgerock.opendj.examples;
29
30 import java.io.IOException;
31 import java.util.Arrays;
32 import java.util.concurrent.CountDownLatch;
33
34 import org.forgerock.opendj.ldap.Connection;
35 import org.forgerock.opendj.ldap.ErrorResultException;
36 import org.forgerock.opendj.ldap.FutureResult;
37 import org.forgerock.opendj.ldap.LDAPConnectionFactory;
38 import org.forgerock.opendj.ldap.ResultCode;
39 import org.forgerock.opendj.ldap.ResultHandler;
40 import org.forgerock.opendj.ldap.SearchResultHandler;
41 import org.forgerock.opendj.ldap.SearchScope;
42 import org.forgerock.opendj.ldap.requests.BindRequest;
43 import org.forgerock.opendj.ldap.requests.CancelExtendedRequest;
44 import org.forgerock.opendj.ldap.requests.Requests;
45 import org.forgerock.opendj.ldap.requests.SearchRequest;
46 import org.forgerock.opendj.ldap.responses.BindResult;
47 import org.forgerock.opendj.ldap.responses.ExtendedResult;
48 import org.forgerock.opendj.ldap.responses.Result;
49 import org.forgerock.opendj.ldap.responses.SearchResultEntry;
50 import org.forgerock.opendj.ldap.responses.SearchResultReference;
51 import org.forgerock.opendj.ldif.LDIFEntryWriter;
52
53
54
55
56
57
58
59
60
61
62 public final class SearchAsync {
63 private static final class BindResultHandlerImpl implements ResultHandler<BindResult> {
64
65
66
67
68 @Override
69 public void handleErrorResult(final ErrorResultException error) {
70 System.err.println(error.getMessage());
71 resultCode = error.getResult().getResultCode().intValue();
72 COMPLETION_LATCH.countDown();
73 }
74
75
76
77
78 @Override
79 public void handleResult(final BindResult result) {
80
81 final SearchRequest request =
82 Requests.newSearchRequest(baseDN, scope, filter, attributes);
83 final FutureResult<Result> futureResult =
84 connection.searchAsync(request, null, new SearchResultHandlerImpl());
85 requestID = futureResult.getRequestID();
86 }
87
88 }
89
90 private static final class ConnectResultHandlerImpl implements ResultHandler<Connection> {
91
92
93
94
95 @Override
96 public void handleErrorResult(final ErrorResultException error) {
97 System.err.println(error.getMessage());
98 resultCode = error.getResult().getResultCode().intValue();
99 COMPLETION_LATCH.countDown();
100 }
101
102
103
104
105 @Override
106 public void handleResult(final Connection connection) {
107
108 SearchAsync.connection = connection;
109
110 final BindRequest request =
111 Requests.newSimpleBindRequest(userName, password.toCharArray());
112 connection.bindAsync(request, null, new BindResultHandlerImpl());
113 }
114
115 }
116
117 private static final class SearchResultHandlerImpl implements SearchResultHandler {
118
119
120
121
122 @Override
123 public synchronized boolean handleEntry(final SearchResultEntry entry) {
124 try {
125 if (entryCount < 10) {
126 WRITER.writeComment("Search result entry: " + entry.getName().toString());
127 WRITER.writeEntry(entry);
128 ++entryCount;
129 } else {
130 CancelExtendedRequest request = Requests.newCancelExtendedRequest(requestID);
131 connection.extendedRequestAsync(request, null, new CancelResultHandlerImpl());
132 return false;
133 }
134 } catch (final IOException e) {
135 System.err.println(e.getMessage());
136 resultCode = ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue();
137 COMPLETION_LATCH.countDown();
138 return false;
139 }
140 return true;
141 }
142
143
144
145
146 @Override
147 public void handleErrorResult(final ErrorResultException error) {
148 System.err.println(error.getMessage());
149 resultCode = error.getResult().getResultCode().intValue();
150 COMPLETION_LATCH.countDown();
151 }
152
153
154
155
156 @Override
157 public synchronized boolean handleReference(final SearchResultReference reference) {
158 try {
159 WRITER.writeComment("Search result reference: " + reference.getURIs().toString());
160 } catch (final IOException e) {
161 System.err.println(e.getMessage());
162 resultCode = ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue();
163 COMPLETION_LATCH.countDown();
164 return false;
165 }
166 return true;
167 }
168
169
170
171
172 @Override
173 public void handleResult(final Result result) {
174 resultCode = result.getResultCode().intValue();
175 COMPLETION_LATCH.countDown();
176 }
177
178 }
179
180 private static final CountDownLatch COMPLETION_LATCH = new CountDownLatch(1);
181 private static final CountDownLatch CANCEL_LATCH = new CountDownLatch(1);
182 private static final LDIFEntryWriter WRITER = new LDIFEntryWriter(System.out);
183 private static String userName;
184 private static String password;
185 private static String baseDN;
186 private static SearchScope scope;
187 private static String filter;
188 private static String[] attributes;
189 private static Connection connection = null;
190 private static int resultCode = 0;
191
192 static int requestID;
193 static int entryCount = 0;
194
195 private static final class CancelResultHandlerImpl implements ResultHandler<ExtendedResult> {
196
197 @Override
198 public void handleErrorResult(final ErrorResultException error) {
199 System.err.println("Cancel request failed with result code: "
200 + error.getResult().getResultCode().intValue());
201 CANCEL_LATCH.countDown();
202 }
203
204 @Override
205 public void handleResult(final ExtendedResult result) {
206 System.err.println("Cancel request succeeded");
207 CANCEL_LATCH.countDown();
208 }
209
210 }
211
212
213
214
215
216
217
218
219
220 public static void main(final String[] args) {
221 if (args.length < 7) {
222 System.err.println("Usage: host port username password baseDN scope "
223 + "filter [attribute ...]");
224 System.exit(1);
225 }
226
227
228 final String hostName = args[0];
229 final int port = Integer.parseInt(args[1]);
230 userName = args[2];
231 password = args[3];
232 baseDN = args[4];
233 final String scopeString = args[5];
234 filter = args[6];
235 if (args.length > 7) {
236 attributes = Arrays.copyOfRange(args, 7, args.length);
237 } else {
238 attributes = new String[0];
239 }
240
241 if (scopeString.equalsIgnoreCase("base")) {
242 scope = SearchScope.BASE_OBJECT;
243 } else if (scopeString.equalsIgnoreCase("one")) {
244 scope = SearchScope.SINGLE_LEVEL;
245 } else if (scopeString.equalsIgnoreCase("sub")) {
246 scope = SearchScope.WHOLE_SUBTREE;
247 } else if (scopeString.equalsIgnoreCase("subordinates")) {
248 scope = SearchScope.SUBORDINATES;
249 } else {
250 System.err.println("Unknown scope: " + scopeString);
251 System.exit(ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue());
252 return;
253 }
254
255
256 final LDAPConnectionFactory factory = new LDAPConnectionFactory(hostName, port);
257 factory.getConnectionAsync(new ConnectResultHandlerImpl());
258
259
260 try {
261 COMPLETION_LATCH.await();
262 } catch (final InterruptedException e) {
263 System.err.println(e.getMessage());
264 System.exit(ResultCode.CLIENT_SIDE_USER_CANCELLED.intValue());
265 return;
266 }
267
268 try {
269 WRITER.flush();
270 } catch (final IOException e) {
271 System.err.println(e.getMessage());
272 System.exit(ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue());
273 return;
274 }
275
276
277 try {
278 CANCEL_LATCH.await();
279 } catch (final InterruptedException e) {
280 System.err.println(e.getMessage());
281 System.exit(ResultCode.CLIENT_SIDE_USER_CANCELLED.intValue());
282 return;
283 }
284
285 if (connection != null) {
286 connection.close();
287 }
288
289 System.exit(resultCode);
290 }
291
292 private SearchAsync() {
293
294 }
295 }