001 /**************************************************************** 002 * Licensed to the Apache Software Foundation (ASF) under one * 003 * or more contributor license agreements. See the NOTICE file * 004 * distributed with this work for additional information * 005 * regarding copyright ownership. The ASF licenses this file * 006 * to you under the Apache License, Version 2.0 (the * 007 * "License"); you may not use this file except in compliance * 008 * with the License. You may obtain a copy of the License at * 009 * * 010 * http://www.apache.org/licenses/LICENSE-2.0 * 011 * * 012 * Unless required by applicable law or agreed to in writing, * 013 * software distributed under the License is distributed on an * 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * 015 * KIND, either express or implied. See the License for the * 016 * specific language governing permissions and limitations * 017 * under the License. * 018 ****************************************************************/ 019 020 package org.apache.james.jspf.impl; 021 022 import java.util.List; 023 024 import org.apache.james.jspf.core.DNSRequest; 025 import org.apache.james.jspf.core.exceptions.TimeoutException; 026 import org.apache.james.jspf.executor.DNSAsynchLookupService; 027 import org.apache.james.jspf.executor.IResponse; 028 import org.apache.james.jspf.executor.IResponseQueue; 029 import org.xbill.DNS.DClass; 030 import org.xbill.DNS.Message; 031 import org.xbill.DNS.Name; 032 import org.xbill.DNS.Record; 033 import org.xbill.DNS.Resolver; 034 import org.xbill.DNS.TextParseException; 035 import org.xbill.DNS.Type; 036 037 import uk.nominet.dnsjnio.ExtendedNonblockingResolver; 038 import uk.nominet.dnsjnio.LookupAsynch; 039 040 public class DNSJnioAsynchService implements DNSAsynchLookupService { 041 042 private ExtendedNonblockingResolver resolver; 043 044 public DNSJnioAsynchService(ExtendedNonblockingResolver resolver) { 045 this.resolver = resolver; 046 LookupAsynch.setDefaultResolver(resolver); 047 } 048 049 /** 050 * Set the timeout for the resolvers 051 * @param timeout 052 */ 053 public synchronized void setTimeout(int timeout) { 054 Resolver[] res = resolver.getResolvers(); 055 for (int i = 0; i < res.length; i++) { 056 res[i].setTimeout(timeout); 057 } 058 } 059 060 /** 061 * @see org.apache.james.jspf.executor.DNSAsynchLookupService#getRecordsAsynch(org.apache.james.jspf.core.DNSRequest, int, org.apache.james.jspf.executor.IResponseQueue) 062 */ 063 public void getRecordsAsynch(DNSRequest request, int id, 064 IResponseQueue responsePool) { 065 066 Message message; 067 try { 068 message = makeQuery(request, id); 069 LookupAsynch la = new LookupAsynch(message.getQuestion().getName(), message.getQuestion().getType()); 070 la.runAsynch(new Runnable() { 071 072 private IResponseQueue responsePool; 073 private Integer id; 074 private LookupAsynch lookup; 075 076 public void run() { 077 responsePool.insertResponse(new IResponse() { 078 079 public Exception getException() { 080 if (lookup.getResult() == LookupAsynch.TRY_AGAIN) { 081 return new TimeoutException(lookup.getErrorString()); 082 } else { 083 return null; 084 } 085 } 086 087 public Object getId() { 088 return id; 089 } 090 091 public List<String> getValue() { 092 return (DNSServiceXBillImpl.convertRecordsToList(lookup.getAnswers())); 093 } 094 095 }); 096 } 097 098 public Runnable setResponsePool(LookupAsynch la, IResponseQueue responsePool, 099 Integer integer) { 100 this.lookup = la; 101 this.responsePool = responsePool; 102 this.id = integer; 103 return this; 104 } 105 106 }.setResponsePool(la, responsePool, new Integer(id))); 107 // this.resolver.sendAsync(message, new Integer(id), new ResponseQueueAdaptor(responsePool)); 108 } catch (TextParseException e) { 109 // TODO Auto-generated catch block 110 e.printStackTrace(); 111 } 112 } 113 114 private Message makeQuery(DNSRequest request, int id) throws TextParseException { 115 Name name = Name.fromString(request.getHostname(), Name.root); 116 117 int type; 118 switch (request.getRecordType()) { 119 case DNSRequest.A: type = Type.A; break; 120 case DNSRequest.AAAA: type = Type.AAAA; break; 121 case DNSRequest.MX: type = Type.MX; break; 122 case DNSRequest.PTR: type = Type.PTR; break; 123 case DNSRequest.SPF: type = Type.SPF; break; 124 case DNSRequest.TXT: type = Type.TXT; break; 125 default: 126 throw new UnsupportedOperationException("Unknown query type: "+request.getRecordType()); 127 } 128 129 Record question = Record.newRecord(name, type, DClass.ANY); 130 Message query = Message.newQuery(question); 131 query.getHeader().setID(id); 132 return query; 133 } 134 }