You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by er...@apache.org on 2005/10/28 23:37:43 UTC
svn commit: r329308 - in
/directory/protocol-providers/dns/trunk/src/java/org/apache/dns: ./
messages/ service/ store/ store/operations/
Author: erodriguez
Date: Fri Oct 28 14:37:33 2005
New Revision: 329308
URL: http://svn.apache.org/viewcvs?rev=329308&view=rev
Log:
Added multi-zone support to dns-protocol:
o Updates to the record store to support switching strategies based on configuration.
o Catalog for resolving zones to domain components.
o Multi-base search strategy.
o Single-base search strategy.
Added:
directory/protocol-providers/dns/trunk/src/java/org/apache/dns/DnsServer.java (with props)
directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/DnsCatalog.java (with props)
directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/MultiBaseSearch.java (with props)
directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/SearchStrategy.java (with props)
directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/SingleBaseSearch.java (with props)
directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/operations/GetFlatRecord.java
- copied, changed from r328198, directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/operations/GetRecord.java
directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/operations/GetRecords.java (with props)
Removed:
directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/operations/GetRecord.java
Modified:
directory/protocol-providers/dns/trunk/src/java/org/apache/dns/DnsConfiguration.java
directory/protocol-providers/dns/trunk/src/java/org/apache/dns/messages/ResourceRecords.java
directory/protocol-providers/dns/trunk/src/java/org/apache/dns/service/DnsContext.java
directory/protocol-providers/dns/trunk/src/java/org/apache/dns/service/GetResourceRecords.java
directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/JndiRecordStoreImpl.java
directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/RecordStore.java
Modified: directory/protocol-providers/dns/trunk/src/java/org/apache/dns/DnsConfiguration.java
URL: http://svn.apache.org/viewcvs/directory/protocol-providers/dns/trunk/src/java/org/apache/dns/DnsConfiguration.java?rev=329308&r1=329307&r2=329308&view=diff
==============================================================================
--- directory/protocol-providers/dns/trunk/src/java/org/apache/dns/DnsConfiguration.java (original)
+++ directory/protocol-providers/dns/trunk/src/java/org/apache/dns/DnsConfiguration.java Fri Oct 28 14:37:33 2005
@@ -21,35 +21,30 @@
import java.util.Map;
import org.apache.ldap.server.DirectoryService;
-import org.apache.ldap.server.configuration.Configuration;
import org.apache.ldap.server.configuration.ConfigurationException;
+import org.apache.protocol.common.LoadStrategy;
+import org.apache.protocol.common.ServiceConfiguration;
-public class DnsConfiguration extends Configuration
+public class DnsConfiguration extends ServiceConfiguration
{
- /** the prop key const for the port */
- public static final String DNS_PORT_KEY = "dns.port";
-
- /** the prop key const for dns.buffer.size */
- public static final String DNS_BUFFER_SIZE_KEY = "dns.buffer.size";
-
/** the default port */
- private static final String DNS_DEFAULT_PORT = "53";
+ private static final String DEFAULT_IP_PORT = "53";
- private static final String SERVICE_PID = "service.pid";
- private static final String PID = "org.apache.dns";
- private static final String name = "Apache DNS Service";
+ /** the default pid */
+ private static final String DEFAULT_PID = "org.apache.dns";
- /** the default dns buffer size */
- private static final int DNS_DEFAULT_BUFFER_SIZE = 1024;
+ /** the default name */
+ private static final String DEFAULT_NAME = "Apache DNS Service";
- private Map configuration = new HashMap();
+ /** the default prefix */
+ private static final String DEFAULT_PREFIX = "dns.";
/**
* Creates a new instance with default settings.
*/
public DnsConfiguration()
{
- this( getDefaultConfig() );
+ this( getDefaultConfig(), LoadStrategy.LDAP );
}
/**
@@ -58,26 +53,31 @@
*/
public DnsConfiguration( String instanceId )
{
- this( getDefaultConfig() );
+ this( getDefaultConfig(), LoadStrategy.LDAP );
setInstanceId( instanceId );
}
public DnsConfiguration( Map properties )
{
+ this( properties, LoadStrategy.LDAP );
+ }
+
+ public DnsConfiguration( Map properties, int strategy )
+ {
if ( properties == null )
{
configuration = getDefaultConfig();
}
else
{
- configuration.putAll( properties );
+ loadProperties( DEFAULT_PREFIX, properties, strategy );
}
int port = getPort();
if ( port < 1 || port > 0xFFFF )
{
- throw new ConfigurationException( "Invalid value: " + DNS_PORT_KEY + "=" + port );
+ throw new ConfigurationException( "Invalid value: " + IP_PORT_KEY + "=" + port );
}
}
@@ -85,8 +85,8 @@
{
Map defaults = new HashMap();
- defaults.put( SERVICE_PID, PID );
- defaults.put( DNS_PORT_KEY, DNS_DEFAULT_PORT );
+ defaults.put( SERVICE_PID, DEFAULT_PID );
+ defaults.put( IP_PORT_KEY, DEFAULT_IP_PORT );
return defaults;
}
@@ -95,7 +95,7 @@
{
int port = getPort();
- if ( port == Integer.parseInt( (String) config.get( DNS_PORT_KEY ) ) )
+ if ( port == Integer.parseInt( (String) config.get( IP_PORT_KEY ) ) )
{
return false;
}
@@ -105,35 +105,30 @@
public String getName()
{
- return name;
+ return DEFAULT_NAME;
}
public int getPort()
{
- String key = DNS_PORT_KEY;
+ String key = IP_PORT_KEY;
if ( configuration.containsKey( key ) )
{
return Integer.parseInt( get( key ) );
}
- return Integer.parseInt( DNS_DEFAULT_PORT );
+ return Integer.parseInt( DEFAULT_IP_PORT );
}
public int getBufferSize()
{
- String key = DNS_BUFFER_SIZE_KEY;
+ String key = BUFFER_SIZE_KEY;
if ( configuration.containsKey( key ) )
{
return Integer.parseInt( get( key ) );
}
- return DNS_DEFAULT_BUFFER_SIZE;
- }
-
- private String get( String key )
- {
- return (String) configuration.get( key );
+ return DEFAULT_BUFFER_SIZE;
}
}
Added: directory/protocol-providers/dns/trunk/src/java/org/apache/dns/DnsServer.java
URL: http://svn.apache.org/viewcvs/directory/protocol-providers/dns/trunk/src/java/org/apache/dns/DnsServer.java?rev=329308&view=auto
==============================================================================
--- directory/protocol-providers/dns/trunk/src/java/org/apache/dns/DnsServer.java (added)
+++ directory/protocol-providers/dns/trunk/src/java/org/apache/dns/DnsServer.java Fri Oct 28 14:37:33 2005
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.dns;
+
+import java.io.IOException;
+import java.util.Dictionary;
+
+import org.apache.dns.protocol.DnsProtocolProvider;
+import org.apache.dns.store.RecordStore;
+import org.apache.mina.common.TransportType;
+import org.apache.mina.protocol.ProtocolProvider;
+import org.apache.mina.registry.Service;
+import org.apache.mina.registry.ServiceRegistry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DnsServer
+{
+ /** the log for this class */
+ private static final Logger log = LoggerFactory.getLogger( DnsServer.class );
+
+ private DnsConfiguration config;
+ private ServiceRegistry registry;
+ private RecordStore store;
+
+ private ProtocolProvider provider;
+ private Service tcpService;
+ private Service udpService;
+
+ public DnsServer( DnsConfiguration config, ServiceRegistry registry, RecordStore store )
+ {
+ this.config = config;
+ this.registry = registry;
+ this.store = store;
+
+ String name = config.getName();
+ int port = config.getPort();
+
+ try
+ {
+ provider = new DnsProtocolProvider( config, this.store );
+
+ udpService = new Service( name, TransportType.DATAGRAM, port );
+ tcpService = new Service( name, TransportType.SOCKET, port );
+
+ registry.bind( udpService, provider );
+ registry.bind( tcpService, provider );
+
+ log.debug( name + " listening on port " + port );
+ }
+ catch ( IOException ioe )
+ {
+ log.error( ioe.getMessage(), ioe );
+ }
+ }
+
+ public boolean isDifferent( Dictionary newConfig )
+ {
+ return config.isDifferent( newConfig );
+ }
+
+ public void destroy()
+ {
+ registry.unbind( udpService );
+ registry.unbind( tcpService );
+
+ registry = null;
+ provider = null;
+ udpService = null;
+ tcpService = null;
+
+ log.debug( config.getName() + " has stopped listening on port " + config.getPort() );
+ }
+}
Propchange: directory/protocol-providers/dns/trunk/src/java/org/apache/dns/DnsServer.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: directory/protocol-providers/dns/trunk/src/java/org/apache/dns/messages/ResourceRecords.java
URL: http://svn.apache.org/viewcvs/directory/protocol-providers/dns/trunk/src/java/org/apache/dns/messages/ResourceRecords.java?rev=329308&r1=329307&r2=329308&view=diff
==============================================================================
--- directory/protocol-providers/dns/trunk/src/java/org/apache/dns/messages/ResourceRecords.java (original)
+++ directory/protocol-providers/dns/trunk/src/java/org/apache/dns/messages/ResourceRecords.java Fri Oct 28 14:37:33 2005
@@ -18,6 +18,7 @@
package org.apache.dns.messages;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@@ -38,6 +39,11 @@
public void add( ResourceRecord record )
{
resourceRecords.add( record );
+ }
+
+ public void addAll( Collection records )
+ {
+ resourceRecords.addAll( records );
}
public int size()
Modified: directory/protocol-providers/dns/trunk/src/java/org/apache/dns/service/DnsContext.java
URL: http://svn.apache.org/viewcvs/directory/protocol-providers/dns/trunk/src/java/org/apache/dns/service/DnsContext.java?rev=329308&r1=329307&r2=329308&view=diff
==============================================================================
--- directory/protocol-providers/dns/trunk/src/java/org/apache/dns/service/DnsContext.java (original)
+++ directory/protocol-providers/dns/trunk/src/java/org/apache/dns/service/DnsContext.java Fri Oct 28 14:37:33 2005
@@ -16,6 +16,9 @@
*/
package org.apache.dns.service;
+import java.util.Collection;
+
+import org.apache.dns.DnsConfiguration;
import org.apache.dns.messages.DnsMessage;
import org.apache.dns.messages.ResourceRecord;
import org.apache.dns.messages.ResourceRecords;
@@ -44,6 +47,14 @@
public void addResourceRecord( ResourceRecord resourceRecord )
{
this.records.add( resourceRecord );
+ }
+
+ /**
+ * @param resourceRecords The resourceRecords to add.
+ */
+ public void addResourceRecords( Collection resourceRecords )
+ {
+ this.records.addAll( resourceRecords );
}
/**
Modified: directory/protocol-providers/dns/trunk/src/java/org/apache/dns/service/GetResourceRecords.java
URL: http://svn.apache.org/viewcvs/directory/protocol-providers/dns/trunk/src/java/org/apache/dns/service/GetResourceRecords.java?rev=329308&r1=329307&r2=329308&view=diff
==============================================================================
--- directory/protocol-providers/dns/trunk/src/java/org/apache/dns/service/GetResourceRecords.java (original)
+++ directory/protocol-providers/dns/trunk/src/java/org/apache/dns/service/GetResourceRecords.java Fri Oct 28 14:37:33 2005
@@ -17,11 +17,11 @@
package org.apache.dns.service;
import java.util.Iterator;
+import java.util.Set;
import org.apache.dns.DnsException;
import org.apache.dns.messages.QuestionRecord;
import org.apache.dns.messages.QuestionRecords;
-import org.apache.dns.messages.ResourceRecord;
import org.apache.dns.messages.ResponseCode;
import org.apache.dns.store.RecordStore;
import org.apache.protocol.common.chain.Context;
@@ -40,30 +40,30 @@
while ( it.hasNext() )
{
- dnsContext.addResourceRecord( getEntry( store, (QuestionRecord) it.next() ) );
+ dnsContext.addResourceRecords( getEntry( store, (QuestionRecord) it.next() ) );
}
return CONTINUE_CHAIN;
}
- public ResourceRecord getEntry( RecordStore store, QuestionRecord question ) throws Exception
+ public Set getEntry( RecordStore store, QuestionRecord question ) throws Exception
{
- ResourceRecord record = null;
+ Set records = null;
try
{
- record = store.getRecord( question );
+ records = store.getRecords( question );
}
catch ( Exception e )
{
throw new DnsException( ResponseCode.SERVER_FAILURE );
}
- if ( record == null )
+ if ( records == null || records.isEmpty() )
{
throw new DnsException( ResponseCode.NAME_ERROR );
}
- return record;
+ return records;
}
}
Added: directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/DnsCatalog.java
URL: http://svn.apache.org/viewcvs/directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/DnsCatalog.java?rev=329308&view=auto
==============================================================================
--- directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/DnsCatalog.java (added)
+++ directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/DnsCatalog.java Fri Oct 28 14:37:33 2005
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.dns.store;
+
+import java.util.Map;
+
+import org.apache.protocol.common.catalog.Catalog;
+
+/**
+ * A catalog for mapping DNS zones to search base DN's.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+class DnsCatalog implements Catalog
+{
+ private Map map;
+
+ public DnsCatalog( Map map )
+ {
+ this.map = map;
+ }
+
+ public String getBaseDn( String name )
+ {
+ if ( name.endsWith( "." ) )
+ {
+ int last = name.lastIndexOf( "." );
+ name = name.substring( 0, last );
+ }
+
+ while ( !name.equals( "" ) && name != null )
+ {
+ String candidate = (String) map.get( name );
+ if ( candidate != null )
+ {
+ return candidate;
+ }
+
+ int period = name.indexOf( "." );
+
+ if ( period > -1 )
+ {
+ name = name.substring( period + 1 );
+ }
+ else
+ {
+ return "";
+ }
+ }
+
+ return "";
+ }
+}
Propchange: directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/DnsCatalog.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/JndiRecordStoreImpl.java
URL: http://svn.apache.org/viewcvs/directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/JndiRecordStoreImpl.java?rev=329308&r1=329307&r2=329308&view=diff
==============================================================================
--- directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/JndiRecordStoreImpl.java (original)
+++ directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/JndiRecordStoreImpl.java Fri Oct 28 14:37:33 2005
@@ -16,49 +16,52 @@
*/
package org.apache.dns.store;
-import javax.naming.Name;
-import javax.naming.ldap.LdapContext;
+import java.util.Set;
+import javax.naming.spi.InitialContextFactory;
+
+import org.apache.dns.DnsConfiguration;
import org.apache.dns.messages.QuestionRecord;
-import org.apache.dns.messages.ResourceRecord;
-import org.apache.dns.store.operations.GetRecord;
-import org.apache.protocol.common.store.ContextOperation;
/**
- * A simple implementation of the RecordStore interface using a JNDI-based store.
+ * A JNDI-backed implementation of the RecordStore interface. This RecordStore uses
+ * the Strategy pattern to either serve records based on a single base DN or to lookup
+ * catalog mappings from directory configuration.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev$, $Date$
*/
public class JndiRecordStoreImpl implements RecordStore
{
- /** a handle on the provider context */
- private LdapContext ctx;
-
- /** the search searchBase relative to the DN of the context supplied */
- private Name searchBase;
+ /** a handle on the configuration */
+ private DnsConfiguration config;
+ /** a handle on the provider factory */
+ private InitialContextFactory factory;
+ /** a handle on the searchh strategy */
+ private SearchStrategy strategy;
- /**
- * Creates the action to be used against the embedded ApacheDS DIT. Note
- * the searchBase is a relative name to the context and not a DN.
- *
- * @param ctx the JNDI context to the store
- * @param searchBase the name relative to the context to use as the search base
- */
- public JndiRecordStoreImpl( LdapContext ctx, Name searchBase )
+ public JndiRecordStoreImpl( DnsConfiguration config, InitialContextFactory factory )
{
- this.ctx = ctx;
+ this.config = config;
+ this.factory = factory;
- this.searchBase = searchBase;
+ strategy = getSearchStrategy();
}
- public ResourceRecord getRecord( QuestionRecord question ) throws Exception
+ public Set getRecords( QuestionRecord question ) throws Exception
{
- return (ResourceRecord) execute( new GetRecord( question ) );
+ return strategy.getRecords( question );
}
- private Object execute( ContextOperation operation ) throws Exception
+ private SearchStrategy getSearchStrategy()
{
- return operation.execute( ctx, searchBase );
+ if ( config.getCatalogBaseDn() != null )
+ {
+ // build catalog from factory
+ return new MultiBaseSearch( config, factory );
+ }
+
+ // use config for catalog baseDN
+ return new SingleBaseSearch( config, factory );
}
}
Added: directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/MultiBaseSearch.java
URL: http://svn.apache.org/viewcvs/directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/MultiBaseSearch.java?rev=329308&view=auto
==============================================================================
--- directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/MultiBaseSearch.java (added)
+++ directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/MultiBaseSearch.java Fri Oct 28 14:37:33 2005
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.dns.store;
+
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+import javax.naming.spi.InitialContextFactory;
+
+import org.apache.dns.DnsConfiguration;
+import org.apache.dns.messages.QuestionRecord;
+import org.apache.dns.store.operations.GetRecords;
+import org.apache.ldap.server.configuration.ConfigurationException;
+import org.apache.protocol.common.catalog.Catalog;
+import org.apache.protocol.common.catalog.GetCatalog;
+import org.apache.protocol.common.store.ContextOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A JNDI-backed search strategy implementation. This search strategy builds a catalog
+ * from directory configuration to determine where zones are to search for
+ * resource records.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class MultiBaseSearch implements SearchStrategy
+{
+ /** the log for this class */
+ private static final Logger log = LoggerFactory.getLogger( MultiBaseSearch.class );
+
+ private InitialContextFactory factory;
+ private Hashtable env;
+
+ private Catalog catalog;
+
+ MultiBaseSearch( DnsConfiguration config, InitialContextFactory factory )
+ {
+ this.factory = factory;
+
+ env = new Hashtable( config.toJndiEnvironment() );
+ env.put( Context.INITIAL_CONTEXT_FACTORY, config.getInitialContextFactory() );
+ env.put( Context.PROVIDER_URL, config.getCatalogBaseDn() );
+
+ try
+ {
+ DirContext ctx = (DirContext) factory.getInitialContext( env );
+ catalog = new DnsCatalog( (Map) execute( ctx, new GetCatalog() ) );
+ }
+ catch ( Exception e )
+ {
+ log.error( e.getMessage(), e );
+ String message = "Failed to get catalog context " + (String) env.get( Context.PROVIDER_URL );
+ throw new ConfigurationException( message );
+ }
+ }
+
+ public Set getRecords( QuestionRecord question ) throws Exception
+ {
+ env.put( Context.PROVIDER_URL, catalog.getBaseDn( question.getDomainName() ) );
+
+ try
+ {
+ DirContext ctx = (DirContext) factory.getInitialContext( env );
+ return (Set) execute( ctx, new GetRecords( question ) );
+ }
+ catch ( NamingException ne )
+ {
+ log.error( ne.getMessage(), ne );
+ String message = "Failed to get initial context " + (String) env.get( Context.PROVIDER_URL );
+ throw new ConfigurationException( message );
+ }
+ }
+
+ private Object execute( DirContext ctx, ContextOperation operation ) throws Exception
+ {
+ return operation.execute( ctx, null );
+ }
+}
Propchange: directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/MultiBaseSearch.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/RecordStore.java
URL: http://svn.apache.org/viewcvs/directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/RecordStore.java?rev=329308&r1=329307&r2=329308&view=diff
==============================================================================
--- directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/RecordStore.java (original)
+++ directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/RecordStore.java Fri Oct 28 14:37:33 2005
@@ -16,14 +16,17 @@
*/
package org.apache.dns.store;
+import java.util.Set;
+
import org.apache.dns.messages.QuestionRecord;
-import org.apache.dns.messages.ResourceRecord;
/**
+ * The store interface used by the DNS protocol to lookup resource records.
+ *
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$, $Date$
+ * @version $Rev: 329063 $, $Date$
*/
public interface RecordStore
{
- public ResourceRecord getRecord( QuestionRecord question ) throws Exception;
+ public Set getRecords( QuestionRecord question ) throws Exception;
}
Added: directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/SearchStrategy.java
URL: http://svn.apache.org/viewcvs/directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/SearchStrategy.java?rev=329308&view=auto
==============================================================================
--- directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/SearchStrategy.java (added)
+++ directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/SearchStrategy.java Fri Oct 28 14:37:33 2005
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.dns.store;
+
+import java.util.Set;
+
+import org.apache.dns.messages.QuestionRecord;
+
+/**
+ * Interface for search strategies. The DNS protocol may search a single
+ * base DN for resource records or use a catalog to lookup resource records
+ * in multiple zones.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+interface SearchStrategy
+{
+ Set getRecords( QuestionRecord question ) throws Exception;
+}
Propchange: directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/SearchStrategy.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/SingleBaseSearch.java
URL: http://svn.apache.org/viewcvs/directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/SingleBaseSearch.java?rev=329308&view=auto
==============================================================================
--- directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/SingleBaseSearch.java (added)
+++ directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/SingleBaseSearch.java Fri Oct 28 14:37:33 2005
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.dns.store;
+
+import java.util.Hashtable;
+import java.util.Set;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+import javax.naming.spi.InitialContextFactory;
+
+import org.apache.dns.DnsConfiguration;
+import org.apache.dns.messages.QuestionRecord;
+import org.apache.dns.store.operations.GetRecords;
+import org.apache.ldap.server.configuration.ConfigurationException;
+import org.apache.protocol.common.store.ContextOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A JNDI-backed search strategy implementation. This search strategy searches a
+ * single base DN for resource records.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class SingleBaseSearch implements SearchStrategy
+{
+ /** the log for this class */
+ private static final Logger log = LoggerFactory.getLogger( SingleBaseSearch.class );
+
+ private DirContext ctx;
+
+ SingleBaseSearch( DnsConfiguration config, InitialContextFactory factory )
+ {
+ Hashtable env = new Hashtable( config.toJndiEnvironment() );
+ env.put( Context.INITIAL_CONTEXT_FACTORY, config.getInitialContextFactory() );
+ env.put( Context.PROVIDER_URL, config.getEntryBaseDn() );
+
+ try
+ {
+ ctx = (DirContext) factory.getInitialContext( env );
+ }
+ catch ( NamingException ne )
+ {
+ log.error( ne.getMessage(), ne );
+ String message = "Failed to get initial context " + (String) env.get( Context.PROVIDER_URL );
+ throw new ConfigurationException( message );
+ }
+ }
+
+ public Set getRecords( QuestionRecord question ) throws Exception
+ {
+ return (Set) execute( new GetRecords( question ) );
+ }
+
+ private Object execute( ContextOperation operation ) throws Exception
+ {
+ return operation.execute( ctx, null );
+ }
+}
Propchange: directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/SingleBaseSearch.java
------------------------------------------------------------------------------
svn:eol-style = native
Copied: directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/operations/GetFlatRecord.java (from r328198, directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/operations/GetRecord.java)
URL: http://svn.apache.org/viewcvs/directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/operations/GetFlatRecord.java?p2=directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/operations/GetFlatRecord.java&p1=directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/operations/GetRecord.java&r1=328198&r2=329308&rev=329308&view=diff
==============================================================================
--- directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/operations/GetRecord.java (original)
+++ directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/operations/GetFlatRecord.java Fri Oct 28 14:37:33 2005
@@ -35,12 +35,12 @@
import org.apache.protocol.common.store.ContextOperation;
/**
- * Encapsulates the action of looking up a Resource Record from an embedded JNDI provider.
+ * A JNDI context operation for looking up a Resource Record with flat attributes.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev$, $Date$
*/
-public class GetRecord implements ContextOperation
+public class GetFlatRecord implements ContextOperation
{
/** The name of the question to get. */
private final QuestionRecord question;
@@ -48,7 +48,7 @@
/**
* Creates the action to be used against the embedded JNDI provider.
*/
- public GetRecord( QuestionRecord question )
+ public GetFlatRecord( QuestionRecord question )
{
this.question = question;
}
@@ -64,7 +64,7 @@
return null;
}
- Attributes matchAttrs = new BasicAttributes( false ); // case-sensitive
+ Attributes matchAttrs = new BasicAttributes( true );
matchAttrs.put( new BasicAttribute( DnsAttribute.NAME, question.getDomainName() ) );
matchAttrs.put( new BasicAttribute( DnsAttribute.TYPE, question.getRecordType().getCode() ) );
Added: directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/operations/GetRecords.java
URL: http://svn.apache.org/viewcvs/directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/operations/GetRecords.java?rev=329308&view=auto
==============================================================================
--- directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/operations/GetRecords.java (added)
+++ directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/operations/GetRecords.java Fri Oct 28 14:37:33 2005
@@ -0,0 +1,307 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.dns.store.operations;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.naming.CompoundName;
+import javax.naming.Name;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+
+import org.apache.dns.messages.QuestionRecord;
+import org.apache.dns.messages.RecordClass;
+import org.apache.dns.messages.RecordType;
+import org.apache.dns.messages.ResourceRecord;
+import org.apache.dns.messages.ResourceRecordModifier;
+import org.apache.dns.store.DnsAttribute;
+import org.apache.protocol.common.store.ContextOperation;
+
+/**
+ * A JNDI context operation for looking up Resource Records from an embedded JNDI provider.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class GetRecords implements ContextOperation
+{
+ /** The name of the question to get. */
+ private final QuestionRecord question;
+
+ /**
+ * Creates the action to be used against the embedded JNDI provider.
+ */
+ public GetRecords( QuestionRecord question )
+ {
+ this.question = question;
+ }
+
+ /**
+ * Mappings of type to objectClass.
+ */
+ private static final Map TYPE_TO_OBJECTCLASS;
+
+ static
+ {
+ Map typeToObjectClass = new HashMap();
+ typeToObjectClass.put( RecordType.SOA, "apacheDnsStartOfAuthorityRecord" );
+ typeToObjectClass.put( RecordType.A, "apacheDnsAddressRecord" );
+ typeToObjectClass.put( RecordType.NS, "apacheDnsNameServerRecord" );
+ typeToObjectClass.put( RecordType.CNAME, "apacheDnsCanonicalNameRecord" );
+ typeToObjectClass.put( RecordType.PTR, "apacheDnsPointerRecord" );
+ typeToObjectClass.put( RecordType.MX, "apacheDnsMailExchangeRecord" );
+ typeToObjectClass.put( RecordType.SRV, "apacheDnsServiceRecord" );
+ typeToObjectClass.put( RecordType.TXT, "apacheDnsTextRecord" );
+
+ TYPE_TO_OBJECTCLASS = Collections.unmodifiableMap( typeToObjectClass );
+ }
+
+ /**
+ * Mappings of type to objectClass.
+ */
+ private static final Map OBJECTCLASS_TO_TYPE;
+
+ static
+ {
+ Map objectClassToType = new HashMap();
+ objectClassToType.put( "apacheDnsStartOfAuthorityRecord", RecordType.SOA );
+ objectClassToType.put( "apacheDnsAddressRecord", RecordType.A );
+ objectClassToType.put( "apacheDnsNameServerRecord", RecordType.NS );
+ objectClassToType.put( "apacheDnsCanonicalNameRecord", RecordType.CNAME );
+ objectClassToType.put( "apacheDnsPointerRecord", RecordType.PTR );
+ objectClassToType.put( "apacheDnsMailExchangeRecord", RecordType.MX );
+ objectClassToType.put( "apacheDnsServiceRecord", RecordType.SRV );
+ objectClassToType.put( "apacheDnsTextRecord", RecordType.TXT );
+ objectClassToType.put( "apacheDnsReferralNameServer", RecordType.NS );
+ objectClassToType.put( "apacheDnsReferralAddress", RecordType.A );
+
+ OBJECTCLASS_TO_TYPE = Collections.unmodifiableMap( objectClassToType );
+ }
+
+ /**
+ * Note that the base is a relative path from the exiting context.
+ * It is not a DN.
+ */
+ public Object execute( DirContext ctx, Name base ) throws Exception
+ {
+ if ( question == null )
+ {
+ return null;
+ }
+
+ String name = question.getDomainName();
+ RecordType type = question.getRecordType();
+
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope( SearchControls.SUBTREE_SCOPE );
+
+ String filter = "(objectClass=" + (String) TYPE_TO_OBJECTCLASS.get( type ) + ")";
+
+ NamingEnumeration list = ctx.search( transformDomainName( name ), filter, controls );
+
+ Set set = new HashSet();
+
+ while ( list.hasMore() )
+ {
+ SearchResult result = (SearchResult) list.next();
+ Name relative = getRelativeName( ctx.getNameInNamespace(), result.getName() );
+
+ set.add( getRecord( result.getAttributes(), relative ) );
+ }
+
+ return set;
+ }
+
+ /**
+ * Marshals a RecordStoreEntry from an Attributes object.
+ *
+ * @param attrs the attributes of the DNS question
+ * @return the entry for the question
+ * @throws NamingException if there are any access problems
+ */
+ private ResourceRecord getRecord( Attributes attrs, Name relative ) throws NamingException
+ {
+ String SOA_MINIMUM = "86400";
+ String SOA_CLASS = "IN";
+
+ ResourceRecordModifier modifier = new ResourceRecordModifier();
+
+ Attribute attr;
+
+ // if no name, transform rdn
+ attr = attrs.get( DnsAttribute.NAME );
+
+ if ( attr != null )
+ {
+ modifier.setDnsName( (String) attr.get() );
+ }
+ else
+ {
+ relative = getDomainComponents( relative );
+
+ String dnsName;
+ dnsName = transformDistinguishedName( relative.toString() );
+ modifier.setDnsName( dnsName );
+ }
+
+ // type is implicit in objectclass
+ attr = attrs.get( DnsAttribute.TYPE );
+
+ if ( attr != null )
+ {
+ modifier.setDnsType( RecordType.getTypeByName( (String) attr.get() ) );
+ }
+ else
+ {
+ modifier.setDnsType( getType( attrs.get( "objectclass" ) ) );
+ }
+
+ // class defaults to SOA CLASS
+ String dnsClass = ( attr = attrs.get( DnsAttribute.CLASS ) ) != null ? (String) attr.get() : SOA_CLASS;
+ modifier.setDnsClass( RecordClass.getTypeByName( dnsClass ) );
+
+ // ttl defaults to SOA MINIMUM
+ String dnsTtl = ( attr = attrs.get( DnsAttribute.TTL ) ) != null ? (String) attr.get() : SOA_MINIMUM;
+ modifier.setDnsTtl( Integer.parseInt( dnsTtl ) );
+
+ NamingEnumeration ids = attrs.getIDs();
+
+ while ( ids.hasMore() )
+ {
+ String id = (String) ids.next();
+ modifier.put( id, (String) attrs.get( id ).get() );
+ }
+
+ return modifier.getEntry();
+ }
+
+ /**
+ * Uses the algorithm in <a href="http://www.faqs.org/rfcs/rfc2247.html">RFC 2247</a>
+ * to transform any Internet domain name into a distinguished name.
+ *
+ * @param domainName the domain name
+ * @return the distinguished name
+ */
+ String transformDomainName( String domainName )
+ {
+ if ( domainName == null || domainName.length() == 0 )
+ {
+ return "";
+ }
+
+ StringBuffer buf = new StringBuffer( domainName.length() + 16 );
+
+ buf.append( "dc=" );
+ buf.append( domainName.replaceAll( "\\.", ",dc=" ) );
+
+ return buf.toString();
+ }
+
+ /**
+ * Uses the algorithm in <a href="http://www.faqs.org/rfcs/rfc2247.html">RFC 2247</a>
+ * to transform a distinguished name into an Internet domain name.
+ *
+ * @param distinguishedName the distinguished name
+ * @return the domain name
+ */
+ String transformDistinguishedName( String distinguishedName )
+ {
+ if ( distinguishedName == null || distinguishedName.length() == 0 )
+ {
+ return "";
+ }
+
+ String domainName = distinguishedName.replaceFirst( "dc=", "" );
+ domainName = domainName.replaceAll( ",dc=", "." );
+
+ return domainName;
+ }
+
+ private RecordType getType( Attribute objectClass ) throws NamingException
+ {
+ NamingEnumeration list = objectClass.getAll();
+
+ while ( list.hasMore() )
+ {
+ String value = (String) list.next();
+
+ if ( !value.equals( "apacheDnsAbstractRecord" ) )
+ {
+ RecordType type = (RecordType) OBJECTCLASS_TO_TYPE.get( value );
+
+ if ( type == null )
+ {
+ throw new RuntimeException( "Record type to objectClass mapping has not been set." );
+ }
+
+ return type;
+ }
+ }
+
+ throw new NamingException( "ResourceRecord requires STRUCTURAL objectClass" );
+ }
+
+ private Name getRelativeName( String nameInNamespace, String baseDn ) throws NamingException
+ {
+ Properties props = new Properties();
+ props.setProperty( "jndi.syntax.direction", "right_to_left" );
+ props.setProperty( "jndi.syntax.separator", "," );
+ props.setProperty( "jndi.syntax.ignorecase", "true" );
+ props.setProperty( "jndi.syntax.trimblanks", "true" );
+
+ Name searchBaseDn = null;
+
+ Name ctxRoot = new CompoundName( nameInNamespace, props );
+ searchBaseDn = new CompoundName( baseDn, props );
+
+ if ( !searchBaseDn.startsWith( ctxRoot ) )
+ {
+ throw new NamingException( "Invalid search base " + baseDn );
+ }
+
+ for ( int ii = 0; ii < ctxRoot.size(); ii++ )
+ {
+ searchBaseDn.remove( 0 );
+ }
+
+ return searchBaseDn;
+ }
+
+ private Name getDomainComponents( Name name ) throws NamingException
+ {
+ for ( int ii = 0; ii < name.size(); ii++ )
+ {
+ if ( !name.get( ii ).startsWith( "dc=" ) )
+ {
+ name.remove( ii );
+ }
+ }
+
+ return name;
+ }
+}
Propchange: directory/protocol-providers/dns/trunk/src/java/org/apache/dns/store/operations/GetRecords.java
------------------------------------------------------------------------------
svn:eol-style = native