NewBaseDNPanel.java revision 998747bfaaa3c6b28bbfaf0e282e6c0ccbf46bc0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
* or http://forgerock.org/license/CDDLv1.0.html.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at legal-notices/CDDLv1_0.txt.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2008-2009 Sun Microsystems, Inc.
* Portions Copyright 2011-2015 ForgeRock AS
*/
package org.opends.guitools.controlpanel.ui;
import static org.opends.messages.AdminToolMessages.*;
import static org.opends.messages.ConfigMessages.*;
import static org.opends.messages.QuickSetupMessages.*;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.ldap.InitialLdapContext;
import javax.swing.AbstractButton;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
import org.opends.guitools.controlpanel.datamodel.BaseDNDescriptor;
import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
import org.opends.guitools.controlpanel.datamodel.ServerDescriptor;
import org.opends.guitools.controlpanel.event.BrowseActionListener;
import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent;
import org.opends.guitools.controlpanel.task.OfflineUpdateException;
import org.opends.guitools.controlpanel.task.OnlineUpdateException;
import org.opends.guitools.controlpanel.task.Task;
import org.opends.guitools.controlpanel.ui.renderer.CustomListCellRenderer;
import org.opends.guitools.controlpanel.util.ConfigReader;
import org.opends.guitools.controlpanel.util.Utilities;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.config.server.ConfigException;
import org.opends.quicksetup.Installation;
import org.opends.quicksetup.installer.InstallerHelper;
import org.opends.quicksetup.util.Utils;
import org.opends.server.admin.client.ManagementContext;
import org.opends.server.admin.client.ldap.JNDIDirContextAdaptor;
import org.opends.server.admin.client.ldap.LDAPManagementContext;
import org.opends.server.admin.std.client.LocalDBBackendCfgClient;
import org.opends.server.admin.std.client.RootCfgClient;
import org.opends.server.admin.std.meta.BackendCfgDefn;
import org.opends.server.admin.std.meta.LocalDBBackendCfgDefn;
import org.opends.server.config.ConfigConstants;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.DNConfigAttribute;
import org.opends.server.core.DirectoryServer;
import org.opends.server.tools.ImportLDIF;
import org.opends.server.tools.LDAPModify;
import org.opends.server.tools.makeldif.MakeLDIF;
import org.forgerock.opendj.ldap.ByteString;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.OpenDsException;
import org.opends.server.util.LDIFReader;
import org.opends.server.util.SetupUtils;
import com.forgerock.opendj.cli.CommandBuilder;
/**
* The class that appears when the user clicks on 'New Base DN'.
*
*/
public class NewBaseDNPanel extends StatusGenericPanel
{
private static final long serialVersionUID = -2680821576362341119L;
private JComboBox backends;
private JTextField newBackend;
private JTextField baseDN;
private JRadioButton onlyCreateBaseEntry;
private JRadioButton leaveDatabaseEmpty;
private JRadioButton importDataFromLDIF;
private JRadioButton importAutomaticallyGenerated;
private JTextField path;
private JTextField numberOfEntries;
private JLabel lRemoteFileHelp;
private JButton browseImportPath;
private JLabel lBackend;
private JLabel lDirectoryBaseDN;
private JLabel lPath;
private JLabel lNumberOfEntries;
private JLabel lDirectoryData;
private DocumentListener documentListener;
private final LocalizableMessage NEW_BACKEND = INFO_CTRL_PANEL_NEW_BACKEND_LABEL.get();
/**
* The default constructor.
*
*/
public NewBaseDNPanel()
{
super();
createLayout();
}
/**
* {@inheritDoc}
*/
public LocalizableMessage getTitle()
{
return INFO_CTRL_PANEL_NEW_BASE_DN_TITLE.get();
}
/**
* {@inheritDoc}
*/
public Component getPreferredFocusComponent()
{
return baseDN;
}
/**
* {@inheritDoc}
*/
public void toBeDisplayed(boolean visible)
{
if (visible)
{
documentListener.changedUpdate(null);
}
}
/**
* Creates the layout of the panel (but the contents are not populated here).
*/
private void createLayout()
{
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 3;
addErrorPane(gbc);
gbc.anchor = GridBagConstraints.WEST;
gbc.weightx = 0.0;
gbc.gridwidth = 1;
gbc.gridy ++;
gbc.fill = GridBagConstraints.NONE;
lBackend = Utilities.createPrimaryLabel(
INFO_CTRL_PANEL_BACKEND_LABEL.get());
add(lBackend, gbc);
gbc.insets.left = 10;
gbc.gridx = 1;
backends = Utilities.createComboBox();
backends.setModel(new DefaultComboBoxModel(new Object[]{"bogus",
NEW_BACKEND}));
backends.setRenderer(new CustomListCellRenderer(backends));
backends.addItemListener(new IgnoreItemListener(backends));
gbc.gridwidth = 1;
add(backends, gbc);
newBackend = Utilities.createTextField();
newBackend.setColumns(25);
gbc.gridx = 2;
add(newBackend, gbc);
ItemListener comboListener = new ItemListener()
{
/**
* {@inheritDoc}
*/
public void itemStateChanged(ItemEvent ev)
{
Object o = backends.getSelectedItem();
newBackend.setEnabled(NEW_BACKEND.equals(o));
}
};
backends.addItemListener(comboListener);
comboListener.itemStateChanged(null);
gbc.insets.top = 10;
gbc.gridx = 0;
gbc.gridy ++;
gbc.insets.left = 0;
gbc.gridwidth = 1;
lDirectoryBaseDN =
Utilities.createPrimaryLabel(INFO_CTRL_PANEL_BASE_DN_LABEL.get());
add(lDirectoryBaseDN, gbc);
gbc.gridx = 1;
gbc.insets.left = 10;
gbc.gridwidth = 2;
baseDN = Utilities.createTextField();
documentListener = new DocumentListener()
{
/**
* {@inheritDoc}
*/
public void changedUpdate(DocumentEvent ev)
{
String text = baseDN.getText().trim();
setEnabledOK((text != null) && (text.length() > 0) &&
!errorPane.isVisible());
}
/**
* {@inheritDoc}
*/
public void removeUpdate(DocumentEvent ev)
{
changedUpdate(ev);
}
/**
* {@inheritDoc}
*/
public void insertUpdate(DocumentEvent ev)
{
changedUpdate(ev);
}
};
baseDN.getDocument().addDocumentListener(documentListener);
gbc.weightx = 1.0;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(baseDN, gbc);
gbc.gridy ++;
gbc.anchor = GridBagConstraints.EAST;
gbc.insets.top = 3;
JLabel inlineHelp =
Utilities.createInlineHelpLabel(INFO_CTRL_PANEL_BASE_DN_EXAMPLE.get());
add(inlineHelp, gbc);
gbc.gridx = 0;
gbc.gridy ++;
gbc.insets.left = 0;
gbc.insets.top = 10;
gbc.gridwidth = 1;
gbc.weightx = 0.0;
lDirectoryData = Utilities.createPrimaryLabel(
INFO_CTRL_PANEL_DIRECTORY_DATA_LABEL.get());
add(lDirectoryData, gbc);
onlyCreateBaseEntry = Utilities.createRadioButton(
INFO_CTRL_PANEL_ONLY_CREATE_BASE_ENTRY_LABEL.get());
onlyCreateBaseEntry.setSelected(false);
gbc.insets.left = 10;
gbc.gridx = 1;
gbc.gridwidth = 2;
add(onlyCreateBaseEntry, gbc);
leaveDatabaseEmpty = Utilities.createRadioButton(
INFO_CTRL_PANEL_LEAVE_DATABASE_EMPTY_LABEL.get());
leaveDatabaseEmpty.setSelected(false);
gbc.gridy ++;
gbc.gridwidth = 2;
gbc.insets.top = 5;
add(leaveDatabaseEmpty, gbc);
importDataFromLDIF = Utilities.createRadioButton(
INFO_CTRL_PANEL_IMPORT_FROM_LDIF_LABEL.get());
importDataFromLDIF.setSelected(false);
gbc.gridy ++;
gbc.gridwidth = 2;
add(importDataFromLDIF, gbc);
gbc.gridy ++;
gbc.gridwidth = 2;
gbc.insets.left = 30;
add(createPathPanel(), gbc);
importAutomaticallyGenerated = Utilities.createRadioButton(
INFO_CTRL_PANEL_IMPORT_AUTOMATICALLY_GENERATED_LABEL.get());
importAutomaticallyGenerated.setOpaque(false);
importAutomaticallyGenerated.setSelected(false);
gbc.gridy ++;
gbc.gridwidth = 2;
gbc.insets.left = 10;
add(importAutomaticallyGenerated, gbc);
gbc.gridy ++;
gbc.gridwidth = 2;
gbc.insets.left = 30;
add(createNumberOfUsersPanel(), gbc);
ButtonGroup group = new ButtonGroup();
group.add(onlyCreateBaseEntry);
group.add(leaveDatabaseEmpty);
group.add(importDataFromLDIF);
group.add(importAutomaticallyGenerated);
ChangeListener listener = new ChangeListener()
{
/**
* {@inheritDoc}
*/
public void stateChanged(ChangeEvent ev)
{
browseImportPath.setEnabled(importDataFromLDIF.isSelected());
lPath.setEnabled(importDataFromLDIF.isSelected());
lRemoteFileHelp.setEnabled(importDataFromLDIF.isSelected());
numberOfEntries.setEnabled(importAutomaticallyGenerated.isSelected());
lNumberOfEntries.setEnabled(importAutomaticallyGenerated.isSelected());
}
};
Enumeration<AbstractButton> buttons = group.getElements();
while (buttons.hasMoreElements())
{
buttons.nextElement().addChangeListener(listener);
}
onlyCreateBaseEntry.setSelected(true);
listener.stateChanged(null);
addBottomGlue(gbc);
}
/**
* {@inheritDoc}
*/
public void configurationChanged(ConfigurationChangeEvent ev)
{
ServerDescriptor desc = ev.getNewDescriptor();
final SortedSet<String> sortedBackends = new TreeSet<String>();
for (BackendDescriptor backend : desc.getBackends())
{
if (!backend.isConfigBackend())
{
sortedBackends.add(backend.getBackendID());
}
}
ArrayList<Object> newElements = new ArrayList<Object>(sortedBackends);
if (sortedBackends.size() > 0)
{
newElements.add(COMBO_SEPARATOR);
}
newElements.add(NEW_BACKEND);
super.updateComboBoxModel(newElements,
((DefaultComboBoxModel)backends.getModel()));
updateErrorPaneAndOKButtonIfAuthRequired(desc,
isLocal() ?
INFO_CTRL_PANEL_AUTHENTICATION_REQUIRED_FOR_CREATE_BASE_DN.get() :
INFO_CTRL_PANEL_CANNOT_CONNECT_TO_REMOTE_DETAILS.get(desc.getHostname()));
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
lRemoteFileHelp.setVisible(!isLocal());
browseImportPath.setVisible(isLocal());
}
});
}
private JPanel createPathPanel()
{
JPanel panel = new JPanel(new GridBagLayout());
panel.setOpaque(false);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = 1;
gbc.gridy = 0;
gbc.gridx = 0;
lPath = Utilities.createDefaultLabel(
INFO_CTRL_PANEL_IMPORT_LDIF_PATH_LABEL.get());
panel.add(lPath, gbc);
gbc.gridx = 1;
gbc.insets.left = 10;
path = Utilities.createTextField();
gbc.weightx = 1.0;
gbc.fill = GridBagConstraints.HORIZONTAL;
panel.add(path, gbc);
browseImportPath =
Utilities.createButton(INFO_CTRL_PANEL_BROWSE_BUTTON_LABEL.get());
browseImportPath.addActionListener(
new BrowseActionListener(path,
BrowseActionListener.BrowseType.OPEN_LDIF_FILE, this));
gbc.gridx = 2;
gbc.weightx = 0.0;
panel.add(browseImportPath, gbc);
gbc.gridy ++;
gbc.gridx = 1;
lRemoteFileHelp = Utilities.createInlineHelpLabel(
INFO_CTRL_PANEL_REMOTE_SERVER_PATH.get());
gbc.insets.top = 3;
gbc.insets.left = 10;
panel.add(lRemoteFileHelp, gbc);
return panel;
}
private JPanel createNumberOfUsersPanel()
{
JPanel panel = new JPanel(new GridBagLayout());
panel.setOpaque(false);
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 0.0;
gbc.fill = GridBagConstraints.HORIZONTAL;
lNumberOfEntries = Utilities.createDefaultLabel(
INFO_CTRL_PANEL_NUMBER_OF_USER_ENTRIES_LABEL.get());
panel.add(lNumberOfEntries, gbc);
gbc.gridx = 1;
gbc.insets.left = 10;
numberOfEntries = Utilities.createTextField("2000", 6);
panel.add(numberOfEntries, gbc);
gbc.gridx = 2;
gbc.insets.left = 0;
gbc.weightx = 1.0;
panel.add(Box.createHorizontalGlue(), gbc);
return panel;
}
/**
* {@inheritDoc}
*/
public void cancelClicked()
{
setPrimaryValid(lBackend);
setPrimaryValid(lDirectoryBaseDN);
setPrimaryValid(lDirectoryData);
setSecondaryValid(lPath);
setSecondaryValid(lNumberOfEntries);
super.cancelClicked();
}
/**
* {@inheritDoc}
*/
protected void checkOKButtonEnable()
{
documentListener.changedUpdate(null);
}
/**
* {@inheritDoc}
*/
public void okClicked()
{
setPrimaryValid(lBackend);
setPrimaryValid(lDirectoryBaseDN);
setPrimaryValid(lDirectoryData);
setSecondaryValid(lPath);
setSecondaryValid(lNumberOfEntries);
final LinkedHashSet<LocalizableMessage> errors = new LinkedHashSet<LocalizableMessage>();
ServerDescriptor desc = getInfo().getServerDescriptor();
Set<BackendDescriptor> backendObjects = desc.getBackends();
Object o = backends.getSelectedItem();
String backendName = String.valueOf(o);
if (o == null)
{
errors.add(ERR_CTRL_PANEL_NO_BACKENDS_SELECTED.get());
setPrimaryInvalid(lBackend);
}
else if (o.equals(NEW_BACKEND))
{
backendName = newBackend.getText().trim();
if (backendName.length() == 0)
{
errors.add(ERR_NEW_BACKEND_NAME_REQUIRED.get());
setPrimaryInvalid(lBackend);
}
else
{
// Check that the backend is not already defined.
for (BackendDescriptor backend : backendObjects)
{
if (backendName.equalsIgnoreCase(backend.getBackendID()))
{
errors.add(ERR_BACKEND_ALREADY_EXISTS.get(backendName));
setPrimaryInvalid(lBackend);
break;
}
}
}
}
String dn = baseDN.getText();
if (dn.trim().length() == 0)
{
errors.add(ERR_NEW_BASE_DN_VALUE_REQUIRED.get());
setPrimaryInvalid(lDirectoryBaseDN);
}
else
{
try
{
DN theDN = DN.valueOf(dn);
// Check that the DN is not defined.
boolean baseDNAlreadyDefined = false;
for (BackendDescriptor backend : backendObjects)
{
for (BaseDNDescriptor baseDN : backend.getBaseDns())
{
if (baseDN.getDn().equals(theDN))
{
errors.add(ERR_BASE_DN_ALREADY_EXISTS.get(dn));
setPrimaryInvalid(lDirectoryBaseDN);
baseDNAlreadyDefined = true;
break;
}
else if (baseDN.getDn().isAncestorOf(theDN))
{
if (backendName.equalsIgnoreCase(backend.getBackendID()))
{
errors.add(ERR_BASE_DN_ANCESTOR_EXISTS.get(baseDN.getDn()));
setPrimaryInvalid(lDirectoryBaseDN);
baseDNAlreadyDefined = true;
break;
}
}
else if (theDN.isAncestorOf(baseDN.getDn()))
{
if (backendName.equalsIgnoreCase(backend.getBackendID()))
{
errors.add(ERR_BASE_DN_DN_IS_ANCESTOR_OF.get(baseDN.getDn()));
setPrimaryInvalid(lDirectoryBaseDN);
baseDNAlreadyDefined = true;
break;
}
}
}
if (baseDNAlreadyDefined)
{
break;
}
}
}
catch (OpenDsException oe)
{
errors.add(INFO_CTRL_PANEL_INVALID_DN_DETAILS.get(dn, oe.getMessageObject()));
setPrimaryInvalid(lDirectoryBaseDN);
}
}
// TODO: what happens with sub-suffixes?
if (importDataFromLDIF.isSelected())
{
String ldifPath = path.getText();
if ((ldifPath == null) || (ldifPath.trim().equals("")))
{
errors.add(INFO_NO_LDIF_PATH.get());
setSecondaryInvalid(lPath);
} else if (isLocal() && !Utils.fileExists(ldifPath))
{
errors.add(INFO_LDIF_FILE_DOES_NOT_EXIST.get());
setSecondaryInvalid(lPath);
}
}
if (importAutomaticallyGenerated.isSelected())
{
String nEntries = numberOfEntries.getText();
int minValue = 1;
int maxValue = isLocal() ? 20000 : 1000;
LocalizableMessage errMsg = ERR_NUMBER_OF_ENTRIES_INVALID.get(minValue, maxValue);
checkIntValue(errors, nEntries, minValue, maxValue, errMsg);
}
if (errors.isEmpty())
{
ProgressDialog progressDialog = new ProgressDialog(
Utilities.createFrame(), Utilities.getParentDialog(this), getTitle(),
getInfo());
NewBaseDNTask newTask = new NewBaseDNTask(getInfo(), progressDialog);
for (Task task : getInfo().getTasks())
{
task.canLaunch(newTask, errors);
}
if (errors.isEmpty())
{
launchOperation(newTask,
INFO_CTRL_PANEL_CREATING_BASE_DN_SUMMARY.get(dn),
INFO_CTRL_PANEL_CREATING_BASE_DN_COMPLETE.get(),
INFO_CTRL_PANEL_CREATING_BASE_DN_SUCCESSFUL.get(dn),
ERR_CTRL_PANEL_CREATING_BASE_DN_ERROR_SUMMARY.get(dn),
null,
ERR_CTRL_PANEL_CREATING_BASE_DN_ERROR_DETAILS,
progressDialog);
progressDialog.setVisible(true);
baseDN.setText("");
baseDN.grabFocus();
Utilities.getParentDialog(this).setVisible(false);
}
}
if (errors.size() > 0)
{
displayErrorDialog(errors);
}
}
private String getBackendName()
{
Object backendName = backends.getSelectedItem();
if (NEW_BACKEND.equals(backendName))
{
return newBackend.getText().trim();
}
else if (backendName != null)
{
return backendName.toString();
}
else
{
return null;
}
}
private boolean isNewBackend()
{
return NEW_BACKEND.equals(backends.getSelectedItem());
}
/**
* The task in charge of creating the base DN (and if required, the backend).
*
*/
protected class NewBaseDNTask extends Task
{
Set<String> backendSet;
private String newBaseDN;
private int progressAfterConfigurationUpdate = -1;
/**
* The constructor of the task.
* @param info the control panel info.
* @param dlg the progress dialog that shows the progress of the task.
*/
public NewBaseDNTask(ControlPanelInfo info, ProgressDialog dlg)
{
super(info, dlg);
backendSet = new HashSet<String>();
backendSet.add(getBackendName());
newBaseDN = baseDN.getText();
if (onlyCreateBaseEntry.isSelected())
{
progressAfterConfigurationUpdate = 40;
}
else if (leaveDatabaseEmpty.isSelected())
{
progressAfterConfigurationUpdate = 90;
}
else if (importAutomaticallyGenerated.isSelected())
{
int nEntries = Integer.parseInt(numberOfEntries.getText().trim());
if (nEntries < 500)
{
progressAfterConfigurationUpdate = 30;
}
else if (nEntries < 3000)
{
progressAfterConfigurationUpdate = 15;
}
else
{
progressAfterConfigurationUpdate = 5;
}
}
}
/**
* {@inheritDoc}
*/
public Type getType()
{
return Type.NEW_BASEDN;
}
/**
* {@inheritDoc}
*/
public LocalizableMessage getTaskDescription()
{
return INFO_CTRL_PANEL_NEW_BASE_DN_TASK_DESCRIPTION.get(newBaseDN,
backendSet.iterator().next());
}
/**
* {@inheritDoc}
*/
public boolean canLaunch(Task taskToBeLaunched,
Collection<LocalizableMessage> incompatibilityReasons)
{
boolean canLaunch = true;
if (state == State.RUNNING && runningOnSameServer(taskToBeLaunched))
{
// All the operations are incompatible if they apply to this
// backend.
Set<String> backends =
new TreeSet<String>(taskToBeLaunched.getBackends());
backends.retainAll(getBackends());
if (backends.size() > 0)
{
incompatibilityReasons.add(getIncompatibilityMessage(this,
taskToBeLaunched));
canLaunch = false;
}
}
return canLaunch;
}
/**
* Returns the equivalent command-line to generate the data.
* @return the equivalent command-line to generate the data.
*/
private String getDataCommandLineToDisplay()
{
StringBuilder sb = new StringBuilder();
sb.append(getDataCommandLineName());
Collection<String> args = getObfuscatedCommandLineArguments(
getDataCommandLineArguments(path.getText(), false));
args.removeAll(getConfigCommandLineArguments());
for (String arg : args)
{
sb.append(" ").append(CommandBuilder.escapeValue(arg));
}
return sb.toString();
}
/**
* Returns the path of the command-line to be used to generate the data.
* @return the path of the command-line to be used to generate the data.
*/
private String getDataCommandLineName()
{
String cmdLineName;
if (!leaveDatabaseEmpty.isSelected())
{
if (isLocal())
{
cmdLineName = getCommandLinePath("import-ldif");
}
else
{
cmdLineName = getCommandLinePath("ldapmodify");
}
}
else
{
cmdLineName = null;
}
return cmdLineName;
}
/**
* Returns the arguments of the command-line that can be used to generate
* the data.
* @param ldifFile the LDIF file.
* @param useTemplate whether to use a template or not.
* @return the arguments of the command-line that can be used to generate
* the data.
*/
private ArrayList<String> getDataCommandLineArguments(String ldifFile,
boolean useTemplate)
{
ArrayList<String> args = new ArrayList<String>();
if (!leaveDatabaseEmpty.isSelected())
{
if (isLocal())
{
if (!useTemplate)
{
args.add("--ldifFile");
args.add(ldifFile);
}
else
{
args.add("--templateFile");
args.add(ldifFile);
args.add("--randomSeed");
args.add("0");
}
args.add("--backendID");
args.add(getBackendName());
args.add("--append");
}
else
{
// If we are not local, we use ldapmodify to update the contents.
args.add("-a");
args.add("-f");
args.add(ldifFile);
}
args.addAll(getConnectionCommandLineArguments(true, !isLocal()));
if (isServerRunning() && isLocal())
{
args.addAll(getConfigCommandLineArguments());
}
args.add(getNoPropertiesFileArgument());
}
return args;
}
private void updateConfiguration() throws OpenDsException, ConfigException
{
boolean configHandlerUpdated = false;
try
{
if (!isServerRunning())
{
getInfo().stopPooling();
if (getInfo().mustDeregisterConfig())
{
DirectoryServer.deregisterBaseDN(DN.valueOf("cn=config"));
}
DirectoryServer.getInstance().initializeConfiguration(
org.opends.server.extensions.ConfigFileHandler.class.getName(),
ConfigReader.configFile);
getInfo().setMustDeregisterConfig(true);
configHandlerUpdated = true;
}
else
{
SwingUtilities.invokeLater(new Runnable()
{
/**
* {@inheritDoc}
*/
public void run()
{
List<String> args =
getObfuscatedCommandLineArguments(
getDSConfigCommandLineArguments());
args.removeAll(getConfigCommandLineArguments());
printEquivalentCommandLine(getConfigCommandLineFullPath(),
args, INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_CREATE_BASE_DN.get());
}
});
}
if (isNewBackend())
{
SwingUtilities.invokeLater(new Runnable()
{
/**
* {@inheritDoc}
*/
public void run()
{
LocalizableMessage msg = INFO_CTRL_PANEL_CREATING_BACKEND_PROGRESS.get(
getBackendName(), newBaseDN);
getProgressDialog().appendProgressHtml(
Utilities.getProgressWithPoints(msg,
ColorAndFontConstants.progressFont));
}
});
if (isServerRunning())
{
createBackend(getInfo().getDirContext(), getBackendName(),
newBaseDN);
}
else
{
createBackend(getBackendName(), newBaseDN);
createAdditionalIndexes(getBackendName());
}
}
else
{
SwingUtilities.invokeLater(new Runnable()
{
/**
* {@inheritDoc}
*/
public void run()
{
LocalizableMessage msg = INFO_CTRL_PANEL_CREATING_BASE_DN_PROGRESS.get(
newBaseDN, getBackendName());
getProgressDialog().appendProgressHtml(
Utilities.getProgressWithPoints(msg,
ColorAndFontConstants.progressFont));
}
});
if (isServerRunning())
{
addBaseDN(getInfo().getDirContext(), getBackendName(), newBaseDN);
}
else
{
addBaseDN(getBackendName(), newBaseDN);
}
}
SwingUtilities.invokeLater(new Runnable()
{
/**
* {@inheritDoc}
*/
public void run()
{
getProgressDialog().appendProgressHtml(
Utilities.getProgressDone(ColorAndFontConstants.progressFont)+
"<br><br>");
}
});
if (isNewBackend() && isServerRunning())
{
// Create additional indexes and display the equivalent command.
// Everything is done in the method createAdditionalIndexes
createAdditionalIndexes(getInfo().getDirContext(), getBackendName());
}
if (progressAfterConfigurationUpdate > 0)
{
SwingUtilities.invokeLater(new Runnable()
{
/**
* {@inheritDoc}
*/
public void run()
{
getProgressDialog().getProgressBar().setIndeterminate(false);
getProgressDialog().getProgressBar().setValue(
progressAfterConfigurationUpdate);
}
});
}
}
finally
{
if (configHandlerUpdated)
{
DirectoryServer.getInstance().initializeConfiguration(
ConfigReader.configClassName, ConfigReader.configFile);
getInfo().startPooling();
}
}
}
/**
* Creates the data in the new base DN.
* @throws OpenDsException if there is an error importing contents.
* @throws IOException if there is an err
*/
private void updateData() throws OpenDsException, IOException
{
final boolean leaveEmpty = leaveDatabaseEmpty.isSelected();
final boolean createBaseEntry = onlyCreateBaseEntry.isSelected();
final boolean importLDIF = importDataFromLDIF.isSelected();
final boolean generateData = !leaveEmpty && !createBaseEntry &&
!importLDIF;
final String nEntries = numberOfEntries.getText();
final String ldif = path.getText();
if (leaveEmpty)
{
state = State.FINISHED_SUCCESSFULLY;
}
else
{
final ProgressDialog progressDialog = getProgressDialog();
String ldifFile;
if (importLDIF)
{
ldifFile = ldif;
final String cmdLine = getDataCommandLineToDisplay();
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
progressDialog.appendProgressHtml(Utilities.applyFont(
"Equivalent command line:<br><b>"+cmdLine+"</b><br><br>",
ColorAndFontConstants.progressFont));
}
});
}
else if (createBaseEntry)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
progressDialog.appendProgressHtml(Utilities.getProgressWithPoints(
INFO_PROGRESS_CREATING_BASE_ENTRY.get(newBaseDN),
ColorAndFontConstants.progressFont));
}
});
InstallerHelper helper = new InstallerHelper();
File f = helper.createBaseEntryTempFile(newBaseDN);
ldifFile = f.getAbsolutePath();
}
else
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
if (isLocal())
{
progressDialog.appendProgressHtml(Utilities.applyFont(
INFO_PROGRESS_IMPORT_AUTOMATICALLY_GENERATED.get(nEntries).
toString(), ColorAndFontConstants.progressFont)+"<br>");
}
else
{
getProgressDialog().appendProgressHtml(
Utilities.getProgressWithPoints(
INFO_PROGRESS_IMPORT_AUTOMATICALLY_GENERATED_REMOTE.get(nEntries),
ColorAndFontConstants.progressFont));
}
}
});
File f = SetupUtils.createTemplateFile(newBaseDN,
Integer.parseInt(nEntries));
if (!isLocal())
{
File tempFile = File.createTempFile("opendj-control-panel",
".ldif");
tempFile.deleteOnExit();
ldifFile = tempFile.getAbsolutePath();
// Create the LDIF file locally using make-ldif
ArrayList<String> makeLDIFArgs = new ArrayList<String>();
makeLDIFArgs.add("--templateFile");
makeLDIFArgs.add(f.getAbsolutePath());
makeLDIFArgs.add("--ldifFile");
makeLDIFArgs.add(ldifFile);
makeLDIFArgs.add("--randomSeed");
makeLDIFArgs.add("0");
makeLDIFArgs.add("--resourcePath");
File makeLDIFPath =
new File(Installation.getLocal().getConfigurationDirectory(),
"MakeLDIF");
makeLDIFArgs.add(makeLDIFPath.getAbsolutePath());
makeLDIFArgs.addAll(getConfigCommandLineArguments());
MakeLDIF makeLDIF = new MakeLDIF();
String[] array = new String[makeLDIFArgs.size()];
makeLDIFArgs.toArray(array);
returnCode = makeLDIF.makeLDIFMain(array, false, false,
outPrintStream, errorPrintStream);
f.delete();
if (returnCode != 0)
{
throw new OnlineUpdateException(
ERR_CTRL_PANEL_ERROR_CREATING_NEW_DATA_LDIF.get(returnCode),
null);
}
}
else
{
ldifFile = f.getAbsolutePath();
}
}
ArrayList<String> arguments = getDataCommandLineArguments(ldifFile,
generateData);
String[] args = new String[arguments.size()];
arguments.toArray(args);
if (createBaseEntry || !isLocal())
{
outPrintStream.setNotifyListeners(false);
errorPrintStream.setNotifyListeners(false);
}
try
{
if (isServerRunning())
{
if (isLocal() || importLDIF)
{
returnCode = ImportLDIF.mainImportLDIF(args, false,
outPrintStream,
errorPrintStream);
}
else
{
returnCode = LDAPModify.mainModify(args, false,
outPrintStream,
errorPrintStream);
}
}
else
{
returnCode = executeCommandLine(getDataCommandLineName(), args);
}
}
finally
{
{
outPrintStream.setNotifyListeners(true);
errorPrintStream.setNotifyListeners(true);
}
}
if (returnCode != 0)
{
state = State.FINISHED_WITH_ERROR;
}
else
{
if (createBaseEntry || (!isLocal() && generateData))
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
progressDialog.appendProgressHtml(
Utilities.getProgressDone(
ColorAndFontConstants.progressFont));
}
});
}
state = State.FINISHED_SUCCESSFULLY;
}
}
}
private void createBackend(InitialLdapContext ctx, String backendName,
String baseDN) throws OpenDsException
{
ManagementContext mCtx = LDAPManagementContext.createFromContext(
JNDIDirContextAdaptor.adapt(ctx));
RootCfgClient root = mCtx.getRootConfiguration();
LocalDBBackendCfgDefn provider = LocalDBBackendCfgDefn.getInstance();
LocalDBBackendCfgClient backend = root.createBackend(provider,
backendName, null);
backend.setEnabled(true);
Set<DN> baseDNs = new HashSet<DN>();
baseDNs.add(DN.valueOf(baseDN));
backend.setBaseDN(baseDNs);
backend.setBackendId(backendName);
backend.setWritabilityMode(BackendCfgDefn.WritabilityMode.ENABLED);
backend.commit();
}
private String getBackendLdif(String backendName)
{
String dn = Utilities.getRDNString("ds-cfg-backend-id", backendName)+
",cn=Backends,cn=config";
return Utilities.makeLdif(
"dn: "+dn,
"objectClass: top",
"objectClass: ds-cfg-backend",
"objectClass: ds-cfg-local-db-backend",
"ds-cfg-base-dn: "+newBaseDN,
"ds-cfg-enabled: true",
"ds-cfg-writability-mode: enabled",
"ds-cfg-java-class: " +
org.opends.server.backends.jeb.BackendImpl.class.getName(),
"ds-cfg-backend-id: " + backendName,
"ds-cfg-db-directory: db",
"",
"dn: cn=Index,"+dn,
"objectClass: top",
"objectClass: ds-cfg-branch",
"cn: Index",
"",
"dn: ds-cfg-attribute=aci,cn=Index,"+dn,
"objectClass: ds-cfg-local-db-index",
"objectClass: top",
"ds-cfg-attribute: aci",
"ds-cfg-index-type: presence",
"",
"dn: ds-cfg-attribute=ds-sync-hist,cn=Index,"+dn,
"objectClass: ds-cfg-local-db-index",
"objectClass: top",
"ds-cfg-attribute: ds-sync-hist",
"ds-cfg-index-type: ordering",
"",
"dn: ds-cfg-attribute=entryUUID,cn=Index,"+dn,
"objectClass: ds-cfg-local-db-index",
"objectClass: top",
"ds-cfg-attribute: entryUUID",
"ds-cfg-index-type: equality",
"",
"dn: ds-cfg-attribute=objectClass,cn=Index,"+dn,
"objectClass: ds-cfg-local-db-index",
"objectClass: top",
"ds-cfg-attribute: objectClass",
"ds-cfg-index-type: equality"
);
}
private String getAdditionalIndexLdif(String backendName)
{
String dn = "ds-cfg-backend-id="+backendName+",cn=Backends,cn=config";
return Utilities.makeLdif(
"dn: ds-cfg-attribute=cn,cn=Index,"+dn,
"objectClass: ds-cfg-local-db-index",
"objectClass: top",
"ds-cfg-attribute: cn",
"ds-cfg-index-type: equality",
"ds-cfg-index-type: substring",
"",
"dn: ds-cfg-attribute=givenName,cn=Index,"+dn,
"objectClass: ds-cfg-local-db-index",
"objectClass: top",
"ds-cfg-attribute: givenName",
"ds-cfg-index-type: equality",
"ds-cfg-index-type: substring",
"",
"dn: ds-cfg-attribute=mail,cn=Index,"+dn,
"objectClass: ds-cfg-local-db-index",
"objectClass: top",
"ds-cfg-attribute: mail",
"ds-cfg-index-type: equality",
"ds-cfg-index-type: substring",
"",
"dn: ds-cfg-attribute=member,cn=Index,"+dn,
"objectClass: ds-cfg-local-db-index",
"objectClass: top",
"ds-cfg-attribute: member",
"ds-cfg-index-type: equality",
"",
"dn: ds-cfg-attribute=sn,cn=Index,"+dn,
"objectClass: ds-cfg-local-db-index",
"objectClass: top",
"ds-cfg-attribute: sn",
"ds-cfg-index-type: equality",
"ds-cfg-index-type: substring",
"",
"dn: ds-cfg-attribute=telephoneNumber,cn=Index,"+dn,
"objectClass: ds-cfg-local-db-index",
"objectClass: top",
"ds-cfg-attribute: telephoneNumber",
"ds-cfg-index-type: equality",
"ds-cfg-index-type: substring",
"",
"dn: ds-cfg-attribute=uid,cn=Index,"+dn,
"objectClass: ds-cfg-local-db-index",
"objectClass: top",
"ds-cfg-attribute: uid",
"ds-cfg-index-type: equality",
"",
"dn: ds-cfg-attribute=uniqueMember,cn=Index,"+dn,
"objectClass: ds-cfg-local-db-index",
"objectClass: top",
"ds-cfg-attribute: uniqueMember",
"ds-cfg-index-type: equality"
);
}
private void createBackend(String backendName, String baseDN)
throws OpenDsException
{
LDIFImportConfig ldifImportConfig = null;
try
{
String ldif = getBackendLdif(backendName);
ldifImportConfig = new LDIFImportConfig(new StringReader(ldif));
LDIFReader reader = new LDIFReader(ldifImportConfig);
Entry backendConfigEntry;
while ((backendConfigEntry = reader.readEntry()) != null)
{
DirectoryServer.getConfigHandler().addEntry(backendConfigEntry, null);
}
DirectoryServer.getConfigHandler().writeUpdatedConfig();
}
catch (IOException ioe)
{
throw new OfflineUpdateException(
ERR_CTRL_PANEL_ERROR_UPDATING_CONFIGURATION.get(ioe), ioe);
}
finally
{
if (ldifImportConfig != null)
{
ldifImportConfig.close();
}
}
}
private void createAdditionalIndexes(String backendName)
throws OpenDsException
{
LDIFImportConfig ldifImportConfig = null;
try
{
String ldif = getAdditionalIndexLdif(backendName);
ldifImportConfig = new LDIFImportConfig(new StringReader(ldif));
LDIFReader reader = new LDIFReader(ldifImportConfig);
Entry indexEntry;
while ((indexEntry = reader.readEntry()) != null)
{
DirectoryServer.getConfigHandler().addEntry(indexEntry, null);
}
DirectoryServer.getConfigHandler().writeUpdatedConfig();
}
catch (IOException ioe)
{
throw new OfflineUpdateException(
ERR_CTRL_PANEL_ERROR_UPDATING_CONFIGURATION.get(ioe), ioe);
}
finally
{
if (ldifImportConfig != null)
{
ldifImportConfig.close();
}
}
}
private void createAdditionalIndexes(InitialLdapContext ctx,
String backendName) throws OpenDsException
{
ArrayList<ArrayList<String>> argsArray =
new ArrayList<ArrayList<String>>();
ArrayList<String> dns = new ArrayList<String>();
ArrayList<Attributes> attributes = new ArrayList<Attributes>();
// Instead of adding indexes using management framework, use this approach
// so that we have to define the additional indexes only in the method
// getBackendLdif.
String ldif = getAdditionalIndexLdif(backendName);
LDIFImportConfig ldifImportConfig = null;
try
{
ldifImportConfig = new LDIFImportConfig(new StringReader(ldif));
LDIFReader reader = new LDIFReader(ldifImportConfig);
Entry indexEntry;
while ((indexEntry = reader.readEntry()) != null)
{
ArrayList<String> args = new ArrayList<String>();
args.add("create-local-db-index");
args.add("--backend-name");
args.add(backendName);
args.add("--type");
args.add("generic");
argsArray.add(args);
Attributes attrs = new BasicAttributes();
BasicAttribute oc = new BasicAttribute("objectClass");
Iterator<ByteString> it = indexEntry.getObjectClassAttribute().iterator();
while (it.hasNext())
{
oc.add(it.next().toString());
}
attrs.put(oc);
List<org.opends.server.types.Attribute> odsAttrs =
indexEntry.getAttributes();
for (org.opends.server.types.Attribute odsAttr : odsAttrs)
{
String attrName = odsAttr.getName();
BasicAttribute attr = new BasicAttribute(attrName);
it = odsAttr.iterator();
while (it.hasNext())
{
attr.add(it.next().toString());
}
attrs.put(attr);
if (attrName.equalsIgnoreCase("ds-cfg-attribute"))
{
args.add("--index-name");
args.add(odsAttr.iterator().next().toString());
}
else if (attrName.equalsIgnoreCase("ds-cfg-index-type"))
{
it = odsAttr.iterator();
while (it.hasNext())
{
args.add("--set");
args.add("index-type:" + it.next().toString());
}
}
}
args.addAll(getConnectionCommandLineArguments());
args.add(getNoPropertiesFileArgument());
args.add("--no-prompt");
dns.add(indexEntry.getName().toString());
attributes.add(attrs);
}
StringBuilder sb = new StringBuilder();
for (List<String> args : argsArray)
{
sb.append(getEquivalentCommandLine(getCommandLinePath("dsconfig"),
getObfuscatedCommandLineArguments(args)));
sb.append("<br><br>");
}
final String cmdLines = sb.toString();
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
getProgressDialog().appendProgressHtml(Utilities.applyFont(
INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_CREATE_ADDITIONAL_INDEXES.get()+
"<br><br><b>"+cmdLines+"</b>",
ColorAndFontConstants.progressFont));
getProgressDialog().appendProgressHtml(
Utilities.getProgressWithPoints(
INFO_CTRL_PANEL_CREATING_ADDITIONAL_INDEXES_PROGRESS.get(),
ColorAndFontConstants.progressFont));
}
});
for (int i=0; i<dns.size(); i++)
{
ctx.createSubcontext(dns.get(i), attributes.get(i));
}
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
getProgressDialog().appendProgressHtml(
Utilities.getProgressDone(ColorAndFontConstants.progressFont)+
"<br><br>");
}
});
}
catch (Throwable t)
{
throw new OnlineUpdateException(
ERR_CTRL_PANEL_ERROR_UPDATING_CONFIGURATION.get(t), t);
}
finally
{
if (ldifImportConfig != null)
{
ldifImportConfig.close();
}
}
}
private void addBaseDN(String backendName, String baseDN)
throws OpenDsException, ConfigException
{
LinkedList<DN> baseDNs = new LinkedList<DN>();
for (BackendDescriptor backend :
getInfo().getServerDescriptor().getBackends())
{
if (backend.getBackendID().equalsIgnoreCase(backendName))
{
for (BaseDNDescriptor b : backend.getBaseDns())
{
baseDNs.add(b.getDn());
}
break;
}
}
baseDNs.add(DN.valueOf(baseDN));
String dn = Utilities.getRDNString("ds-cfg-backend-id", backendName)+
",cn=Backends,cn=config";
ConfigEntry configEntry =
DirectoryServer.getConfigHandler().getConfigEntry(DN.valueOf(dn));
DNConfigAttribute baseDNAttr =
new DNConfigAttribute(
ConfigConstants.ATTR_BACKEND_BASE_DN,
INFO_CONFIG_BACKEND_ATTR_DESCRIPTION_BASE_DNS.get(),
true, true, false, baseDNs);
configEntry.putConfigAttribute(baseDNAttr);
DirectoryServer.getConfigHandler().writeUpdatedConfig();
}
private void addBaseDN(InitialLdapContext ctx, String backendName,
String baseDN) throws OpenDsException
{
ManagementContext mCtx = LDAPManagementContext.createFromContext(
JNDIDirContextAdaptor.adapt(ctx));
RootCfgClient root = mCtx.getRootConfiguration();
LocalDBBackendCfgClient backend =
(LocalDBBackendCfgClient)root.getBackend(backendName);
Set<DN> baseDNs = backend.getBaseDN();
DN dn = DN.valueOf(baseDN);
baseDNs.add(dn);
backend.setBaseDN(baseDNs);
backend.commit();
}
/**
* {@inheritDoc}
*/
protected String getCommandLinePath()
{
return null;
}
/**
* {@inheritDoc}
*/
protected ArrayList<String> getCommandLineArguments()
{
return new ArrayList<String>();
}
/**
* Returns the configuration command-line full path.
* @return the configuration command-line full path.
*/
private String getConfigCommandLineFullPath()
{
if (isServerRunning())
{
return getCommandLinePath("dsconfig");
}
else
{
return null;
}
}
/**
* Returns the configuration command-line arguments.
* @return the configuration command-line arguments.
*/
private ArrayList<String> getDSConfigCommandLineArguments()
{
ArrayList<String> args = new ArrayList<String>();
if (isServerRunning())
{
if (isNewBackend())
{
args.add("create-backend");
args.add("--backend-name");
args.add(getBackendName());
args.add("--set");
args.add("base-dn:"+newBaseDN);
args.add("--set");
args.add("enabled:true");
args.add("--type");
args.add("local-db");
}
else
{
args.add("set-backend-prop");
args.add("--backend-name");
args.add(getBackendName());
args.add("--add");
args.add("base-dn:"+newBaseDN);
}
args.addAll(getConnectionCommandLineArguments());
args.add(getNoPropertiesFileArgument());
args.add("--no-prompt");
}
return args;
}
/**
* {@inheritDoc}
*/
public void runTask()
{
state = State.RUNNING;
lastException = null;
try
{
updateConfiguration();
updateData();
}
catch (Throwable t)
{
lastException = t;
state = State.FINISHED_WITH_ERROR;
}
}
/**
* {@inheritDoc}
*/
public Set<String> getBackends()
{
return backendSet;
}
}
}