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 legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2008-2009 Sun Microsystems, Inc.
025 *      Portions Copyright 2014-2015 ForgeRock AS
026 */
027
028package org.opends.guitools.controlpanel.task;
029
030import static org.opends.messages.AdminToolMessages.*;
031import static org.opends.messages.ConfigMessages.*;
032
033import java.util.ArrayList;
034import java.util.Collection;
035import java.util.HashMap;
036import java.util.HashSet;
037import java.util.LinkedList;
038import java.util.List;
039import java.util.Map;
040import java.util.Set;
041import java.util.SortedSet;
042import java.util.TreeSet;
043import java.util.concurrent.atomic.AtomicReference;
044
045import javax.naming.ldap.InitialLdapContext;
046import javax.swing.SwingUtilities;
047
048import org.forgerock.i18n.LocalizableMessage;
049import org.forgerock.opendj.config.server.ConfigException;
050import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
051import org.opends.guitools.controlpanel.datamodel.BaseDNDescriptor;
052import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
053import org.opends.guitools.controlpanel.ui.ColorAndFontConstants;
054import org.opends.guitools.controlpanel.ui.ProgressDialog;
055import org.opends.guitools.controlpanel.util.ConfigReader;
056import org.opends.guitools.controlpanel.util.Utilities;
057import org.opends.server.admin.client.ManagementContext;
058import org.opends.server.admin.client.ldap.JNDIDirContextAdaptor;
059import org.opends.server.admin.client.ldap.LDAPManagementContext;
060import org.opends.server.admin.server.ServerManagementContext;
061import org.opends.server.admin.std.client.LocalDBBackendCfgClient;
062import org.opends.server.admin.std.client.ReplicationDomainCfgClient;
063import org.opends.server.admin.std.client.ReplicationSynchronizationProviderCfgClient;
064import org.opends.server.admin.std.client.RootCfgClient;
065import org.opends.server.admin.std.server.ReplicationDomainCfg;
066import org.opends.server.admin.std.server.ReplicationSynchronizationProviderCfg;
067import org.opends.server.admin.std.server.RootCfg;
068import org.opends.server.config.ConfigConstants;
069import org.opends.server.config.ConfigEntry;
070import org.opends.server.config.DNConfigAttribute;
071import org.opends.server.core.DirectoryServer;
072import org.opends.server.types.DN;
073import org.opends.server.types.OpenDsException;
074
075/** The task used to delete a set of base DNs or backends. */
076public class DeleteBaseDNAndBackendTask extends Task
077{
078  private Set<String> backendSet;
079  private Map<String, Set<BaseDNDescriptor>> baseDNsToDelete = new HashMap<>();
080  private ArrayList<BackendDescriptor> backendsToDelete = new ArrayList<>();
081
082  /**
083   * Constructor of the task.
084   * @param info the control panel information.
085   * @param dlg the progress dialog where the task progress will be displayed.
086   * @param backendsToDelete the backends to delete.
087   * @param baseDNsToDelete the base DNs to delete.
088   */
089  public DeleteBaseDNAndBackendTask(ControlPanelInfo info, ProgressDialog dlg,
090      Collection<BackendDescriptor> backendsToDelete,
091      Collection<BaseDNDescriptor> baseDNsToDelete)
092  {
093    super(info, dlg);
094    backendSet = new HashSet<>();
095    for (BackendDescriptor backend : backendsToDelete)
096    {
097      backendSet.add(backend.getBackendID());
098    }
099    for (BaseDNDescriptor baseDN : baseDNsToDelete)
100    {
101      backendSet.add(baseDN.getBackend().getBackendID());
102    }
103    for (BaseDNDescriptor baseDN : baseDNsToDelete)
104    {
105      String backendID = baseDN.getBackend().getBackendID();
106      Set<BaseDNDescriptor> set = this.baseDNsToDelete.get(backendID);
107      if (set == null)
108      {
109        set = new HashSet<>();
110        this.baseDNsToDelete.put(backendID, set);
111      }
112      set.add(baseDN);
113    }
114    ArrayList<String> indirectBackendsToDelete = new ArrayList<>();
115    for (Set<BaseDNDescriptor> set : this.baseDNsToDelete.values())
116    {
117      BackendDescriptor backend = set.iterator().next().getBackend();
118      if (set.size() == backend.getBaseDns().size())
119      {
120        // All of the suffixes must be deleted.
121        indirectBackendsToDelete.add(backend.getBackendID());
122        this.backendsToDelete.add(backend);
123      }
124    }
125    for (String backendID : indirectBackendsToDelete)
126    {
127      this.baseDNsToDelete.remove(backendID);
128    }
129    this.backendsToDelete.addAll(backendsToDelete);
130  }
131
132  /** {@inheritDoc} */
133  public Type getType()
134  {
135    return !baseDNsToDelete.isEmpty() ? Type.DELETE_BASEDN : Type.DELETE_BACKEND;
136  }
137
138  /** {@inheritDoc} */
139  public Set<String> getBackends()
140  {
141    return backendSet;
142  }
143
144  /** {@inheritDoc} */
145  public LocalizableMessage getTaskDescription()
146  {
147    StringBuilder sb = new StringBuilder();
148
149    if (!baseDNsToDelete.isEmpty())
150    {
151      ArrayList<String> dns = new ArrayList<>();
152      for (Set<BaseDNDescriptor> set : baseDNsToDelete.values())
153      {
154        for (BaseDNDescriptor baseDN : set)
155        {
156          dns.add(baseDN.getDn().toString());
157        }
158      }
159      if (dns.size() == 1)
160      {
161        String dn = dns.iterator().next();
162        sb.append(INFO_CTRL_PANEL_DELETE_BASE_DN_DESCRIPTION.get(dn));
163      }
164      else
165      {
166        ArrayList<String> quotedDns = new ArrayList<>();
167        for (String dn : dns)
168        {
169          quotedDns.add("'"+dn+"'");
170        }
171        sb.append(INFO_CTRL_PANEL_DELETE_BASE_DNS_DESCRIPTION.get(
172        Utilities.getStringFromCollection(quotedDns, ", ")));
173      }
174    }
175
176    if (!backendsToDelete.isEmpty())
177    {
178      if (sb.length() > 0)
179      {
180        sb.append("  ");
181      }
182      if (backendsToDelete.size() == 1)
183      {
184        sb.append(INFO_CTRL_PANEL_DELETE_BACKEND_DESCRIPTION.get(
185            backendsToDelete.iterator().next().getBackendID()));
186      }
187      else
188      {
189        ArrayList<String> ids = new ArrayList<>();
190        for (BackendDescriptor backend : backendsToDelete)
191        {
192          ids.add(backend.getBackendID());
193        }
194        sb.append(INFO_CTRL_PANEL_DELETE_BACKENDS_DESCRIPTION.get(
195        Utilities.getStringFromCollection(ids, ", ")));
196      }
197    }
198    return LocalizableMessage.raw(sb.toString());
199  }
200
201  /** {@inheritDoc} */
202  public boolean canLaunch(Task taskToBeLaunched,
203      Collection<LocalizableMessage> incompatibilityReasons)
204  {
205    boolean canLaunch = true;
206    if (state == State.RUNNING && runningOnSameServer(taskToBeLaunched))
207    {
208      // All the operations are incompatible if they apply to this
209      // backend for safety.  This is a short operation so the limitation
210      // has not a lot of impact.
211      Set<String> backends = new TreeSet<>(taskToBeLaunched.getBackends());
212      backends.retainAll(getBackends());
213      if (!backends.isEmpty())
214      {
215        incompatibilityReasons.add(
216            getIncompatibilityMessage(this, taskToBeLaunched));
217        canLaunch = false;
218      }
219    }
220    return canLaunch;
221  }
222
223  /**
224   * Update the configuration in the server.
225   * @throws OpenDsException if an error occurs.
226   */
227  private void updateConfiguration() throws OpenDsException, ConfigException
228  {
229    boolean configHandlerUpdated = false;
230    final int totalNumber = baseDNsToDelete.size() + backendsToDelete.size();
231    int numberDeleted = 0;
232    try
233    {
234      if (!isServerRunning())
235      {
236        configHandlerUpdated = true;
237        getInfo().stopPooling();
238        if (getInfo().mustDeregisterConfig())
239        {
240          DirectoryServer.deregisterBaseDN(DN.valueOf("cn=config"));
241        }
242        DirectoryServer.getInstance().initializeConfiguration(
243            org.opends.server.extensions.ConfigFileHandler.class.getName(),
244            ConfigReader.configFile);
245        getInfo().setMustDeregisterConfig(true);
246      }
247      boolean isFirst = true;
248      for (final Set<BaseDNDescriptor> baseDNs : baseDNsToDelete.values())
249      {
250        if (!isFirst)
251        {
252          SwingUtilities.invokeLater(new Runnable()
253          {
254            public void run()
255            {
256              getProgressDialog().appendProgressHtml("<br><br>");
257            }
258          });
259        }
260        isFirst = false;
261
262        for (BaseDNDescriptor baseDN : baseDNs)
263        {
264          disableReplicationIfRequired(baseDN);
265        }
266
267        if (isServerRunning())
268        {
269          SwingUtilities.invokeLater(new Runnable()
270          {
271            public void run()
272            {
273              List<String> args =
274                getObfuscatedCommandLineArguments(
275                    getDSConfigCommandLineArguments(baseDNs));
276              args.removeAll(getConfigCommandLineArguments());
277              printEquivalentCommandLine(getConfigCommandLinePath(), args,
278                  INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_DELETE_BASE_DN.get());
279            }
280          });
281        }
282        SwingUtilities.invokeLater(new Runnable()
283        {
284          public void run()
285          {
286            if (baseDNs.size() == 1)
287            {
288              String dn = baseDNs.iterator().next().getDn().toString();
289              getProgressDialog().appendProgressHtml(
290                  Utilities.getProgressWithPoints(
291                      INFO_CTRL_PANEL_DELETING_BASE_DN.get(dn),
292                      ColorAndFontConstants.progressFont));
293            }
294            else
295            {
296              ArrayList<String> dns = new ArrayList<>();
297              for (BaseDNDescriptor baseDN : baseDNs)
298              {
299                dns.add("'" + baseDN.getDn() + "'");
300              }
301              getProgressDialog().appendProgressHtml(
302                  Utilities.getProgressWithPoints(
303                      INFO_CTRL_PANEL_DELETING_BASE_DNS.get(
304                      Utilities.getStringFromCollection(dns, ", ")),
305                      ColorAndFontConstants.progressFont));
306            }
307          }
308        });
309        if (isServerRunning())
310        {
311          deleteBaseDNs(getInfo().getDirContext(), baseDNs);
312        }
313        else
314        {
315          deleteBaseDNs(baseDNs);
316        }
317        numberDeleted ++;
318        final int fNumberDeleted = numberDeleted;
319        SwingUtilities.invokeLater(new Runnable()
320        {
321          public void run()
322          {
323            getProgressDialog().getProgressBar().setIndeterminate(false);
324            getProgressDialog().getProgressBar().setValue(
325                (fNumberDeleted * 100) / totalNumber);
326            getProgressDialog().appendProgressHtml(
327                Utilities.getProgressDone(ColorAndFontConstants.progressFont));
328          }
329        });
330      }
331      for (final BackendDescriptor backend : backendsToDelete)
332      {
333        if (!isFirst)
334        {
335          SwingUtilities.invokeLater(new Runnable()
336          {
337            public void run()
338            {
339              getProgressDialog().appendProgressHtml("<br><br>");
340            }
341          });
342        }
343        for (BaseDNDescriptor baseDN : backend.getBaseDns())
344        {
345          disableReplicationIfRequired(baseDN);
346        }
347        isFirst = false;
348        if (isServerRunning())
349        {
350          SwingUtilities.invokeLater(new Runnable()
351          {
352            public void run()
353            {
354              List<String> args =
355                getObfuscatedCommandLineArguments(
356                    getDSConfigCommandLineArguments(backend));
357              args.removeAll(getConfigCommandLineArguments());
358              printEquivalentCommandLine(getConfigCommandLinePath(), args,
359                  INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_DELETE_BACKEND.get());
360            }
361          });
362        }
363        SwingUtilities.invokeLater(new Runnable()
364        {
365          public void run()
366          {
367            getProgressDialog().appendProgressHtml(
368                  Utilities.getProgressWithPoints(
369                      INFO_CTRL_PANEL_DELETING_BACKEND.get(
370                          backend.getBackendID()),
371                      ColorAndFontConstants.progressFont));
372          }
373        });
374        if (isServerRunning())
375        {
376          deleteBackend(getInfo().getDirContext(), backend);
377        }
378        else
379        {
380          deleteBackend(backend);
381        }
382        numberDeleted ++;
383        final int fNumberDeleted = numberDeleted;
384        SwingUtilities.invokeLater(new Runnable()
385        {
386          public void run()
387          {
388            getProgressDialog().getProgressBar().setIndeterminate(false);
389            getProgressDialog().getProgressBar().setValue(
390                (fNumberDeleted * 100) / totalNumber);
391            getProgressDialog().appendProgressHtml(
392                Utilities.getProgressDone(ColorAndFontConstants.progressFont));
393          }
394        });
395      }
396    }
397    finally
398    {
399      if (configHandlerUpdated)
400      {
401        DirectoryServer.getInstance().initializeConfiguration(
402            ConfigReader.configClassName, ConfigReader.configFile);
403        getInfo().startPooling();
404      }
405    }
406  }
407
408  /**
409   * Returns the DN in the configuration for a given backend.
410   * @param backend the backend.
411   * @return the backend configuration entry DN.
412   */
413  private String getDN(BackendDescriptor backend)
414  {
415    return Utilities.getRDNString("ds-cfg-backend-id",
416        backend.getBackendID())+",cn=Backends,cn=config";
417  }
418
419  /**
420   * Deletes a set of base DNs.  The code assumes that the server is not running
421   * and that the configuration file can be edited.
422   * @param baseDNs the list of base DNs.
423   * @throws OpenDsException if an error occurs.
424   */
425  private void deleteBaseDNs(Set<BaseDNDescriptor> baseDNs)
426  throws OpenDsException, ConfigException
427  {
428    BackendDescriptor backend = baseDNs.iterator().next().getBackend();
429
430    SortedSet<DN> oldBaseDNs = new TreeSet<>();
431    for (BaseDNDescriptor baseDN : backend.getBaseDns())
432    {
433      oldBaseDNs.add(baseDN.getDn());
434    }
435    LinkedList<DN> newBaseDNs = new LinkedList<>(oldBaseDNs);
436    ArrayList<DN> dnsToRemove = new ArrayList<>();
437    for (BaseDNDescriptor baseDN : baseDNs)
438    {
439      dnsToRemove.add(baseDN.getDn());
440    }
441    newBaseDNs.removeAll(dnsToRemove);
442
443    String backendName = backend.getBackendID();
444    String dn = Utilities.getRDNString("ds-cfg-backend-id", backendName)+
445    ",cn=Backends,cn=config";
446    ConfigEntry configEntry =
447      DirectoryServer.getConfigHandler().getConfigEntry(DN.valueOf(dn));
448
449    DNConfigAttribute baseDNAttr =
450      new DNConfigAttribute(
451          ConfigConstants.ATTR_BACKEND_BASE_DN,
452          INFO_CONFIG_BACKEND_ATTR_DESCRIPTION_BASE_DNS.get(),
453          true, true, false, newBaseDNs);
454    configEntry.putConfigAttribute(baseDNAttr);
455    DirectoryServer.getConfigHandler().writeUpdatedConfig();
456  }
457
458  /**
459   * Deletes a set of base DNs.  The code assumes that the server is running
460   * and that the provided connection is active.
461   * @param baseDNs the list of base DNs.
462   * @param ctx the connection to the server.
463   * @throws OpenDsException if an error occurs.
464   */
465  private void deleteBaseDNs(InitialLdapContext ctx,
466      Set<BaseDNDescriptor> baseDNs) throws OpenDsException
467  {
468    ManagementContext mCtx = LDAPManagementContext.createFromContext(
469        JNDIDirContextAdaptor.adapt(ctx));
470    RootCfgClient root = mCtx.getRootConfiguration();
471    LocalDBBackendCfgClient backend =
472      (LocalDBBackendCfgClient)root.getBackend(
473          baseDNs.iterator().next().getBackend().getBackendID());
474    SortedSet<DN> oldBaseDNs = backend.getBaseDN();
475    SortedSet<DN> newBaseDNs = new TreeSet<>(oldBaseDNs);
476    ArrayList<DN> dnsToRemove = new ArrayList<>();
477    for (BaseDNDescriptor baseDN : baseDNs)
478    {
479      dnsToRemove.add(baseDN.getDn());
480    }
481    newBaseDNs.removeAll(dnsToRemove);
482    backend.setBaseDN(newBaseDNs);
483    backend.commit();
484  }
485
486  /**
487   * Deletes a backend.  The code assumes that the server is not running
488   * and that the configuration file can be edited.
489   * @param backend the backend to be deleted.
490   * @throws OpenDsException if an error occurs.
491   */
492  private void deleteBackend(BackendDescriptor backend) throws OpenDsException, ConfigException
493  {
494    String dn = getDN(backend);
495    Utilities.deleteConfigSubtree(
496        DirectoryServer.getConfigHandler(), DN.valueOf(dn));
497  }
498
499  /**
500   * Deletes a backend.  The code assumes that the server is running
501   * and that the provided connection is active.
502   * @param backend the backend to be deleted.
503   * @param ctx the connection to the server.
504   * @throws OpenDsException if an error occurs.
505   */
506  private void deleteBackend(InitialLdapContext ctx,
507      BackendDescriptor backend) throws OpenDsException
508  {
509    ManagementContext mCtx = LDAPManagementContext.createFromContext(
510        JNDIDirContextAdaptor.adapt(ctx));
511    RootCfgClient root = mCtx.getRootConfiguration();
512    root.removeBackend(backend.getBackendID());
513    root.commit();
514  }
515
516  /** {@inheritDoc} */
517  protected String getCommandLinePath()
518  {
519    return null;
520  }
521
522  /** {@inheritDoc} */
523  protected ArrayList<String> getCommandLineArguments()
524  {
525    return new ArrayList<>();
526  }
527
528  /**
529   * Returns the path of the command line to be used.
530   *
531   * @return the path of the command line to be used
532   */
533  private String getConfigCommandLinePath()
534  {
535    if (isServerRunning())
536    {
537      return getCommandLinePath("dsconfig");
538    }
539    return null;
540  }
541
542  /** {@inheritDoc} */
543  public void runTask()
544  {
545    state = State.RUNNING;
546    lastException = null;
547
548    try
549    {
550      updateConfiguration();
551      state = State.FINISHED_SUCCESSFULLY;
552    }
553    catch (Throwable t)
554    {
555      lastException = t;
556      state = State.FINISHED_WITH_ERROR;
557    }
558  }
559
560  /**
561   * Return the dsconfig arguments required to delete a set of base DNs.
562   * @param baseDNs the base DNs to be deleted.
563   * @return the dsconfig arguments required to delete a set of base DNs.
564   */
565  private ArrayList<String> getDSConfigCommandLineArguments(
566      Set<BaseDNDescriptor> baseDNs)
567  {
568    ArrayList<String> args = new ArrayList<>();
569    if (isServerRunning())
570    {
571      args.add("set-backend-prop");
572      args.add("--backend-name");
573      args.add(baseDNs.iterator().next().getBackend().getBackendID());
574      args.add("--remove");
575      for (BaseDNDescriptor baseDN : baseDNs)
576      {
577        args.add("base-dn:" + baseDN.getDn());
578      }
579      args.addAll(getConnectionCommandLineArguments());
580      args.add("--no-prompt");
581    }
582    return args;
583  }
584
585  /**
586   * Return the dsconfig arguments required to delete a backend.
587   * @param backend the backend to be deleted.
588   * @return the dsconfig arguments required to delete a backend.
589   */
590  private ArrayList<String> getDSConfigCommandLineArguments(
591      BackendDescriptor backend)
592  {
593    ArrayList<String> args = new ArrayList<>();
594    args.add("delete-backend");
595    args.add("--backend-name");
596    args.add(backend.getBackendID());
597
598    args.addAll(getConnectionCommandLineArguments());
599    args.add("--no-prompt");
600    return args;
601  }
602
603  /**
604   * Disables replication if required: if the deleted base DN is replicated,
605   * update the replication configuration to remove any reference to it.
606   * @param baseDN the base DN that is going to be removed.
607   * @throws OpenDsException if an error occurs.
608   */
609  private void disableReplicationIfRequired(final BaseDNDescriptor baseDN)
610  throws OpenDsException, ConfigException
611  {
612    if (baseDN.getType() == BaseDNDescriptor.Type.REPLICATED)
613    {
614      final AtomicReference<String> domainName = new AtomicReference<>();
615
616      try
617      {
618        if (isServerRunning())
619        {
620          InitialLdapContext ctx = getInfo().getDirContext();
621          ManagementContext mCtx = LDAPManagementContext.createFromContext(
622              JNDIDirContextAdaptor.adapt(ctx));
623          RootCfgClient root = mCtx.getRootConfiguration();
624          ReplicationSynchronizationProviderCfgClient sync = null;
625          try
626          {
627            sync = (ReplicationSynchronizationProviderCfgClient)
628            root.getSynchronizationProvider("Multimaster Synchronization");
629          }
630          catch (OpenDsException oe)
631          {
632            // Ignore this one
633          }
634          if (sync != null)
635          {
636            String[] domains = sync.listReplicationDomains();
637            if (domains != null)
638            {
639              for (String dName : domains)
640              {
641                ReplicationDomainCfgClient domain = sync.getReplicationDomain(dName);
642                if (baseDN.getDn().equals(domain.getBaseDN()))
643                {
644                  domainName.set(dName);
645                  sync.removeReplicationDomain(dName);
646                  sync.commit();
647                  break;
648                }
649              }
650            }
651          }
652        }
653        else
654        {
655          RootCfg root =
656            ServerManagementContext.getInstance().getRootConfiguration();
657          ReplicationSynchronizationProviderCfg sync = null;
658          try
659          {
660            sync = (ReplicationSynchronizationProviderCfg)
661            root.getSynchronizationProvider("Multimaster Synchronization");
662          }
663          catch (ConfigException oe)
664          {
665            // Ignore this one
666          }
667          if (sync != null)
668          {
669            String[] domains = sync.listReplicationDomains();
670            if (domains != null)
671            {
672              for (String dName : domains)
673              {
674                ReplicationDomainCfg domain = sync.getReplicationDomain(dName);
675                DN dn = domain.getBaseDN();
676                if (dn.equals(baseDN.getDn()))
677                {
678                  domainName.set(dName);
679                  DN entryDN = domain.dn();
680                  Utilities.deleteConfigSubtree(
681                      DirectoryServer.getConfigHandler(), entryDN);
682                  break;
683                }
684              }
685            }
686          }
687        }
688      }
689      finally
690      {
691        // This is not super clean, but this way we calculate the domain name only once.
692        if (isServerRunning() && domainName.get() != null)
693        {
694          SwingUtilities.invokeLater(new Runnable()
695          {
696            public void run()
697            {
698              List<String> args =
699                getObfuscatedCommandLineArguments(
700                    getCommandLineArgumentsToDisableReplication(domainName.get()));
701              args.removeAll(getConfigCommandLineArguments());
702              args.add(getNoPropertiesFileArgument());
703              printEquivalentCommandLine(getConfigCommandLinePath(), args,
704                  INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_DELETE_DOMAIN.get(baseDN.getDn()));
705              }
706          });
707        }
708        SwingUtilities.invokeLater(new Runnable()
709        {
710          public void run()
711          {
712            getProgressDialog().appendProgressHtml(
713                Utilities.getProgressWithPoints(
714                    INFO_CTRL_PANEL_DELETING_DOMAIN.get(baseDN.getDn()),
715                    ColorAndFontConstants.progressFont));
716          }
717        });
718      }
719      SwingUtilities.invokeLater(new Runnable()
720      {
721        public void run()
722        {
723          getProgressDialog().appendProgressHtml(
724              Utilities.getProgressDone(ColorAndFontConstants.progressFont)+
725              "<br>");
726        }
727      });
728    }
729  }
730
731  /**
732   * Return the dsconfig arguments required to delete a replication domain.
733   * @param domainName the name of the domain to be deleted.
734   * @return the dsconfig arguments required to delete a replication domain.
735   */
736  private ArrayList<String> getCommandLineArgumentsToDisableReplication(
737      String domainName)
738  {
739    ArrayList<String> args = new ArrayList<>();
740    args.add("delete-replication-domain");
741    args.add("--provider-name");
742    args.add("Multimaster Synchronization");
743    args.add("--domain-name");
744    args.add(domainName);
745    args.addAll(getConnectionCommandLineArguments());
746    args.add("--no-prompt");
747    return args;
748  }
749}
750