Source Code Cross Referenced for ExtendedResolver.java in  » Net » dnsjava » org » xbill » DNS » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Net » dnsjava » org.xbill.DNS 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        // Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)
002:
003:        package org.xbill.DNS;
004:
005:        import java.util.*;
006:        import java.io.*;
007:        import java.net.*;
008:
009:        /**
010:         * An implementation of Resolver that can send queries to multiple servers,
011:         * sending the queries multiple times if necessary.
012:         * @see Resolver
013:         *
014:         * @author Brian Wellington
015:         */
016:
017:        public class ExtendedResolver implements  Resolver {
018:
019:            private static class Resolution implements  ResolverListener {
020:                Resolver[] resolvers;
021:                int[] sent;
022:                Object[] inprogress;
023:                int retries;
024:                int outstanding;
025:                boolean done;
026:                Message query;
027:                Message response;
028:                Throwable thrown;
029:                ResolverListener listener;
030:
031:                public Resolution(ExtendedResolver eres, Message query) {
032:                    List l = eres.resolvers;
033:                    resolvers = (Resolver[]) l.toArray(new Resolver[l.size()]);
034:                    if (eres.loadBalance) {
035:                        int nresolvers = resolvers.length;
036:                        /*
037:                         * Note: this is not synchronized, since the
038:                         * worst thing that can happen is a random
039:                         * ordering, which is ok.
040:                         */
041:                        int start = eres.lbStart++ % nresolvers;
042:                        if (eres.lbStart > nresolvers)
043:                            eres.lbStart %= nresolvers;
044:                        if (start > 0) {
045:                            Resolver[] shuffle = new Resolver[nresolvers];
046:                            for (int i = 0; i < nresolvers; i++) {
047:                                int pos = (i + start) % nresolvers;
048:                                shuffle[i] = resolvers[pos];
049:                            }
050:                            resolvers = shuffle;
051:                        }
052:                    }
053:                    sent = new int[resolvers.length];
054:                    inprogress = new Object[resolvers.length];
055:                    retries = eres.retries;
056:                    this .query = query;
057:                }
058:
059:                /* Asynchronously sends a message. */
060:                public void send(int n) {
061:                    sent[n]++;
062:                    outstanding++;
063:                    try {
064:                        inprogress[n] = resolvers[n].sendAsync(query, this );
065:                    } catch (Throwable t) {
066:                        thrown = t;
067:                        done = true;
068:                        if (listener == null) {
069:                            notifyAll();
070:                            return;
071:                        }
072:                    }
073:                }
074:
075:                /* Start a synchronous resolution */
076:                public Message start() throws IOException {
077:                    try {
078:                        /*
079:                         * First, try sending synchronously.  If this works,
080:                         * we're done.  Otherwise, we'll get an exception
081:                         * and continue.  It would be easier to call send(0),
082:                         * but this avoids a thread creation.  If and when
083:                         * SimpleResolver.sendAsync() can be made to not
084:                         * create a thread, this could be changed.
085:                         */
086:                        sent[0]++;
087:                        outstanding++;
088:                        inprogress[0] = new Object();
089:                        return resolvers[0].send(query);
090:                    } catch (Exception e) {
091:                        /*
092:                         * This will either cause more queries to be sent
093:                         * asynchronously or will set the 'done' flag.
094:                         */
095:                        handleException(inprogress[0], e);
096:                    }
097:                    if (!done) {
098:                        /*
099:                         * Wait for a successful response or for each
100:                         * subresolver to fail.
101:                         */
102:                        synchronized (this ) {
103:                            while (!done) {
104:                                try {
105:                                    wait();
106:                                } catch (InterruptedException e) {
107:                                }
108:                            }
109:                        }
110:                    }
111:                    /* Return the response or throw an exception */
112:                    if (response != null)
113:                        return response;
114:                    else if (thrown instanceof  IOException)
115:                        throw (IOException) thrown;
116:                    else if (thrown instanceof  RuntimeException)
117:                        throw (RuntimeException) thrown;
118:                    else if (thrown instanceof  Error)
119:                        throw (Error) thrown;
120:                    else
121:                        throw new IllegalStateException(
122:                                "ExtendedResolver failure");
123:                }
124:
125:                /* Start an asynchronous resolution */
126:                public void startAsync(ResolverListener listener) {
127:                    this .listener = listener;
128:                    send(0);
129:                }
130:
131:                /*
132:                 * Receive a response.  If the resolution hasn't been completed,
133:                 * either wake up the blocking thread or call the callback.
134:                 */
135:                public void receiveMessage(Object id, Message m) {
136:                    if (Options.check("verbose"))
137:                        System.err.println("ExtendedResolver: "
138:                                + "received message");
139:                    synchronized (this ) {
140:                        if (done)
141:                            return;
142:                        response = m;
143:                        done = true;
144:                        if (listener == null) {
145:                            notifyAll();
146:                            return;
147:                        }
148:                    }
149:                    listener.receiveMessage(this , response);
150:                }
151:
152:                /*
153:                 * Receive an exception.  If the resolution has been completed,
154:                 * do nothing.  Otherwise make progress.
155:                 */
156:                public void handleException(Object id, Exception e) {
157:                    if (Options.check("verbose"))
158:                        System.err.println("ExtendedResolver: got " + e);
159:                    synchronized (this ) {
160:                        outstanding--;
161:                        if (done)
162:                            return;
163:                        int n;
164:                        for (n = 0; n < inprogress.length; n++)
165:                            if (inprogress[n] == id)
166:                                break;
167:                        /* If we don't know what this is, do nothing. */
168:                        if (n == inprogress.length)
169:                            return;
170:                        boolean startnext = false;
171:                        boolean waiting = false;
172:                        /*
173:                         * If this is the first response from server n, 
174:                         * we should start sending queries to server n + 1.
175:                         */
176:                        if (sent[n] == 1 && n < resolvers.length - 1)
177:                            startnext = true;
178:                        if (e instanceof  InterruptedIOException) {
179:                            /* Got a timeout; resend */
180:                            if (sent[n] < retries)
181:                                send(n);
182:                            if (thrown == null)
183:                                thrown = e;
184:                        } else if (e instanceof  SocketException) {
185:                            /*
186:                             * Problem with the socket; don't resend
187:                             * on it
188:                             */
189:                            if (thrown == null
190:                                    || thrown instanceof  InterruptedIOException)
191:                                thrown = e;
192:                        } else {
193:                            /*
194:                             * Problem with the response; don't resend
195:                             * on the same socket.
196:                             */
197:                            thrown = e;
198:                        }
199:                        if (done)
200:                            return;
201:                        if (startnext)
202:                            send(n + 1);
203:                        if (done)
204:                            return;
205:                        if (outstanding == 0) {
206:                            /*
207:                             * If we're done and this is synchronous,
208:                             * wake up the blocking thread.
209:                             */
210:                            done = true;
211:                            if (listener == null) {
212:                                notifyAll();
213:                                return;
214:                            }
215:                        }
216:                        if (!done)
217:                            return;
218:                    }
219:                    /* If we're done and this is asynchronous, call the callback. */
220:                    if (!(thrown instanceof  Exception))
221:                        thrown = new RuntimeException(thrown.getMessage());
222:                    listener.handleException(this , (Exception) thrown);
223:                }
224:            }
225:
226:            private static final int quantum = 5;
227:
228:            private List resolvers;
229:            private boolean loadBalance = false;
230:            private int lbStart = 0;
231:            private int retries = 3;
232:
233:            private void init() {
234:                resolvers = new ArrayList();
235:            }
236:
237:            /**
238:             * Creates a new Extended Resolver.  The default ResolverConfig is used to
239:             * determine the servers for which SimpleResolver contexts should be
240:             * initialized.
241:             * @see SimpleResolver
242:             * @see ResolverConfig
243:             * @exception UnknownHostException Failure occured initializing SimpleResolvers
244:             */
245:            public ExtendedResolver() throws UnknownHostException {
246:                init();
247:                String[] servers = ResolverConfig.getCurrentConfig().servers();
248:                if (servers != null) {
249:                    for (int i = 0; i < servers.length; i++) {
250:                        Resolver r = new SimpleResolver(servers[i]);
251:                        r.setTimeout(quantum);
252:                        resolvers.add(r);
253:                    }
254:                } else
255:                    resolvers.add(new SimpleResolver());
256:            }
257:
258:            /**
259:             * Creates a new Extended Resolver
260:             * @param servers An array of server names for which SimpleResolver
261:             * contexts should be initialized.
262:             * @see SimpleResolver
263:             * @exception UnknownHostException Failure occured initializing SimpleResolvers
264:             */
265:            public ExtendedResolver(String[] servers)
266:                    throws UnknownHostException {
267:                init();
268:                for (int i = 0; i < servers.length; i++) {
269:                    Resolver r = new SimpleResolver(servers[i]);
270:                    r.setTimeout(quantum);
271:                    resolvers.add(r);
272:                }
273:            }
274:
275:            /**
276:             * Creates a new Extended Resolver
277:             * @param res An array of pre-initialized Resolvers is provided.
278:             * @see SimpleResolver
279:             * @exception UnknownHostException Failure occured initializing SimpleResolvers
280:             */
281:            public ExtendedResolver(Resolver[] res) throws UnknownHostException {
282:                init();
283:                for (int i = 0; i < res.length; i++)
284:                    resolvers.add(res[i]);
285:            }
286:
287:            public void setPort(int port) {
288:                for (int i = 0; i < resolvers.size(); i++)
289:                    ((Resolver) resolvers.get(i)).setPort(port);
290:            }
291:
292:            public void setTCP(boolean flag) {
293:                for (int i = 0; i < resolvers.size(); i++)
294:                    ((Resolver) resolvers.get(i)).setTCP(flag);
295:            }
296:
297:            public void setIgnoreTruncation(boolean flag) {
298:                for (int i = 0; i < resolvers.size(); i++)
299:                    ((Resolver) resolvers.get(i)).setIgnoreTruncation(flag);
300:            }
301:
302:            public void setEDNS(int level) {
303:                for (int i = 0; i < resolvers.size(); i++)
304:                    ((Resolver) resolvers.get(i)).setEDNS(level);
305:            }
306:
307:            public void setEDNS(int level, int payloadSize, int flags,
308:                    List options) {
309:                for (int i = 0; i < resolvers.size(); i++)
310:                    ((Resolver) resolvers.get(i)).setEDNS(level, payloadSize,
311:                            flags, options);
312:            }
313:
314:            public void setTSIGKey(TSIG key) {
315:                for (int i = 0; i < resolvers.size(); i++)
316:                    ((Resolver) resolvers.get(i)).setTSIGKey(key);
317:            }
318:
319:            public void setTimeout(int secs, int msecs) {
320:                for (int i = 0; i < resolvers.size(); i++)
321:                    ((Resolver) resolvers.get(i)).setTimeout(secs, msecs);
322:            }
323:
324:            public void setTimeout(int secs) {
325:                setTimeout(secs, 0);
326:            }
327:
328:            /**
329:             * Sends a message and waits for a response.  Multiple servers are queried,
330:             * and queries are sent multiple times until either a successful response
331:             * is received, or it is clear that there is no successful response.
332:             * @param query The query to send.
333:             * @return The response.
334:             * @throws IOException An error occurred while sending or receiving.
335:             */
336:            public Message send(Message query) throws IOException {
337:                Resolution res = new Resolution(this , query);
338:                return res.start();
339:            }
340:
341:            /**
342:             * Asynchronously sends a message to multiple servers, potentially multiple
343:             * times, registering a listener to receive a callback on success or exception.
344:             * Multiple asynchronous lookups can be performed in parallel.  Since the
345:             * callback may be invoked before the function returns, external
346:             * synchronization is necessary.
347:             * @param query The query to send
348:             * @param listener The object containing the callbacks.
349:             * @return An identifier, which is also a parameter in the callback
350:             */
351:            public Object sendAsync(final Message query,
352:                    final ResolverListener listener) {
353:                Resolution res = new Resolution(this , query);
354:                res.startAsync(listener);
355:                return res;
356:            }
357:
358:            /** Returns the nth resolver used by this ExtendedResolver */
359:            public Resolver getResolver(int n) {
360:                if (n < resolvers.size())
361:                    return (Resolver) resolvers.get(n);
362:                return null;
363:            }
364:
365:            /** Returns all resolvers used by this ExtendedResolver */
366:            public Resolver[] getResolvers() {
367:                return (Resolver[]) resolvers.toArray(new Resolver[resolvers
368:                        .size()]);
369:            }
370:
371:            /** Adds a new resolver to be used by this ExtendedResolver */
372:            public void addResolver(Resolver r) {
373:                resolvers.add(r);
374:            }
375:
376:            /** Deletes a resolver used by this ExtendedResolver */
377:            public void deleteResolver(Resolver r) {
378:                resolvers.remove(r);
379:            }
380:
381:            /** Sets whether the servers should be load balanced.
382:             * @param flag If true, servers will be tried in round-robin order.  If false,
383:             * servers will always be queried in the same order.
384:             */
385:            public void setLoadBalance(boolean flag) {
386:                loadBalance = flag;
387:            }
388:
389:            /** Sets the number of retries sent to each server per query */
390:            public void setRetries(int retries) {
391:                this.retries = retries;
392:            }
393:
394:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.