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 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.tools; 028 029 import java.io.OutputStream; 030 import java.io.PrintStream; 031 import java.util.ArrayList; 032 import java.util.HashSet; 033 import java.util.List; 034 035 import org.opends.server.api.Backend; 036 import org.opends.server.api.ErrorLogPublisher; 037 import org.opends.server.api.DebugLogPublisher; 038 import org.opends.server.api.plugin.PluginType; 039 import org.opends.server.config.ConfigException; 040 import static org.opends.server.config.ConfigConstants.*; 041 import org.opends.server.core.CoreConfigManager; 042 import org.opends.server.core.DirectoryServer; 043 import org.opends.server.core.LockFileManager; 044 import org.opends.server.extensions.ConfigFileHandler; 045 import org.opends.server.loggers.TextWriter; 046 import org.opends.server.loggers.TextErrorLogPublisher; 047 import org.opends.server.loggers.ErrorLogger; 048 import org.opends.server.loggers.debug.TextDebugLogPublisher; 049 import org.opends.server.loggers.debug.DebugLogger; 050 import org.opends.server.types.AttributeType; 051 import org.opends.server.types.DirectoryException; 052 import org.opends.server.types.DN; 053 import org.opends.server.types.ExistingFileBehavior; 054 import org.opends.server.types.InitializationException; 055 import org.opends.server.types.LDIFExportConfig; 056 import org.opends.server.types.NullOutputStream; 057 import org.opends.server.types.SearchFilter; 058 import org.opends.server.types.RawAttribute; 059 import org.opends.server.util.args.ArgumentException; 060 import org.opends.server.util.args.BooleanArgument; 061 import org.opends.server.util.args.IntegerArgument; 062 import org.opends.server.util.args.StringArgument; 063 import org.opends.server.util.args.LDAPConnectionArgumentParser; 064 065 import org.opends.messages.Message; 066 import static org.opends.messages.ToolMessages.*; 067 import static org.opends.server.loggers.ErrorLogger.*; 068 import static org.opends.server.util.ServerConstants.*; 069 import static org.opends.server.util.StaticUtils.*; 070 import static org.opends.server.tools.ToolConstants.*; 071 import org.opends.server.tools.tasks.TaskTool; 072 import org.opends.server.admin.std.server.BackendCfg; 073 import org.opends.server.protocols.ldap.LDAPAttribute; 074 import org.opends.server.protocols.asn1.ASN1OctetString; 075 import org.opends.server.tasks.ExportTask; 076 077 078 /** 079 * This program provides a utility that may be used to export the contents of a 080 * Directory Server backend to an LDIF file. Depending on the arguments given, 081 * this program will either perform the export directly as a process that 082 * runs separate from Directory Server; or by scheduling a task to perform the 083 * action within the Directory Server via the tasks interface. 084 */ 085 public class ExportLDIF extends TaskTool { 086 087 /** 088 * The main method for ExportLDIF tool. 089 * 090 * @param args The command-line arguments provided to this program. 091 */ 092 public static void main(String[] args) 093 { 094 int retCode = mainExportLDIF(args, true, System.out, System.err); 095 096 if(retCode != 0) 097 { 098 System.exit(filterExitCode(retCode)); 099 } 100 } 101 102 /** 103 * Processes the command-line arguments and invokes the export process. 104 * 105 * @param args The command-line arguments provided to this program. 106 * 107 * @return The error code. 108 */ 109 public static int mainExportLDIF(String[] args) 110 { 111 return mainExportLDIF(args, true, System.out, System.err); 112 } 113 114 /** 115 * Processes the command-line arguments and invokes the export process. 116 * 117 * @param args The command-line arguments provided to this 118 * program. 119 * @param initializeServer Indicates whether to initialize the server. 120 * @param outStream The output stream to use for standard output, or 121 * {@code null} if standard output is not needed. 122 * @param errStream The output stream to use for standard error, or 123 * {@code null} if standard error is not needed. 124 * 125 * @return The error code. 126 */ 127 public static int mainExportLDIF(String[] args, boolean initializeServer, 128 OutputStream outStream, 129 OutputStream errStream) 130 { 131 ExportLDIF tool = new ExportLDIF(); 132 return tool.process(args, initializeServer, outStream, errStream); 133 } 134 135 // Define the command-line arguments that may be used with this program. 136 private BooleanArgument appendToLDIF = null; 137 private BooleanArgument compressLDIF = null; 138 private BooleanArgument displayUsage = null; 139 private BooleanArgument encryptLDIF = null; 140 private BooleanArgument excludeOperationalAttrs = null; 141 private BooleanArgument signHash = null; 142 private IntegerArgument wrapColumn = null; 143 private StringArgument backendID = null; 144 private StringArgument configClass = null; 145 private StringArgument configFile = null; 146 private StringArgument excludeAttributeStrings = null; 147 private StringArgument excludeBranchStrings = null; 148 private StringArgument excludeFilterStrings = null; 149 private StringArgument includeAttributeStrings = null; 150 private StringArgument includeBranchStrings = null; 151 private StringArgument includeFilterStrings = null; 152 private StringArgument ldifFile = null; 153 154 private int process(String[] args, boolean initializeServer, 155 OutputStream outStream, OutputStream errStream) { 156 157 PrintStream out; 158 if (outStream == null) 159 { 160 out = NullOutputStream.printStream(); 161 } 162 else 163 { 164 out = new PrintStream(outStream); 165 } 166 167 PrintStream err; 168 if (errStream == null) 169 { 170 err = NullOutputStream.printStream(); 171 } 172 else 173 { 174 err = new PrintStream(errStream); 175 } 176 177 // Create the command-line argument parser for use with this program. 178 LDAPConnectionArgumentParser argParser = 179 createArgParser("org.opends.server.tools.ExportLDIF", 180 INFO_LDIFEXPORT_TOOL_DESCRIPTION.get()); 181 182 183 // Initialize all the command-line argument types and register them with the 184 // parser. 185 try 186 { 187 configClass = 188 new StringArgument("configclass", OPTION_SHORT_CONFIG_CLASS, 189 OPTION_LONG_CONFIG_CLASS, true, false, 190 true, INFO_CONFIGCLASS_PLACEHOLDER.get(), 191 ConfigFileHandler.class.getName(), null, 192 INFO_DESCRIPTION_CONFIG_CLASS.get()); 193 configClass.setHidden(true); 194 argParser.addArgument(configClass); 195 196 197 configFile = 198 new StringArgument("configfile", 'f', "configFile", true, false, 199 true, INFO_CONFIGFILE_PLACEHOLDER.get(), null, 200 null, 201 INFO_DESCRIPTION_CONFIG_FILE.get()); 202 configFile.setHidden(true); 203 argParser.addArgument(configFile); 204 205 206 ldifFile = 207 new StringArgument("ldiffile", OPTION_SHORT_LDIF_FILE, 208 OPTION_LONG_LDIF_FILE,true, false, true, 209 INFO_LDIFFILE_PLACEHOLDER.get(), null, null, 210 INFO_LDIFEXPORT_DESCRIPTION_LDIF_FILE.get()); 211 argParser.addArgument(ldifFile); 212 213 214 appendToLDIF = new BooleanArgument( 215 "appendldif", 'a', "appendToLDIF", 216 INFO_LDIFEXPORT_DESCRIPTION_APPEND_TO_LDIF.get()); 217 argParser.addArgument(appendToLDIF); 218 219 220 backendID = 221 new StringArgument("backendid", 'n', "backendID", true, false, true, 222 INFO_BACKENDNAME_PLACEHOLDER.get(), null, null, 223 INFO_LDIFEXPORT_DESCRIPTION_BACKEND_ID.get()); 224 argParser.addArgument(backendID); 225 226 227 includeBranchStrings = 228 new StringArgument("includebranch", 'b', "includeBranch", false, 229 true, true, INFO_BRANCH_DN_PLACEHOLDER.get(), 230 null, null, 231 INFO_LDIFEXPORT_DESCRIPTION_INCLUDE_BRANCH.get()); 232 argParser.addArgument(includeBranchStrings); 233 234 235 excludeBranchStrings = 236 new StringArgument("excludebranch", 'B', "excludeBranch", false, 237 true, true, INFO_BRANCH_DN_PLACEHOLDER.get(), 238 null, null, 239 INFO_LDIFEXPORT_DESCRIPTION_EXCLUDE_BRANCH.get()); 240 argParser.addArgument(excludeBranchStrings); 241 242 243 includeAttributeStrings = 244 new StringArgument( 245 "includeattribute", 'i', "includeAttribute", 246 false, true, true, INFO_ATTRIBUTE_PLACEHOLDER.get(), null, 247 null, 248 INFO_LDIFEXPORT_DESCRIPTION_INCLUDE_ATTRIBUTE.get()); 249 argParser.addArgument(includeAttributeStrings); 250 251 252 excludeAttributeStrings = 253 new StringArgument( 254 "excludeattribute", 'e', "excludeAttribute", 255 false, true, true, INFO_ATTRIBUTE_PLACEHOLDER.get(), null, 256 null, 257 INFO_LDIFEXPORT_DESCRIPTION_EXCLUDE_ATTRIBUTE.get()); 258 argParser.addArgument(excludeAttributeStrings); 259 260 261 includeFilterStrings = 262 new StringArgument("includefilter", 'I', "includeFilter", 263 false, true, true, INFO_FILTER_PLACEHOLDER.get(), 264 null, null, 265 INFO_LDIFEXPORT_DESCRIPTION_INCLUDE_FILTER.get()); 266 argParser.addArgument(includeFilterStrings); 267 268 269 excludeFilterStrings = 270 new StringArgument("excludefilter", 'E', "excludeFilter", 271 false, true, true, INFO_FILTER_PLACEHOLDER.get(), 272 null, null, 273 INFO_LDIFEXPORT_DESCRIPTION_EXCLUDE_FILTER.get()); 274 argParser.addArgument(excludeFilterStrings); 275 276 277 excludeOperationalAttrs = 278 new BooleanArgument("excludeoperational", 'O', "excludeOperational", 279 INFO_LDIFEXPORT_DESCRIPTION_EXCLUDE_OPERATIONAL.get()); 280 argParser.addArgument(excludeOperationalAttrs); 281 282 283 wrapColumn = 284 new IntegerArgument("wrapcolumn", null, "wrapColumn", false, false, 285 true, INFO_WRAP_COLUMN_PLACEHOLDER.get(), 0, 286 null, true, 0, false, 0, 287 INFO_LDIFEXPORT_DESCRIPTION_WRAP_COLUMN.get()); 288 argParser.addArgument(wrapColumn); 289 290 291 compressLDIF = 292 new BooleanArgument("compressldif", OPTION_SHORT_COMPRESS, 293 OPTION_LONG_COMPRESS, 294 INFO_LDIFEXPORT_DESCRIPTION_COMPRESS_LDIF.get()); 295 argParser.addArgument(compressLDIF); 296 297 298 encryptLDIF = 299 new BooleanArgument("encryptldif", 'y', "encryptLDIF", 300 INFO_LDIFEXPORT_DESCRIPTION_ENCRYPT_LDIF.get()); 301 encryptLDIF.setHidden(true); // See issue #27 302 argParser.addArgument(encryptLDIF); 303 304 305 signHash = 306 new BooleanArgument("signhash", 's', "signHash", 307 INFO_LDIFEXPORT_DESCRIPTION_SIGN_HASH.get()); 308 signHash.setHidden(true); // See issue #28 309 argParser.addArgument(signHash); 310 311 312 displayUsage = 313 new BooleanArgument("help", OPTION_SHORT_HELP, 314 OPTION_LONG_HELP, 315 INFO_DESCRIPTION_USAGE.get()); 316 argParser.addArgument(displayUsage); 317 argParser.setUsageArgument(displayUsage); 318 } 319 catch (ArgumentException ae) 320 { 321 Message message = ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage()); 322 323 err.println(wrapText(message, MAX_LINE_WIDTH)); 324 return 1; 325 } 326 327 328 // Parse the command-line arguments provided to this program. 329 try 330 { 331 argParser.parseArguments(args); 332 validateTaskArgs(); 333 } 334 catch (ArgumentException ae) 335 { 336 Message message = ERR_ERROR_PARSING_ARGS.get(ae.getMessage()); 337 338 err.println(wrapText(message, MAX_LINE_WIDTH)); 339 err.println(argParser.getUsage()); 340 return 1; 341 } 342 343 344 // If we should just display usage or version information, 345 // then print it and exit. 346 if (argParser.usageOrVersionDisplayed()) 347 { 348 return 0; 349 } 350 351 return process(argParser, initializeServer, out, err); 352 } 353 354 /** 355 * {@inheritDoc} 356 */ 357 public void addTaskAttributes(List<RawAttribute> attributes) 358 { 359 // 360 // Required attributes 361 // 362 ArrayList<ASN1OctetString> values = new ArrayList<ASN1OctetString>(1); 363 values.add(new ASN1OctetString(ldifFile.getValue())); 364 attributes.add(new LDAPAttribute(ATTR_TASK_EXPORT_LDIF_FILE, values)); 365 366 values = new ArrayList<ASN1OctetString>(1); 367 values.add(new ASN1OctetString(backendID.getValue())); 368 attributes.add(new LDAPAttribute(ATTR_TASK_EXPORT_BACKEND_ID, values)); 369 370 // 371 // Optional attributes 372 // 373 if (appendToLDIF.getValue() != null && 374 !appendToLDIF.getValue().equals(appendToLDIF.getDefaultValue())) { 375 values = new ArrayList<ASN1OctetString>(1); 376 values.add(new ASN1OctetString(appendToLDIF.getValue())); 377 attributes.add( 378 new LDAPAttribute(ATTR_TASK_EXPORT_APPEND_TO_LDIF, values)); 379 } 380 381 if (compressLDIF.getValue() != null && 382 !compressLDIF.getValue().equals(compressLDIF.getDefaultValue())) { 383 values = new ArrayList<ASN1OctetString>(1); 384 values.add(new ASN1OctetString(compressLDIF.getValue())); 385 attributes.add(new LDAPAttribute(ATTR_TASK_EXPORT_COMPRESS_LDIF, values)); 386 } 387 388 if (encryptLDIF.getValue() != null && 389 !encryptLDIF.getValue().equals(encryptLDIF.getDefaultValue())) { 390 values = new ArrayList<ASN1OctetString>(1); 391 values.add(new ASN1OctetString(encryptLDIF.getValue())); 392 attributes.add(new LDAPAttribute(ATTR_TASK_EXPORT_ENCRYPT_LDIF, values)); 393 } 394 395 if (signHash.getValue() != null && 396 !signHash.getValue().equals(signHash.getDefaultValue())) { 397 values = new ArrayList<ASN1OctetString>(1); 398 values.add(new ASN1OctetString(signHash.getValue())); 399 attributes.add( 400 new LDAPAttribute(ATTR_TASK_EXPORT_SIGN_HASH, values)); 401 } 402 403 List<String> includeAttributes = includeAttributeStrings.getValues(); 404 if (includeAttributes != null && includeAttributes.size() > 0) { 405 values = new ArrayList<ASN1OctetString>(includeAttributes.size()); 406 for (String includeAttribute : includeAttributes) { 407 values.add(new ASN1OctetString(includeAttribute)); 408 } 409 attributes.add( 410 new LDAPAttribute(ATTR_TASK_EXPORT_INCLUDE_ATTRIBUTE, values)); 411 } 412 413 List<String> excludeAttributes = excludeAttributeStrings.getValues(); 414 if (excludeAttributes != null && excludeAttributes.size() > 0) { 415 values = new ArrayList<ASN1OctetString>(excludeAttributes.size()); 416 for (String excludeAttribute : excludeAttributes) { 417 values.add(new ASN1OctetString(excludeAttribute)); 418 } 419 attributes.add( 420 new LDAPAttribute(ATTR_TASK_EXPORT_EXCLUDE_ATTRIBUTE, values)); 421 } 422 423 List<String> includeFilters = includeFilterStrings.getValues(); 424 if (includeFilters != null && includeFilters.size() > 0) { 425 values = new ArrayList<ASN1OctetString>(includeFilters.size()); 426 for (String includeFilter : includeFilters) { 427 values.add(new ASN1OctetString(includeFilter)); 428 } 429 attributes.add( 430 new LDAPAttribute(ATTR_TASK_EXPORT_INCLUDE_FILTER, values)); 431 } 432 433 List<String> excludeFilters = excludeFilterStrings.getValues(); 434 if (excludeFilters != null && excludeFilters.size() > 0) { 435 values = new ArrayList<ASN1OctetString>(excludeFilters.size()); 436 for (String excludeFilter : excludeFilters) { 437 values.add(new ASN1OctetString(excludeFilter)); 438 } 439 attributes.add( 440 new LDAPAttribute(ATTR_TASK_EXPORT_EXCLUDE_FILTER, values)); 441 } 442 443 List<String> includeBranches = includeBranchStrings.getValues(); 444 if (includeBranches != null && includeBranches.size() > 0) { 445 values = new ArrayList<ASN1OctetString>(includeBranches.size()); 446 for (String includeBranche : includeBranches) { 447 values.add(new ASN1OctetString(includeBranche)); 448 } 449 attributes.add( 450 new LDAPAttribute(ATTR_TASK_EXPORT_INCLUDE_BRANCH, values)); 451 } 452 453 List<String> excludeBranches = excludeBranchStrings.getValues(); 454 if (excludeBranches != null && excludeBranches.size() > 0) { 455 values = new ArrayList<ASN1OctetString>(excludeBranches.size()); 456 for (String excludeBranche : excludeBranches) { 457 values.add(new ASN1OctetString(excludeBranche)); 458 } 459 attributes.add( 460 new LDAPAttribute(ATTR_TASK_EXPORT_EXCLUDE_BRANCH, values)); 461 } 462 463 if (wrapColumn.getValue() != null && 464 !wrapColumn.getValue().equals(wrapColumn.getDefaultValue())) { 465 values = new ArrayList<ASN1OctetString>(1); 466 values.add(new ASN1OctetString(wrapColumn.getValue())); 467 attributes.add( 468 new LDAPAttribute(ATTR_TASK_EXPORT_WRAP_COLUMN, values)); 469 } 470 471 if (excludeOperationalAttrs.isPresent()) 472 { 473 values = new ArrayList<ASN1OctetString>(1); 474 values.add(new ASN1OctetString("false")); 475 attributes.add( 476 new LDAPAttribute(ATTR_TASK_EXPORT_INCLUDE_OPERATIONAL_ATTRIBUTES, 477 values)); 478 } 479 } 480 481 /** 482 * {@inheritDoc} 483 */ 484 public String getTaskObjectclass() { 485 return "ds-task-export"; 486 } 487 488 /** 489 * {@inheritDoc} 490 */ 491 public Class getTaskClass() { 492 return ExportTask.class; 493 } 494 495 /** 496 * {@inheritDoc} 497 */ 498 protected int processLocal(boolean initializeServer, 499 PrintStream out, 500 PrintStream err) { 501 502 // Perform the initial bootstrap of the Directory Server and process the 503 // configuration. 504 DirectoryServer directoryServer = DirectoryServer.getInstance(); 505 if (initializeServer) 506 { 507 try 508 { 509 DirectoryServer.bootstrapClient(); 510 DirectoryServer.initializeJMX(); 511 } 512 catch (Exception e) 513 { 514 Message message = 515 ERR_SERVER_BOOTSTRAP_ERROR.get(getExceptionMessage(e)); 516 err.println(wrapText(message, MAX_LINE_WIDTH)); 517 return 1; 518 } 519 520 try 521 { 522 directoryServer.initializeConfiguration(configClass.getValue(), 523 configFile.getValue()); 524 } 525 catch (InitializationException ie) 526 { 527 Message message = ERR_CANNOT_LOAD_CONFIG.get(ie.getMessage()); 528 err.println(wrapText(message, MAX_LINE_WIDTH)); 529 return 1; 530 } 531 catch (Exception e) 532 { 533 Message message = ERR_CANNOT_LOAD_CONFIG.get(getExceptionMessage(e)); 534 err.println(wrapText(message, MAX_LINE_WIDTH)); 535 return 1; 536 } 537 538 539 540 // Initialize the Directory Server schema elements. 541 try 542 { 543 directoryServer.initializeSchema(); 544 } 545 catch (ConfigException ce) 546 { 547 Message message = ERR_CANNOT_LOAD_SCHEMA.get(ce.getMessage()); 548 err.println(wrapText(message, MAX_LINE_WIDTH)); 549 return 1; 550 } 551 catch (InitializationException ie) 552 { 553 Message message = ERR_CANNOT_LOAD_SCHEMA.get(ie.getMessage()); 554 err.println(wrapText(message, MAX_LINE_WIDTH)); 555 return 1; 556 } 557 catch (Exception e) 558 { 559 Message message = ERR_CANNOT_LOAD_SCHEMA.get(getExceptionMessage(e)); 560 err.println(wrapText(message, MAX_LINE_WIDTH)); 561 return 1; 562 } 563 564 565 // Initialize the Directory Server core configuration. 566 try 567 { 568 CoreConfigManager coreConfigManager = new CoreConfigManager(); 569 coreConfigManager.initializeCoreConfig(); 570 } 571 catch (ConfigException ce) 572 { 573 Message message = 574 ERR_CANNOT_INITIALIZE_CORE_CONFIG.get(ce.getMessage()); 575 err.println(wrapText(message, MAX_LINE_WIDTH)); 576 return 1; 577 } 578 catch (InitializationException ie) 579 { 580 Message message = 581 ERR_CANNOT_INITIALIZE_CORE_CONFIG.get(ie.getMessage()); 582 err.println(wrapText(message, MAX_LINE_WIDTH)); 583 return 1; 584 } 585 catch (Exception e) 586 { 587 Message message = 588 ERR_CANNOT_INITIALIZE_CORE_CONFIG.get(getExceptionMessage(e)); 589 err.println(wrapText(message, MAX_LINE_WIDTH)); 590 return 1; 591 } 592 593 594 // Initialize the Directory Server crypto manager. 595 try 596 { 597 directoryServer.initializeCryptoManager(); 598 } 599 catch (ConfigException ce) 600 { 601 Message message = 602 ERR_CANNOT_INITIALIZE_CRYPTO_MANAGER.get(ce.getMessage()); 603 err.println(wrapText(message, MAX_LINE_WIDTH)); 604 return 1; 605 } 606 catch (InitializationException ie) 607 { 608 Message message = 609 ERR_CANNOT_INITIALIZE_CRYPTO_MANAGER.get(ie.getMessage()); 610 err.println(wrapText(message, MAX_LINE_WIDTH)); 611 return 1; 612 } 613 catch (Exception e) 614 { 615 Message message = 616 ERR_CANNOT_INITIALIZE_CRYPTO_MANAGER.get( 617 getExceptionMessage(e)); 618 err.println(wrapText(message, MAX_LINE_WIDTH)); 619 return 1; 620 } 621 622 623 try 624 { 625 ErrorLogPublisher errorLogPublisher = 626 TextErrorLogPublisher.getStartupTextErrorPublisher( 627 new TextWriter.STREAM(out)); 628 DebugLogPublisher debugLogPublisher = 629 TextDebugLogPublisher.getStartupTextDebugPublisher( 630 new TextWriter.STREAM(out)); 631 ErrorLogger.addErrorLogPublisher(errorLogPublisher); 632 DebugLogger.addDebugLogPublisher(debugLogPublisher); 633 } 634 catch(Exception e) 635 { 636 err.println("Error installing the custom error logger: " + 637 stackTraceToSingleLineString(e)); 638 } 639 640 641 642 // Make sure that the Directory Server plugin initialization is performed. 643 try 644 { 645 HashSet<PluginType> pluginTypes = new HashSet<PluginType>(1); 646 pluginTypes.add(PluginType.LDIF_EXPORT); 647 directoryServer.initializePlugins(pluginTypes); 648 } 649 catch (ConfigException ce) 650 { 651 Message message = 652 ERR_LDIFEXPORT_CANNOT_INITIALIZE_PLUGINS.get(ce.getMessage()); 653 err.println(wrapText(message, MAX_LINE_WIDTH)); 654 return 1; 655 } 656 catch (InitializationException ie) 657 { 658 Message message = 659 ERR_LDIFEXPORT_CANNOT_INITIALIZE_PLUGINS.get(ie.getMessage()); 660 err.println(wrapText(message, MAX_LINE_WIDTH)); 661 return 1; 662 } 663 catch (Exception e) 664 { 665 Message message = 666 ERR_LDIFEXPORT_CANNOT_INITIALIZE_PLUGINS.get( 667 getExceptionMessage(e)); 668 err.println(wrapText(message, MAX_LINE_WIDTH)); 669 return 1; 670 } 671 } 672 673 674 // See if there were any user-defined sets of include/exclude attributes or 675 // filters. If so, then process them. 676 HashSet<AttributeType> excludeAttributes; 677 if (excludeAttributeStrings == null) 678 { 679 excludeAttributes = null; 680 } 681 else 682 { 683 excludeAttributes = new HashSet<AttributeType>(); 684 for (String attrName : excludeAttributeStrings.getValues()) 685 { 686 String lowerName = attrName.toLowerCase(); 687 AttributeType attrType = DirectoryServer.getAttributeType(lowerName); 688 if (attrType == null) 689 { 690 attrType = DirectoryServer.getDefaultAttributeType(attrName); 691 } 692 693 excludeAttributes.add(attrType); 694 } 695 } 696 697 HashSet<AttributeType> includeAttributes; 698 if (includeAttributeStrings == null) 699 { 700 includeAttributes = null; 701 } 702 else 703 { 704 includeAttributes =new HashSet<AttributeType>(); 705 for (String attrName : includeAttributeStrings.getValues()) 706 { 707 String lowerName = attrName.toLowerCase(); 708 AttributeType attrType = DirectoryServer.getAttributeType(lowerName); 709 if (attrType == null) 710 { 711 attrType = DirectoryServer.getDefaultAttributeType(attrName); 712 } 713 714 includeAttributes.add(attrType); 715 } 716 } 717 718 ArrayList<SearchFilter> excludeFilters; 719 if (excludeFilterStrings == null) 720 { 721 excludeFilters = null; 722 } 723 else 724 { 725 excludeFilters = new ArrayList<SearchFilter>(); 726 for (String filterString : excludeFilterStrings.getValues()) 727 { 728 try 729 { 730 excludeFilters.add(SearchFilter.createFilterFromString(filterString)); 731 } 732 catch (DirectoryException de) 733 { 734 Message message = ERR_LDIFEXPORT_CANNOT_PARSE_EXCLUDE_FILTER.get( 735 filterString, de.getMessageObject()); 736 logError(message); 737 return 1; 738 } 739 catch (Exception e) 740 { 741 Message message = ERR_LDIFEXPORT_CANNOT_PARSE_EXCLUDE_FILTER.get( 742 filterString, getExceptionMessage(e)); 743 logError(message); 744 return 1; 745 } 746 } 747 } 748 749 ArrayList<SearchFilter> includeFilters; 750 if (includeFilterStrings == null) 751 { 752 includeFilters = null; 753 } 754 else 755 { 756 includeFilters = new ArrayList<SearchFilter>(); 757 for (String filterString : includeFilterStrings.getValues()) 758 { 759 try 760 { 761 includeFilters.add(SearchFilter.createFilterFromString(filterString)); 762 } 763 catch (DirectoryException de) 764 { 765 Message message = ERR_LDIFEXPORT_CANNOT_PARSE_INCLUDE_FILTER.get( 766 filterString, de.getMessageObject()); 767 logError(message); 768 return 1; 769 } 770 catch (Exception e) 771 { 772 Message message = ERR_LDIFEXPORT_CANNOT_PARSE_INCLUDE_FILTER.get( 773 filterString, getExceptionMessage(e)); 774 logError(message); 775 return 1; 776 } 777 } 778 } 779 780 781 // Get information about the backends defined in the server. Iterate 782 // through them, finding the one backend that should be used for the export, 783 // and also finding backends with subordinate base DNs that should be 784 // excluded from the export. 785 Backend backend = null; 786 List<DN> baseDNList = null; 787 List<DN> defaultIncludeBranches = null; 788 ArrayList<DN> excludeBranches = null; 789 790 ArrayList<Backend> backendList = new ArrayList<Backend>(); 791 ArrayList<BackendCfg> entryList = new ArrayList<BackendCfg>(); 792 ArrayList<List<DN>> dnList = new ArrayList<List<DN>>(); 793 BackendToolUtils.getBackends(backendList, entryList, dnList); 794 795 int numBackends = backendList.size(); 796 for (int i=0; i < numBackends; i++) 797 { 798 Backend b = backendList.get(i); 799 if (! backendID.getValue().equals(b.getBackendID())) 800 { 801 continue; 802 } 803 804 if (backend == null) 805 { 806 backend = b; 807 baseDNList = dnList.get(i); 808 defaultIncludeBranches = dnList.get(i); 809 } 810 else 811 { 812 Message message = 813 ERR_LDIFEXPORT_MULTIPLE_BACKENDS_FOR_ID.get(backendID.getValue()); 814 logError(message); 815 return 1; 816 } 817 } 818 819 if (backend == null) 820 { 821 Message message = 822 ERR_LDIFEXPORT_NO_BACKENDS_FOR_ID.get(backendID.getValue()); 823 logError(message); 824 return 1; 825 } 826 else if (! backend.supportsLDIFExport()) 827 { 828 Message message = 829 ERR_LDIFEXPORT_CANNOT_EXPORT_BACKEND.get(backendID.getValue()); 830 logError(message); 831 return 1; 832 } 833 834 if (excludeBranchStrings.isPresent()) 835 { 836 excludeBranches = new ArrayList<DN>(); 837 for (String s : excludeBranchStrings.getValues()) 838 { 839 DN excludeBranch; 840 try 841 { 842 excludeBranch = DN.decode(s); 843 } 844 catch (DirectoryException de) 845 { 846 Message message = ERR_LDIFEXPORT_CANNOT_DECODE_EXCLUDE_BASE.get( 847 s, de.getMessageObject()); 848 logError(message); 849 return 1; 850 } 851 catch (Exception e) 852 { 853 Message message = ERR_LDIFEXPORT_CANNOT_DECODE_EXCLUDE_BASE.get( 854 s, getExceptionMessage(e)); 855 logError(message); 856 return 1; 857 } 858 859 if (! excludeBranches.contains(excludeBranch)) 860 { 861 excludeBranches.add(excludeBranch); 862 } 863 } 864 } 865 866 867 List<DN> includeBranches; 868 if (includeBranchStrings.isPresent()) 869 { 870 includeBranches = new ArrayList<DN>(); 871 for (String s : includeBranchStrings.getValues()) 872 { 873 DN includeBranch; 874 try 875 { 876 includeBranch = DN.decode(s); 877 } 878 catch (DirectoryException de) 879 { 880 Message message = ERR_LDIFIMPORT_CANNOT_DECODE_INCLUDE_BASE.get( 881 s, de.getMessageObject()); 882 logError(message); 883 return 1; 884 } 885 catch (Exception e) 886 { 887 Message message = ERR_LDIFIMPORT_CANNOT_DECODE_INCLUDE_BASE.get( 888 s, getExceptionMessage(e)); 889 logError(message); 890 return 1; 891 } 892 893 if (! Backend.handlesEntry(includeBranch, defaultIncludeBranches, 894 excludeBranches)) 895 { 896 Message message = 897 ERR_LDIFEXPORT_INVALID_INCLUDE_BASE.get(s, backendID.getValue()); 898 logError(message); 899 return 1; 900 } 901 902 includeBranches.add(includeBranch); 903 } 904 } 905 else 906 { 907 includeBranches = defaultIncludeBranches; 908 } 909 910 911 // Create the LDIF export configuration to use when reading the LDIF. 912 ExistingFileBehavior existingBehavior; 913 if (appendToLDIF.isPresent()) 914 { 915 existingBehavior = ExistingFileBehavior.APPEND; 916 } 917 else 918 { 919 existingBehavior = ExistingFileBehavior.OVERWRITE; 920 } 921 922 LDIFExportConfig exportConfig = new LDIFExportConfig(ldifFile.getValue(), 923 existingBehavior); 924 exportConfig.setCompressData(compressLDIF.isPresent()); 925 exportConfig.setEncryptData(encryptLDIF.isPresent()); 926 exportConfig.setExcludeAttributes(excludeAttributes); 927 exportConfig.setExcludeBranches(excludeBranches); 928 exportConfig.setExcludeFilters(excludeFilters); 929 exportConfig.setIncludeAttributes(includeAttributes); 930 exportConfig.setIncludeBranches(includeBranches); 931 exportConfig.setIncludeFilters(includeFilters); 932 exportConfig.setSignHash(signHash.isPresent()); 933 exportConfig.setIncludeOperationalAttributes( 934 (! excludeOperationalAttrs.isPresent())); 935 936 // FIXME -- Should this be conditional? 937 exportConfig.setInvokeExportPlugins(true); 938 939 try 940 { 941 exportConfig.setWrapColumn(wrapColumn.getIntValue()); 942 } 943 catch (ArgumentException ae) 944 { 945 Message message = ERR_LDIFEXPORT_CANNOT_DECODE_WRAP_COLUMN_AS_INTEGER.get( 946 wrapColumn.getValue()); 947 logError(message); 948 return 1; 949 } 950 951 952 // Get the set of base DNs for the backend as an array. 953 DN[] baseDNs = new DN[baseDNList.size()]; 954 baseDNList.toArray(baseDNs); 955 956 957 // Acquire a shared lock for the backend. 958 try 959 { 960 String lockFile = LockFileManager.getBackendLockFileName(backend); 961 StringBuilder failureReason = new StringBuilder(); 962 if (! LockFileManager.acquireSharedLock(lockFile, failureReason)) 963 { 964 Message message = ERR_LDIFEXPORT_CANNOT_LOCK_BACKEND.get( 965 backend.getBackendID(), String.valueOf(failureReason)); 966 logError(message); 967 return 1; 968 } 969 } 970 catch (Exception e) 971 { 972 Message message = ERR_LDIFEXPORT_CANNOT_LOCK_BACKEND.get( 973 backend.getBackendID(), getExceptionMessage(e)); 974 logError(message); 975 return 1; 976 } 977 978 boolean errorOccurred = false; 979 980 // Launch the export. 981 try 982 { 983 backend.exportLDIF(exportConfig); 984 } 985 catch (DirectoryException de) 986 { 987 Message message = 988 ERR_LDIFEXPORT_ERROR_DURING_EXPORT.get(de.getMessageObject()); 989 logError(message); 990 errorOccurred = true; 991 } 992 catch (Exception e) 993 { 994 Message message = 995 ERR_LDIFEXPORT_ERROR_DURING_EXPORT.get(getExceptionMessage(e)); 996 logError(message); 997 errorOccurred = true; 998 } 999 1000 1001 // Release the shared lock on the backend. 1002 try 1003 { 1004 String lockFile = LockFileManager.getBackendLockFileName(backend); 1005 StringBuilder failureReason = new StringBuilder(); 1006 if (! LockFileManager.releaseLock(lockFile, failureReason)) 1007 { 1008 Message message = WARN_LDIFEXPORT_CANNOT_UNLOCK_BACKEND.get( 1009 backend.getBackendID(), String.valueOf(failureReason)); 1010 logError(message); 1011 } 1012 } 1013 catch (Exception e) 1014 { 1015 Message message = WARN_LDIFEXPORT_CANNOT_UNLOCK_BACKEND.get( 1016 backend.getBackendID(), getExceptionMessage(e)); 1017 logError(message); 1018 } 1019 1020 1021 // Clean up after the export by closing the export config. 1022 exportConfig.close(); 1023 if (!errorOccurred) 1024 { 1025 return 0; 1026 } 1027 else 1028 { 1029 return 1; 1030 } 1031 } 1032 } 1033