001 /*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License"). You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at
010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012 * See the License for the specific language governing permissions
013 * and limitations under the License.
014 *
015 * When distributing Covered Code, include this CDDL HEADER in each
016 * file and include the License file at
017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
018 * add the following below this CDDL HEADER, with the fields enclosed
019 * by brackets "[]" replaced with your own identifying information:
020 * Portions Copyright [yyyy] [name of copyright owner]
021 *
022 * CDDL HEADER END
023 *
024 *
025 * Copyright 2008 Sun Microsystems, Inc.
026 */
027 package org.opends.server.admin.std.meta;
028
029
030
031 import java.util.Collection;
032 import java.util.SortedSet;
033 import org.opends.server.admin.AdministratorAction;
034 import org.opends.server.admin.client.AuthorizationException;
035 import org.opends.server.admin.client.CommunicationException;
036 import org.opends.server.admin.client.ConcurrentModificationException;
037 import org.opends.server.admin.client.ManagedObject;
038 import org.opends.server.admin.client.MissingMandatoryPropertiesException;
039 import org.opends.server.admin.client.OperationRejectedException;
040 import org.opends.server.admin.DefaultBehaviorProvider;
041 import org.opends.server.admin.DefinedDefaultBehaviorProvider;
042 import org.opends.server.admin.DNPropertyDefinition;
043 import org.opends.server.admin.DurationPropertyDefinition;
044 import org.opends.server.admin.EnumPropertyDefinition;
045 import org.opends.server.admin.IntegerPropertyDefinition;
046 import org.opends.server.admin.ManagedObjectAlreadyExistsException;
047 import org.opends.server.admin.ManagedObjectDefinition;
048 import org.opends.server.admin.PropertyIsReadOnlyException;
049 import org.opends.server.admin.PropertyOption;
050 import org.opends.server.admin.PropertyProvider;
051 import org.opends.server.admin.server.ConfigurationChangeListener;
052 import org.opends.server.admin.server.ServerManagedObject;
053 import org.opends.server.admin.std.client.ReplicationDomainCfgClient;
054 import org.opends.server.admin.std.server.ReplicationDomainCfg;
055 import org.opends.server.admin.StringPropertyDefinition;
056 import org.opends.server.admin.Tag;
057 import org.opends.server.admin.TopCfgDefn;
058 import org.opends.server.admin.UndefinedDefaultBehaviorProvider;
059 import org.opends.server.types.DN;
060
061
062
063 /**
064 * An interface for querying the Replication Domain managed object
065 * definition meta information.
066 * <p>
067 * A Replication Domain comprises of several Directory Servers sharing
068 * the same synchronized set of data.
069 */
070 public final class ReplicationDomainCfgDefn extends ManagedObjectDefinition<ReplicationDomainCfgClient, ReplicationDomainCfg> {
071
072 // The singleton configuration definition instance.
073 private static final ReplicationDomainCfgDefn INSTANCE = new ReplicationDomainCfgDefn();
074
075
076
077 /**
078 * Defines the set of permissable values for the "isolation-policy" property.
079 * <p>
080 * Specifies the behavior of the Directory Server if a write
081 * operation is attempted on the data within the Replication Domain
082 * when none of the configured Replication Servers are available.
083 */
084 public static enum IsolationPolicy {
085
086 /**
087 * Indicates that updates should be accepted even though it is not
088 * possible to send them to any Replication Server. Best effort is
089 * made to re-send those updates to a Replication Servers when one
090 * of them is available, however those changes are at risk because
091 * they are only available from the historical information. This
092 * mode can also introduce high replication latency.
093 */
094 ACCEPT_ALL_UPDATES("accept-all-updates"),
095
096
097
098 /**
099 * Indicates that all updates attempted on this Replication Domain
100 * are rejected when no Replication Server is available.
101 */
102 REJECT_ALL_UPDATES("reject-all-updates");
103
104
105
106 // String representation of the value.
107 private final String name;
108
109
110
111 // Private constructor.
112 private IsolationPolicy(String name) { this.name = name; }
113
114
115
116 /**
117 * {@inheritDoc}
118 */
119 public String toString() { return name; }
120
121 }
122
123
124
125 // The "base-dn" property definition.
126 private static final DNPropertyDefinition PD_BASE_DN;
127
128
129
130 // The "heartbeat-interval" property definition.
131 private static final DurationPropertyDefinition PD_HEARTBEAT_INTERVAL;
132
133
134
135 // The "isolation-policy" property definition.
136 private static final EnumPropertyDefinition<IsolationPolicy> PD_ISOLATION_POLICY;
137
138
139
140 // The "replication-server" property definition.
141 private static final StringPropertyDefinition PD_REPLICATION_SERVER;
142
143
144
145 // The "server-id" property definition.
146 private static final IntegerPropertyDefinition PD_SERVER_ID;
147
148
149
150 // The "window-size" property definition.
151 private static final IntegerPropertyDefinition PD_WINDOW_SIZE;
152
153
154
155 // Build the "base-dn" property definition.
156 static {
157 DNPropertyDefinition.Builder builder = DNPropertyDefinition.createBuilder(INSTANCE, "base-dn");
158 builder.setOption(PropertyOption.READ_ONLY);
159 builder.setOption(PropertyOption.MANDATORY);
160 builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "base-dn"));
161 builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<DN>());
162 PD_BASE_DN = builder.getInstance();
163 INSTANCE.registerPropertyDefinition(PD_BASE_DN);
164 }
165
166
167
168 // Build the "heartbeat-interval" property definition.
169 static {
170 DurationPropertyDefinition.Builder builder = DurationPropertyDefinition.createBuilder(INSTANCE, "heartbeat-interval");
171 builder.setOption(PropertyOption.ADVANCED);
172 builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "heartbeat-interval"));
173 DefaultBehaviorProvider<Long> provider = new DefinedDefaultBehaviorProvider<Long>("1000ms");
174 builder.setDefaultBehaviorProvider(provider);
175 builder.setBaseUnit("ms");
176 builder.setLowerLimit("100");
177 PD_HEARTBEAT_INTERVAL = builder.getInstance();
178 INSTANCE.registerPropertyDefinition(PD_HEARTBEAT_INTERVAL);
179 }
180
181
182
183 // Build the "isolation-policy" property definition.
184 static {
185 EnumPropertyDefinition.Builder<IsolationPolicy> builder = EnumPropertyDefinition.createBuilder(INSTANCE, "isolation-policy");
186 builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "isolation-policy"));
187 DefaultBehaviorProvider<IsolationPolicy> provider = new DefinedDefaultBehaviorProvider<IsolationPolicy>("reject-all-updates");
188 builder.setDefaultBehaviorProvider(provider);
189 builder.setEnumClass(IsolationPolicy.class);
190 PD_ISOLATION_POLICY = builder.getInstance();
191 INSTANCE.registerPropertyDefinition(PD_ISOLATION_POLICY);
192 }
193
194
195
196 // Build the "replication-server" property definition.
197 static {
198 StringPropertyDefinition.Builder builder = StringPropertyDefinition.createBuilder(INSTANCE, "replication-server");
199 builder.setOption(PropertyOption.MULTI_VALUED);
200 builder.setOption(PropertyOption.MANDATORY);
201 builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "replication-server"));
202 builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<String>());
203 builder.setPattern("^.+:[0-9]+$", "HOST:PORT");
204 PD_REPLICATION_SERVER = builder.getInstance();
205 INSTANCE.registerPropertyDefinition(PD_REPLICATION_SERVER);
206 }
207
208
209
210 // Build the "server-id" property definition.
211 static {
212 IntegerPropertyDefinition.Builder builder = IntegerPropertyDefinition.createBuilder(INSTANCE, "server-id");
213 builder.setOption(PropertyOption.READ_ONLY);
214 builder.setOption(PropertyOption.MANDATORY);
215 builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "server-id"));
216 builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<Integer>());
217 builder.setUpperLimit(65535);
218 builder.setLowerLimit(1);
219 PD_SERVER_ID = builder.getInstance();
220 INSTANCE.registerPropertyDefinition(PD_SERVER_ID);
221 }
222
223
224
225 // Build the "window-size" property definition.
226 static {
227 IntegerPropertyDefinition.Builder builder = IntegerPropertyDefinition.createBuilder(INSTANCE, "window-size");
228 builder.setOption(PropertyOption.ADVANCED);
229 builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "window-size"));
230 DefaultBehaviorProvider<Integer> provider = new DefinedDefaultBehaviorProvider<Integer>("100");
231 builder.setDefaultBehaviorProvider(provider);
232 PD_WINDOW_SIZE = builder.getInstance();
233 INSTANCE.registerPropertyDefinition(PD_WINDOW_SIZE);
234 }
235
236
237
238 // Register the tags associated with this managed object definition.
239 static {
240 INSTANCE.registerTag(Tag.valueOf("replication"));
241 }
242
243
244
245 /**
246 * Get the Replication Domain configuration definition singleton.
247 *
248 * @return Returns the Replication Domain configuration definition
249 * singleton.
250 */
251 public static ReplicationDomainCfgDefn getInstance() {
252 return INSTANCE;
253 }
254
255
256
257 /**
258 * Private constructor.
259 */
260 private ReplicationDomainCfgDefn() {
261 super("replication-domain", TopCfgDefn.getInstance());
262 }
263
264
265
266 /**
267 * {@inheritDoc}
268 */
269 public ReplicationDomainCfgClient createClientConfiguration(
270 ManagedObject<? extends ReplicationDomainCfgClient> impl) {
271 return new ReplicationDomainCfgClientImpl(impl);
272 }
273
274
275
276 /**
277 * {@inheritDoc}
278 */
279 public ReplicationDomainCfg createServerConfiguration(
280 ServerManagedObject<? extends ReplicationDomainCfg> impl) {
281 return new ReplicationDomainCfgServerImpl(impl);
282 }
283
284
285
286 /**
287 * {@inheritDoc}
288 */
289 public Class<ReplicationDomainCfg> getServerConfigurationClass() {
290 return ReplicationDomainCfg.class;
291 }
292
293
294
295 /**
296 * Get the "base-dn" property definition.
297 * <p>
298 * Specifies the base DN of the replicated data.
299 *
300 * @return Returns the "base-dn" property definition.
301 */
302 public DNPropertyDefinition getBaseDNPropertyDefinition() {
303 return PD_BASE_DN;
304 }
305
306
307
308 /**
309 * Get the "heartbeat-interval" property definition.
310 * <p>
311 * Specifies the heart-beat interval that the Directory Server will
312 * use when communicating with Replication Servers.
313 * <p>
314 * The Directory Server expects a regular heart-beat coming from the
315 * Replication Server within the specified interval. If a heartbeat
316 * is not received within the interval, the Directory Server closes
317 * its connection and connects to another Replication Server.
318 *
319 * @return Returns the "heartbeat-interval" property definition.
320 */
321 public DurationPropertyDefinition getHeartbeatIntervalPropertyDefinition() {
322 return PD_HEARTBEAT_INTERVAL;
323 }
324
325
326
327 /**
328 * Get the "isolation-policy" property definition.
329 * <p>
330 * Specifies the behavior of the Directory Server if a write
331 * operation is attempted on the data within the Replication Domain
332 * when none of the configured Replication Servers are available.
333 *
334 * @return Returns the "isolation-policy" property definition.
335 */
336 public EnumPropertyDefinition<IsolationPolicy> getIsolationPolicyPropertyDefinition() {
337 return PD_ISOLATION_POLICY;
338 }
339
340
341
342 /**
343 * Get the "replication-server" property definition.
344 * <p>
345 * Specifies the addresses of the Replication Servers within the
346 * Replication Domain to which the Directory Server should try to
347 * connect at startup time.
348 * <p>
349 * Addresses must be specified using the syntax: hostname:port
350 *
351 * @return Returns the "replication-server" property definition.
352 */
353 public StringPropertyDefinition getReplicationServerPropertyDefinition() {
354 return PD_REPLICATION_SERVER;
355 }
356
357
358
359 /**
360 * Get the "server-id" property definition.
361 * <p>
362 * Specifies a unique identifier for the Directory Server within the
363 * Replication Domain.
364 * <p>
365 * Each Directory Server within the same Replication Domain must
366 * have a different server ID. A Directory Server which is a member
367 * of multiple Replication Domains may use the same server ID for
368 * each of its Replication Domain configurations.
369 *
370 * @return Returns the "server-id" property definition.
371 */
372 public IntegerPropertyDefinition getServerIdPropertyDefinition() {
373 return PD_SERVER_ID;
374 }
375
376
377
378 /**
379 * Get the "window-size" property definition.
380 * <p>
381 * Specifies the window size that the Directory Server will use when
382 * communicating with Replication Servers.
383 *
384 * @return Returns the "window-size" property definition.
385 */
386 public IntegerPropertyDefinition getWindowSizePropertyDefinition() {
387 return PD_WINDOW_SIZE;
388 }
389
390
391
392 /**
393 * Managed object client implementation.
394 */
395 private static class ReplicationDomainCfgClientImpl implements
396 ReplicationDomainCfgClient {
397
398 // Private implementation.
399 private ManagedObject<? extends ReplicationDomainCfgClient> impl;
400
401
402
403 // Private constructor.
404 private ReplicationDomainCfgClientImpl(
405 ManagedObject<? extends ReplicationDomainCfgClient> impl) {
406 this.impl = impl;
407 }
408
409
410
411 /**
412 * {@inheritDoc}
413 */
414 public DN getBaseDN() {
415 return impl.getPropertyValue(INSTANCE.getBaseDNPropertyDefinition());
416 }
417
418
419
420 /**
421 * {@inheritDoc}
422 */
423 public void setBaseDN(DN value) throws PropertyIsReadOnlyException {
424 impl.setPropertyValue(INSTANCE.getBaseDNPropertyDefinition(), value);
425 }
426
427
428
429 /**
430 * {@inheritDoc}
431 */
432 public long getHeartbeatInterval() {
433 return impl.getPropertyValue(INSTANCE.getHeartbeatIntervalPropertyDefinition());
434 }
435
436
437
438 /**
439 * {@inheritDoc}
440 */
441 public void setHeartbeatInterval(Long value) {
442 impl.setPropertyValue(INSTANCE.getHeartbeatIntervalPropertyDefinition(), value);
443 }
444
445
446
447 /**
448 * {@inheritDoc}
449 */
450 public IsolationPolicy getIsolationPolicy() {
451 return impl.getPropertyValue(INSTANCE.getIsolationPolicyPropertyDefinition());
452 }
453
454
455
456 /**
457 * {@inheritDoc}
458 */
459 public void setIsolationPolicy(IsolationPolicy value) {
460 impl.setPropertyValue(INSTANCE.getIsolationPolicyPropertyDefinition(), value);
461 }
462
463
464
465 /**
466 * {@inheritDoc}
467 */
468 public SortedSet<String> getReplicationServer() {
469 return impl.getPropertyValues(INSTANCE.getReplicationServerPropertyDefinition());
470 }
471
472
473
474 /**
475 * {@inheritDoc}
476 */
477 public void setReplicationServer(Collection<String> values) {
478 impl.setPropertyValues(INSTANCE.getReplicationServerPropertyDefinition(), values);
479 }
480
481
482
483 /**
484 * {@inheritDoc}
485 */
486 public Integer getServerId() {
487 return impl.getPropertyValue(INSTANCE.getServerIdPropertyDefinition());
488 }
489
490
491
492 /**
493 * {@inheritDoc}
494 */
495 public void setServerId(int value) throws PropertyIsReadOnlyException {
496 impl.setPropertyValue(INSTANCE.getServerIdPropertyDefinition(), value);
497 }
498
499
500
501 /**
502 * {@inheritDoc}
503 */
504 public int getWindowSize() {
505 return impl.getPropertyValue(INSTANCE.getWindowSizePropertyDefinition());
506 }
507
508
509
510 /**
511 * {@inheritDoc}
512 */
513 public void setWindowSize(Integer value) {
514 impl.setPropertyValue(INSTANCE.getWindowSizePropertyDefinition(), value);
515 }
516
517
518
519 /**
520 * {@inheritDoc}
521 */
522 public ManagedObjectDefinition<? extends ReplicationDomainCfgClient, ? extends ReplicationDomainCfg> definition() {
523 return INSTANCE;
524 }
525
526
527
528 /**
529 * {@inheritDoc}
530 */
531 public PropertyProvider properties() {
532 return impl;
533 }
534
535
536
537 /**
538 * {@inheritDoc}
539 */
540 public void commit() throws ManagedObjectAlreadyExistsException,
541 MissingMandatoryPropertiesException, ConcurrentModificationException,
542 OperationRejectedException, AuthorizationException,
543 CommunicationException {
544 impl.commit();
545 }
546
547 }
548
549
550
551 /**
552 * Managed object server implementation.
553 */
554 private static class ReplicationDomainCfgServerImpl implements
555 ReplicationDomainCfg {
556
557 // Private implementation.
558 private ServerManagedObject<? extends ReplicationDomainCfg> impl;
559
560 // The value of the "base-dn" property.
561 private final DN pBaseDN;
562
563 // The value of the "heartbeat-interval" property.
564 private final long pHeartbeatInterval;
565
566 // The value of the "isolation-policy" property.
567 private final IsolationPolicy pIsolationPolicy;
568
569 // The value of the "replication-server" property.
570 private final SortedSet<String> pReplicationServer;
571
572 // The value of the "server-id" property.
573 private final int pServerId;
574
575 // The value of the "window-size" property.
576 private final int pWindowSize;
577
578
579
580 // Private constructor.
581 private ReplicationDomainCfgServerImpl(ServerManagedObject<? extends ReplicationDomainCfg> impl) {
582 this.impl = impl;
583 this.pBaseDN = impl.getPropertyValue(INSTANCE.getBaseDNPropertyDefinition());
584 this.pHeartbeatInterval = impl.getPropertyValue(INSTANCE.getHeartbeatIntervalPropertyDefinition());
585 this.pIsolationPolicy = impl.getPropertyValue(INSTANCE.getIsolationPolicyPropertyDefinition());
586 this.pReplicationServer = impl.getPropertyValues(INSTANCE.getReplicationServerPropertyDefinition());
587 this.pServerId = impl.getPropertyValue(INSTANCE.getServerIdPropertyDefinition());
588 this.pWindowSize = impl.getPropertyValue(INSTANCE.getWindowSizePropertyDefinition());
589 }
590
591
592
593 /**
594 * {@inheritDoc}
595 */
596 public void addChangeListener(
597 ConfigurationChangeListener<ReplicationDomainCfg> listener) {
598 impl.registerChangeListener(listener);
599 }
600
601
602
603 /**
604 * {@inheritDoc}
605 */
606 public void removeChangeListener(
607 ConfigurationChangeListener<ReplicationDomainCfg> listener) {
608 impl.deregisterChangeListener(listener);
609 }
610
611
612
613 /**
614 * {@inheritDoc}
615 */
616 public DN getBaseDN() {
617 return pBaseDN;
618 }
619
620
621
622 /**
623 * {@inheritDoc}
624 */
625 public long getHeartbeatInterval() {
626 return pHeartbeatInterval;
627 }
628
629
630
631 /**
632 * {@inheritDoc}
633 */
634 public IsolationPolicy getIsolationPolicy() {
635 return pIsolationPolicy;
636 }
637
638
639
640 /**
641 * {@inheritDoc}
642 */
643 public SortedSet<String> getReplicationServer() {
644 return pReplicationServer;
645 }
646
647
648
649 /**
650 * {@inheritDoc}
651 */
652 public int getServerId() {
653 return pServerId;
654 }
655
656
657
658 /**
659 * {@inheritDoc}
660 */
661 public int getWindowSize() {
662 return pWindowSize;
663 }
664
665
666
667 /**
668 * {@inheritDoc}
669 */
670 public Class<? extends ReplicationDomainCfg> configurationClass() {
671 return ReplicationDomainCfg.class;
672 }
673
674
675
676 /**
677 * {@inheritDoc}
678 */
679 public DN dn() {
680 return impl.getDN();
681 }
682
683 }
684 }