View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.server.ldap.replication;
21  
22  
23  import java.util.HashSet;
24  import java.util.Set;
25  
26  import javax.net.ssl.X509TrustManager;
27  
28  import org.apache.directory.api.ldap.model.constants.LdapConstants;
29  import org.apache.directory.api.ldap.model.constants.SchemaConstants;
30  import org.apache.directory.api.ldap.model.message.AliasDerefMode;
31  import org.apache.directory.api.ldap.model.message.SearchScope;
32  import org.apache.directory.api.ldap.model.name.Dn;
33  import org.apache.directory.api.util.Network;
34  import org.apache.directory.ldap.client.api.NoVerificationTrustManager;
35  
36  
37  /**
38   * A class for holding the syncrepl consumer's configuration. the following parameters
39   * are part of the Syncrepl Consumer configuration :<br>
40   * <ul>
41   *   <li>remoteHost : the remote server's name, defaults to 'localhost'</li>
42   *   <li>remotePort : the remote server's LDAP port, defaults to 10389</li>
43   *   <li>replUserDn : The replication User's DN</li>
44   *   <li>replUserPassword : The replication User's password</li>
45   *   <li>refreshNPersist : the replication mode, defaults to 'true'</li>
46   *   <li>refreshInterval : the interval between replications when in refreshOnly mode, defaults to 60s</li>
47   *   <li>baseDn : the base from which to fetch entries on the remote server</li>
48   *   <li>filter : the filter to select entries,defaults to (ObjectClass=*)</li>
49   *   <li>attributes : the list of attributes to replicate, defaults to all</li>
50   *   <li>searchSizeLimit : the maximum number of entries to fetch, defaults to no limit</li>
51   *   <li>searchTimeout : the maximum delay to wait for entries, defaults to no limit</li>
52   *   <li>searchScope : the scope, defaults to SUBTREE</li>
53   *   <li>aliasDerefMode : set the aliss derefence policy, defaults to NEVER </li>
54   *   <li>replicaId : the replica identifier</li>
55   *   <li>configEntryDn : the configuration entry's DN</li>
56   *   <li>chaseReferrals : tells if we chase referrals, defaults to false</li>
57   *   <li>cookie : the replication cookie</li>
58   *   <li>useTls : the connection uses TLS, defaults to true</li>
59   *   <li>strictCertVerification : strictly verify the certificate, defaults to true</li>
60   *   <li>trustManager : the trustManager to use, defaults to @link{NoVerificationTrustManager}</li>
61   *   <li></li>
62   * </ul>
63   * 
64   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
65   */
66  public class SyncReplConfiguration implements ReplicationConsumerConfig
67  {
68      /** host name of the syncrepl remote server, default value is localhost */
69      private String remoteHost;
70  
71      /** port number of the syncrepl provider server, default is 10389 */
72      private int remotePort;
73  
74      /** The producer, as <host>:<port> */
75      private String producer;
76  
77      /** replication user's Dn */
78      private String replUserDn;
79  
80      /** password for binding with replication user dn */
81      private byte[] replUserPassword;
82  
83      /** flag to represent refresh and persist or refresh only mode, defaults to true */
84      private boolean refreshNPersist = true;
85  
86      /** time interval for successive sync requests, default is 60 seconds */
87      private long refreshInterval = 60L * 1000L;
88  
89      /** the base Dn whose content will be searched for replicating */
90      private String baseDn;
91  
92      /** the ldap filter for fetching the entries, default value is (objectClass=*) */
93      private String filter = LdapConstants.OBJECT_CLASS_STAR;
94  
95      /** names of attributes to be replicated, default value is all user attributes */
96      private Set<String> attributes;
97  
98      /** the maximum number of search results to be fetched
99       * default value is 0 (i.e no limit) */
100     private int searchSizeLimit = 0;
101 
102     /** the timeout value to be used while doing a search 
103      * default value is 0 (i.e no limit)*/
104     private int searchTimeout = 0;
105 
106     /** the search scope, default is sub tree level */
107     private SearchScope searchScope = SearchScope.SUBTREE;
108 
109     /** alias dereferencing mode, default is set to 'never deref aliases' */
110     private AliasDerefMode aliasDerefMode = AliasDerefMode.NEVER_DEREF_ALIASES;
111 
112     /** the cookie received from server */
113     private byte[] cookie;
114 
115     /** the replica's id */
116     private int replicaId;
117 
118     /** The configuration entry DN */
119     private Dn configEntryDn = null;
120 
121     /** flag to indicate whether to chase referrals or not, default is false hence passes ManageDsaITControl with syncsearch request*/
122     private boolean chaseReferrals = false;
123 
124     /** flag to indicate the use of TLS, default is true */
125     private boolean useTls = true;
126 
127     /** flag to indicate the use of strict certificate verification, default is true */
128     private boolean strictCertVerification = true;
129 
130     /** the X509 certificate trust manager used, default value set to {@link NoVerificationTrustManager} */
131     private X509TrustManager trustManager = new NoVerificationTrustManager();
132 
133     /** flag to indicate if this node is part of a MMR setup, default value is true */
134     private boolean mmrMode = true;
135 
136 
137     /**
138      * Creates a new instance of SyncreplConfiguration
139      */
140     public SyncReplConfiguration()
141     {
142         attributes = new HashSet<>();
143         // the default list of attributes
144         attributes.add( SchemaConstants.ALL_USER_ATTRIBUTES );
145         
146         remoteHost = Network.LOOPBACK_HOSTNAME;
147         
148         remotePort = 10389;
149         
150         producer = remoteHost + ":" + remotePort;
151     }
152 
153 
154     /**
155      * @return the remote Host
156      */
157     public String getRemoteHost()
158     {
159         return remoteHost;
160     }
161 
162 
163     /**
164      * @param remoteHost the remote Host to set
165      */
166     public void setRemoteHost( String remoteHost )
167     {
168         this.remoteHost = remoteHost;
169         producer = remoteHost + ":" + remotePort;
170     }
171 
172 
173     /**
174      * A convenient method that concatenates the host and port of the producer
175      * @return The &lt;host&gt;:&lt;port&gt; the consumer is connected to
176      */
177     public String getProducer()
178     {
179         return producer;
180     }
181 
182 
183     /**
184      * @return the port
185      */
186     public int getRemotePort()
187     {
188         return remotePort;
189     }
190 
191 
192     /**
193      * @param remotePort the remote port to set
194      */
195     public void setRemotePort( int remotePort )
196     {
197         this.remotePort = remotePort;
198         producer = remoteHost + ":" + remotePort;
199     }
200 
201 
202     /**
203      * @return the replication user's Dn
204      */
205     public String getReplUserDn()
206     {
207         return replUserDn;
208     }
209 
210 
211     /**
212      * @param replUserdDn the Dn of the replication user
213      */
214     public void setReplUserDn( String replUserdDn )
215     {
216         this.replUserDn = replUserdDn;
217     }
218 
219 
220     /**
221      * @return the replication user's password
222      */
223     public byte[] getReplUserPassword()
224     {
225         return replUserPassword;
226     }
227 
228 
229     /**
230      * @param replUserPassword the replication user's password
231      */
232     public void setReplUserPassword( byte[] replUserPassword )
233     {
234         this.replUserPassword = replUserPassword;
235     }
236 
237 
238     /**
239      * @return the refreshPersist
240      */
241     public boolean isRefreshNPersist()
242     {
243         return refreshNPersist;
244     }
245 
246 
247     /**
248      * @param refreshNPersist the falg indicating to run the consumer in refreshAndPersist mode
249      */
250     public void setRefreshNPersist( boolean refreshNPersist )
251     {
252         this.refreshNPersist = refreshNPersist;
253     }
254 
255 
256     /**
257      * @return the refresh interval
258      */
259     public long getRefreshInterval()
260     {
261         return refreshInterval;
262     }
263 
264 
265     /**
266      * @param refreshInterval the consumerInterval to set
267      */
268     public void setRefreshInterval( long refreshInterval )
269     {
270         if ( refreshInterval <= 0 )
271         {
272             throw new IllegalArgumentException( "refresh interval should be more than zero" );
273         }
274         this.refreshInterval = refreshInterval;
275     }
276 
277 
278     /**
279      * @return the baseDn
280      */
281     public String getBaseDn()
282     {
283         return baseDn;
284     }
285 
286 
287     /**
288      * @param baseDn the baseDn to set
289      */
290     public void setBaseDn( String baseDn )
291     {
292         this.baseDn = baseDn;
293     }
294 
295 
296     /**
297      * @return the filter
298      */
299     public String getFilter()
300     {
301         return filter;
302     }
303 
304 
305     /**
306      * @param filter the filter to set
307      */
308     public void setFilter( String filter )
309     {
310         this.filter = filter;
311     }
312 
313 
314     /**
315      * @return the attributes
316      */
317     public String[] getAttributes()
318     {
319         return attributes.toArray( new String[]
320             {} );
321     }
322 
323 
324     /**
325      * @param attrs the attributes to set
326      */
327     public void setAttributes( String[] attrs )
328     {
329         attributes.clear();
330 
331         for ( String attr : attrs )
332         {
333             attributes.add( attr );
334         }
335     }
336 
337 
338     /**
339      * @return the searchSizeLimit
340      */
341     public int getSearchSizeLimit()
342     {
343         return searchSizeLimit;
344     }
345 
346 
347     /**
348      * @param searchSizeLimit the searchSizeLimit to set
349      */
350     public void setSearchSizeLimit( int searchSizeLimit )
351     {
352         if ( searchSizeLimit < 0 )
353         {
354             throw new IllegalArgumentException( "search size limit value cannot be negative " + searchSizeLimit );
355         }
356 
357         this.searchSizeLimit = searchSizeLimit;
358     }
359 
360 
361     /**
362      * @return the searchTimeout
363      */
364     public int getSearchTimeout()
365     {
366         return searchTimeout;
367     }
368 
369 
370     /**
371      * @param searchTimeout the searchTimeout to set
372      */
373     public void setSearchTimeout( int searchTimeout )
374     {
375         if ( searchTimeout < 0 )
376         {
377             throw new IllegalArgumentException( "search timeout value cannot be negative " + searchTimeout );
378         }
379 
380         this.searchTimeout = searchTimeout;
381     }
382 
383 
384     /**
385      * @return the searchScope
386      */
387     public SearchScope getSearchScope()
388     {
389         return searchScope;
390     }
391 
392 
393     /**
394      * @param searchScope the searchScope to set
395      */
396     public void setSearchScope( SearchScope searchScope )
397     {
398         this.searchScope = searchScope;
399     }
400 
401 
402     /**
403      * @return the replicaId
404      */
405     public int getReplicaId()
406     {
407         return replicaId;
408     }
409 
410 
411     /**
412      * @param replicaId the replicaId to set
413      */
414     public void setReplicaId( int replicaId )
415     {
416         this.replicaId = replicaId;
417     }
418 
419 
420     /**
421      * @return The ALiasDerefMode parameter
422      */
423     public AliasDerefMode getAliasDerefMode()
424     {
425         return aliasDerefMode;
426     }
427 
428 
429     /**
430      * @param aliasDerefMode Should be either NEVER_DEREF_ALIASES or DEREF_FINDING_BASE_OBJ
431      */
432     public void setAliasDerefMode( AliasDerefMode aliasDerefMode )
433     {
434         if ( aliasDerefMode != AliasDerefMode.NEVER_DEREF_ALIASES
435             && aliasDerefMode != AliasDerefMode.DEREF_FINDING_BASE_OBJ )
436         {
437             throw new IllegalArgumentException(
438                 "alias deref mode should only be set to either 'NEVER_DEREF_ALIASES' or 'DEREF_FINDING_BASE_OBJ'" );
439         }
440 
441         this.aliasDerefMode = aliasDerefMode;
442     }
443 
444 
445     /**
446      * @return The replication cookie
447      */
448     public byte[] getCookie()
449     {
450         return cookie;
451     }
452 
453 
454     /**
455      * @param cookie The cookie to set
456      */
457     public void setCookie( byte[] cookie )
458     {
459         this.cookie = cookie;
460     }
461 
462 
463     /**
464      * Tells if we chase referrals
465      * @return true if we chase referals
466      */
467     public boolean isChaseReferrals()
468     {
469         return chaseReferrals;
470     }
471 
472 
473     /**
474      * @param chaseReferrals Lust be false, always.
475      */
476     public void setChaseReferrals( boolean chaseReferrals )
477     {
478         if ( chaseReferrals )
479         {
480             throw new UnsupportedOperationException( "client-api currently doesn't support chasing referrals" );
481         }
482 
483         this.chaseReferrals = chaseReferrals;
484     }
485 
486 
487     /**
488      * @return The DN of the configuration entry
489      */
490     public Dn getConfigEntryDn()
491     {
492         return configEntryDn;
493     }
494 
495 
496     /**
497      * @return true if we use TLS
498      */
499     public boolean isUseTls()
500     {
501         return useTls;
502     }
503 
504 
505     /**
506      * set the option to turn on/off use of TLS
507      * 
508      * @param useTls If we have to use TLS
509      */
510     public void setUseTls( boolean useTls )
511     {
512         this.useTls = useTls;
513     }
514 
515 
516     /**
517      * @return true if the certificate verification is enforced 
518      */
519     public boolean isStrictCertVerification()
520     {
521         return strictCertVerification;
522     }
523 
524 
525     /**
526      * set the strict certificate verification
527      * 
528      * @param strictCertVerification If we require a certificate validation
529      */
530     public void setStrictCertVerification( boolean strictCertVerification )
531     {
532         if ( strictCertVerification )
533         {
534             trustManager = ReplicationTrustManager.getInstance();
535         }
536         else
537         {
538             trustManager = new NoVerificationTrustManager();
539         }
540 
541         this.strictCertVerification = strictCertVerification;
542     }
543 
544 
545     /**
546      * @return The Trustmanager instance
547      */
548     public X509TrustManager getTrustManager()
549     {
550         return trustManager;
551     }
552 
553 
554     /**
555      * @param configEntryDn the configEntryDn to set
556      */
557     public void setConfigEntryDn( Dn configEntryDn )
558     {
559         this.configEntryDn = configEntryDn;
560     }
561 
562 
563     /**
564      * @return true if this node is part of MMR setup
565      */
566     public boolean isMmrMode()
567     {
568         return mmrMode;
569     }
570 
571 
572     /**
573      * enable/disable MMR option
574      *
575      * @param mmrMode The type of replication
576      */
577     public void setMmrMode( boolean mmrMode )
578     {
579         this.mmrMode = mmrMode;
580     }
581 
582 
583     public String toString()
584     {
585         StringBuilder sb = new StringBuilder();
586 
587         sb.append( "[" );
588         sb.append( "rid:" ).append( replicaId ).append( ", " );
589         sb.append( "base:'" ).append( baseDn ).append( "', " );
590         sb.append( "filter:" ).append( filter ).append( ", " );
591         sb.append( "scope:" ).append( searchScope ).append( ", " );
592         sb.append( "alias:" ).append( aliasDerefMode ).append( ", " );
593         sb.append( "chase referrals:" ).append( chaseReferrals ).append( ", " );
594 
595         boolean isFirst = true;
596 
597         if ( attributes != null )
598         {
599             sb.append( "attributes:{" );
600 
601             for ( String attribute : attributes )
602             {
603                 if ( isFirst )
604                 {
605                     isFirst = false;
606                 }
607                 else
608                 {
609                     sb.append( "/" );
610                 }
611 
612                 sb.append( attribute );
613             }
614 
615             sb.append( "}, " );
616         }
617 
618         if ( refreshNPersist )
619         {
620             sb.append( "refresh:" ).append( refreshInterval ).append( ", " );
621         }
622         else
623         {
624             sb.append( "refreshOnly, " );
625         }
626 
627         if ( mmrMode )
628         {
629             sb.append( "MMR, " );
630         }
631         else
632         {
633             sb.append( "MS, " );
634         }
635 
636         sb.append( "provider:" ).append( producer ).append( ", " );
637         sb.append( "user:'" ).append( replUserDn ).append( "', " );
638 
639         if ( strictCertVerification )
640         {
641             sb.append( "strict" ).append( ", " );
642         }
643 
644         sb.append( "TLS:" ).append( useTls ).append( "]" );
645 
646         return sb.toString();
647     }
648 }