001/* 002 * Copyright 2013-2018 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2015-2018 Ping Identity Corporation 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021package com.unboundid.ldap.sdk.unboundidds.tasks; 022 023 024 025import java.util.ArrayList; 026import java.util.Arrays; 027import java.util.Collections; 028import java.util.Date; 029import java.util.LinkedHashMap; 030import java.util.List; 031import java.util.Map; 032 033import com.unboundid.ldap.sdk.Attribute; 034import com.unboundid.ldap.sdk.Entry; 035import com.unboundid.util.NotMutable; 036import com.unboundid.util.ThreadSafety; 037import com.unboundid.util.ThreadSafetyLevel; 038import com.unboundid.util.Validator; 039 040import static com.unboundid.ldap.sdk.unboundidds.tasks.TaskMessages.*; 041 042 043 044/** 045 * This class defines a Directory Server task that can be used to cause entries 046 * contained in a local DB backend to be re-encoded, which may be used to 047 * apply any configuration changes that affect the encoding of that entry (e.g., 048 * if the entry should be encrypted, hashed, compressed, or fully or partially 049 * uncached; or if these settings should be reverted). 050 * <BR> 051 * <BLOCKQUOTE> 052 * <B>NOTE:</B> This class, and other classes within the 053 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 054 * supported for use against Ping Identity, UnboundID, and 055 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 056 * for proprietary functionality or for external specifications that are not 057 * considered stable or mature enough to be guaranteed to work in an 058 * interoperable way with other types of LDAP servers. 059 * </BLOCKQUOTE> 060 * <BR> 061 * The properties that are available for use with this type of task include: 062 * <UL> 063 * <LI>The backend ID of the backend in which entries should be re-encoded. 064 * This must be provided.</LI> 065 * <LI>The base DN of a branch of entries to include in the re-encode 066 * processing.</LI> 067 * <LI>The base DN of a branch of entries to exclude from the re-encode 068 * processing.</LI> 069 * <LI>A filter to use to identify entries to include in the re-encode 070 * processing.</LI> 071 * <LI>A filter to use to identify entries to exclude from the re-encode 072 * processing.</LI> 073 * <LI>The maximum rate at which to re-encode entries, in number of entries 074 * per second.</LI> 075 * <LI>An indication as to whether to skip entries that are fully 076 * uncached.</LI> 077 * <LI>An indication as to whether to skip entries that are partially 078 * uncached.</LI> 079 * </UL> 080 */ 081@NotMutable() 082@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 083public final class ReEncodeEntriesTask 084 extends Task 085{ 086 /** 087 * The fully-qualified name of the Java class that is used for the re-encode 088 * entries task. 089 */ 090 static final String RE_ENCODE_ENTRIES_TASK_CLASS = 091 "com.unboundid.directory.server.tasks.ReEncodeEntriesTask"; 092 093 094 /** 095 * The name of the attribute used to specify the backend ID containing the 096 * entries to re-encode. 097 */ 098 private static final String ATTR_BACKEND_ID = "ds-task-reencode-backend-id"; 099 100 101 /** 102 * The name of the attribute used to specify the include branch(es). 103 */ 104 private static final String ATTR_INCLUDE_BRANCH = 105 "ds-task-reencode-include-branch"; 106 107 108 /** 109 * The name of the attribute used to specify the exclude branch(es). 110 */ 111 private static final String ATTR_EXCLUDE_BRANCH = 112 "ds-task-reencode-exclude-branch"; 113 114 115 /** 116 * The name of the attribute used to specify the include filter(s). 117 */ 118 private static final String ATTR_INCLUDE_FILTER = 119 "ds-task-reencode-include-filter"; 120 121 122 /** 123 * The name of the attribute used to specify the exclude filter(s). 124 */ 125 private static final String ATTR_EXCLUDE_FILTER = 126 "ds-task-reencode-exclude-filter"; 127 128 129 /** 130 * The name of the attribute used to specify the maximum re-encode rate in 131 * entries per second. 132 */ 133 private static final String ATTR_MAX_ENTRIES_PER_SECOND = 134 "ds-task-reencode-max-entries-per-second"; 135 136 137 /** 138 * The name of the attribute used to specify whether to skip fully uncached 139 * entries. 140 */ 141 private static final String ATTR_SKIP_FULLY_UNCACHED = 142 "ds-task-reencode-skip-fully-uncached-entries"; 143 144 145 /** 146 * The name of the attribute used to specify whether to skip partially 147 * uncached entries. 148 */ 149 private static final String ATTR_SKIP_PARTIALLY_UNCACHED = 150 "ds-task-reencode-skip-partially-uncached-entries"; 151 152 153 /** 154 * The name of the object class used in re-encode entries task entries. 155 */ 156 private static final String OC_REENCODE_ENTRIES_TASK = 157 "ds-task-reencode"; 158 159 160 /** 161 * The task property that will be used for the backend ID. 162 */ 163 static final TaskProperty PROPERTY_BACKEND_ID = 164 new TaskProperty(ATTR_BACKEND_ID, 165 INFO_DISPLAY_NAME_REENCODE_BACKEND_ID.get(), 166 INFO_DESCRIPTION_REENCODE_BACKEND_ID.get(), 167 String.class, true, false, false); 168 169 170 171 /** 172 * The task property that will be used for the include branch(es). 173 */ 174 private static final TaskProperty PROPERTY_INCLUDE_BRANCH = 175 new TaskProperty(ATTR_INCLUDE_BRANCH, 176 INFO_DISPLAY_NAME_REENCODE_INCLUDE_BRANCH.get(), 177 INFO_DESCRIPTION_REENCODE_INCLUDE_BRANCH.get(), 178 String.class, false, true, false); 179 180 181 182 /** 183 * The task property that will be used for the exclude branch(es). 184 */ 185 private static final TaskProperty PROPERTY_EXCLUDE_BRANCH = 186 new TaskProperty(ATTR_EXCLUDE_BRANCH, 187 INFO_DISPLAY_NAME_REENCODE_EXCLUDE_BRANCH.get(), 188 INFO_DESCRIPTION_REENCODE_EXCLUDE_BRANCH.get(), 189 String.class, false, true, false); 190 191 192 193 /** 194 * The task property that will be used for the include filter(s). 195 */ 196 private static final TaskProperty PROPERTY_INCLUDE_FILTER = 197 new TaskProperty(ATTR_INCLUDE_FILTER, 198 INFO_DISPLAY_NAME_REENCODE_INCLUDE_FILTER.get(), 199 INFO_DESCRIPTION_REENCODE_INCLUDE_FILTER.get(), 200 String.class, false, true, false); 201 202 203 204 /** 205 * The task property that will be used for the exclude filter(s). 206 */ 207 private static final TaskProperty PROPERTY_EXCLUDE_FILTER = 208 new TaskProperty(ATTR_EXCLUDE_FILTER, 209 INFO_DISPLAY_NAME_REENCODE_EXCLUDE_FILTER.get(), 210 INFO_DESCRIPTION_REENCODE_EXCLUDE_FILTER.get(), 211 String.class, false, true, false); 212 213 214 215 /** 216 * The task property that will be used for the maximum reencode rate. 217 */ 218 private static final TaskProperty PROPERTY_MAX_ENTRIES_PER_SECOND = 219 new TaskProperty(ATTR_MAX_ENTRIES_PER_SECOND, 220 INFO_DISPLAY_NAME_REENCODE_MAX_ENTRIES_PER_SECOND.get(), 221 INFO_DESCRIPTION_REENCODE_MAX_ENTRIES_PER_SECOND.get(), 222 Long.class, false, false, false); 223 224 225 226 /** 227 * The task property that will be used to indicate whether to skip fully 228 * uncached entries. 229 */ 230 private static final TaskProperty PROPERTY_SKIP_FULLY_UNCACHED = 231 new TaskProperty(ATTR_SKIP_FULLY_UNCACHED, 232 INFO_DISPLAY_NAME_REENCODE_SKIP_FULLY_UNCACHED.get(), 233 INFO_DESCRIPTION_REENCODE_SKIP_FULLY_UNCACHED.get(), 234 Boolean.class, false, false, false); 235 236 237 238 /** 239 * The task property that will be used to indicate whether to skip partially 240 * uncached entries. 241 */ 242 private static final TaskProperty PROPERTY_SKIP_PARTIALLY_UNCACHED = 243 new TaskProperty(ATTR_SKIP_PARTIALLY_UNCACHED, 244 INFO_DISPLAY_NAME_REENCODE_SKIP_PARTIALLY_UNCACHED.get(), 245 INFO_DESCRIPTION_REENCODE_SKIP_PARTIALLY_UNCACHED.get(), 246 Boolean.class, false, false, false); 247 248 249 250 /** 251 * The serial version UID for this serializable class. 252 */ 253 private static final long serialVersionUID = 1804218099237094046L; 254 255 256 257 // Indicates whether to skip fully-uncached entries. 258 private final boolean skipFullyUncachedEntries; 259 260 // Indicates whether to skip partially-uncached entries. 261 private final boolean skipPartiallyUncachedEntries; 262 263 // The maximum number of entries to re-encode per second. 264 private final Long maxEntriesPerSecond; 265 266 // The list of exclude branch DNs. 267 private final List<String> excludeBranches; 268 269 // The list of exclude filters. 270 private final List<String> excludeFilters; 271 272 // The list of include branch DNs. 273 private final List<String> includeBranches; 274 275 // The list of include filters. 276 private final List<String> includeFilters; 277 278 // The backend ID for the backend containing entries to re-encode. 279 private final String backendID; 280 281 282 283 /** 284 * Creates a new uninitialized re-encode entries task instance which should 285 * only be used for obtaining general information about this task, including 286 * the task name, description, and supported properties. Attempts to use a 287 * task created with this constructor for any other reason will likely fail. 288 */ 289 public ReEncodeEntriesTask() 290 { 291 skipFullyUncachedEntries = false; 292 skipPartiallyUncachedEntries = false; 293 maxEntriesPerSecond = null; 294 excludeBranches = null; 295 excludeFilters = null; 296 includeBranches = null; 297 includeFilters = null; 298 backendID = null; 299 } 300 301 302 303 /** 304 * Creates a new re-encode entries task with the provided information. 305 * 306 * @param taskID The task ID to use for this task. If 307 * it is {@code null} then a UUID will 308 * be generated for use as the task ID. 309 * @param backendID The backend ID of the backend 310 * containing the entries to re-encode. 311 * It must not be {@code null}. 312 * @param includeBranches A list containing the base DNs of 313 * branches to include in re-encode 314 * processing. It may be {@code null} 315 * or empty if there should not be any 316 * include branches. 317 * @param excludeBranches A list containing the base DNs of 318 * branches to exclude from re-encode 319 * processing. It may be {@code null} 320 * or empty if there should not be any 321 * exclude branches. 322 * @param includeFilters A list containing filters to use to 323 * identify entries to include in 324 * re-encode processing. It may be 325 * {@code null} or empty if there should 326 * not be any include filters. 327 * @param excludeFilters A list containing filters to use to 328 * identify entries to exclude from 329 * re-encode processing. It may be 330 * {@code null} or empty if there should 331 * not be any exclude filters. 332 * @param maxEntriesPerSecond The maximum number of entries to 333 * re-encode per second. It may be 334 * {@code null} to indicate that no 335 * limit should be imposed. 336 * @param skipFullyUncachedEntries Indicates whether to skip re-encode 337 * processing for entries that are fully 338 * uncached. 339 * @param skipPartiallyUncachedEntries Indicates whether to skip re-encode 340 * processing for entries that contain 341 * a mix of cached and uncached 342 * attributes. 343 */ 344 public ReEncodeEntriesTask(final String taskID, 345 final String backendID, 346 final List<String> includeBranches, 347 final List<String> excludeBranches, 348 final List<String> includeFilters, 349 final List<String> excludeFilters, 350 final Long maxEntriesPerSecond, 351 final boolean skipFullyUncachedEntries, 352 final boolean skipPartiallyUncachedEntries) 353 { 354 this(taskID, backendID, includeBranches, excludeBranches, includeFilters, 355 excludeFilters, maxEntriesPerSecond, skipFullyUncachedEntries, 356 skipPartiallyUncachedEntries, null, null, null, null, null); 357 } 358 359 360 361 /** 362 * Creates a new re-encode entries task with the provided information. 363 * 364 * @param taskID The task ID to use for this task. If 365 * it is {@code null} then a UUID will 366 * be generated for use as the task ID. 367 * @param backendID The backend ID of the backend 368 * containing the entries to re-encode. 369 * It must not be {@code null}. 370 * @param includeBranches A list containing the base DNs of 371 * branches to include in re-encode 372 * processing. It may be {@code null} 373 * or empty if there should not be any 374 * include branches. 375 * @param excludeBranches A list containing the base DNs of 376 * branches to exclude from re-encode 377 * processing. It may be {@code null} 378 * or empty if there should not be any 379 * exclude branches. 380 * @param includeFilters A list containing filters to use to 381 * identify entries to include in 382 * re-encode processing. It may be 383 * {@code null} or empty if there should 384 * not be any include filters. 385 * @param excludeFilters A list containing filters to use to 386 * identify entries to exclude from 387 * re-encode processing. It may be 388 * {@code null} or empty if there should 389 * not be any exclude filters. 390 * @param maxEntriesPerSecond The maximum number of entries to 391 * re-encode per second. It may be 392 * {@code null} to indicate that no 393 * limit should be imposed. 394 * @param skipFullyUncachedEntries Indicates whether to skip re-encode 395 * processing for entries that are fully 396 * uncached. 397 * @param skipPartiallyUncachedEntries Indicates whether to skip re-encode 398 * processing for entries that contain 399 * a mix of cached and uncached 400 * attributes. 401 * @param scheduledStartTime The time that this task should start 402 * running. 403 * @param dependencyIDs The list of task IDs that will be 404 * required to complete before this task 405 * will be eligible to start. 406 * @param failedDependencyAction Indicates what action should be taken 407 * if any of the dependencies for this 408 * task do not complete successfully. 409 * @param notifyOnCompletion The list of e-mail addresses of 410 * individuals that should be notified 411 * when this task completes. 412 * @param notifyOnError The list of e-mail addresses of 413 * individuals that should be notified 414 * if this task does not complete 415 * successfully. 416 */ 417 public ReEncodeEntriesTask(final String taskID, final String backendID, 418 final List<String> includeBranches, 419 final List<String> excludeBranches, 420 final List<String> includeFilters, 421 final List<String> excludeFilters, 422 final Long maxEntriesPerSecond, 423 final boolean skipFullyUncachedEntries, 424 final boolean skipPartiallyUncachedEntries, 425 final Date scheduledStartTime, 426 final List<String> dependencyIDs, 427 final FailedDependencyAction failedDependencyAction, 428 final List<String> notifyOnCompletion, 429 final List<String> notifyOnError) 430 { 431 this(taskID, backendID, includeBranches, excludeBranches, includeFilters, 432 excludeFilters, maxEntriesPerSecond, skipFullyUncachedEntries, 433 skipPartiallyUncachedEntries, scheduledStartTime, dependencyIDs, 434 failedDependencyAction, null, notifyOnCompletion, null, 435 notifyOnError, null, null, null); 436 } 437 438 439 440 /** 441 * Creates a new re-encode entries task with the provided information. 442 * 443 * @param taskID The task ID to use for this task. If 444 * it is {@code null} then a UUID will 445 * be generated for use as the task ID. 446 * @param backendID The backend ID of the backend 447 * containing the entries to re-encode. 448 * It must not be {@code null}. 449 * @param includeBranches A list containing the base DNs of 450 * branches to include in re-encode 451 * processing. It may be {@code null} 452 * or empty if there should not be any 453 * include branches. 454 * @param excludeBranches A list containing the base DNs of 455 * branches to exclude from re-encode 456 * processing. It may be {@code null} 457 * or empty if there should not be any 458 * exclude branches. 459 * @param includeFilters A list containing filters to use to 460 * identify entries to include in 461 * re-encode processing. It may be 462 * {@code null} or empty if there should 463 * not be any include filters. 464 * @param excludeFilters A list containing filters to use to 465 * identify entries to exclude from 466 * re-encode processing. It may be 467 * {@code null} or empty if there should 468 * not be any exclude filters. 469 * @param maxEntriesPerSecond The maximum number of entries to 470 * re-encode per second. It may be 471 * {@code null} to indicate that no 472 * limit should be imposed. 473 * @param skipFullyUncachedEntries Indicates whether to skip re-encode 474 * processing for entries that are fully 475 * uncached. 476 * @param skipPartiallyUncachedEntries Indicates whether to skip re-encode 477 * processing for entries that contain 478 * a mix of cached and uncached 479 * attributes. 480 * @param scheduledStartTime The time that this task should start 481 * running. 482 * @param dependencyIDs The list of task IDs that will be 483 * required to complete before this task 484 * will be eligible to start. 485 * @param failedDependencyAction Indicates what action should be taken 486 * if any of the dependencies for this 487 * task do not complete successfully. 488 * @param notifyOnStart The list of e-mail addresses of 489 * individuals that should be notified 490 * when this task starts running. 491 * @param notifyOnCompletion The list of e-mail addresses of 492 * individuals that should be notified 493 * when this task completes. 494 * @param notifyOnSuccess The list of e-mail addresses of 495 * individuals that should be notified 496 * if this task completes successfully. 497 * @param notifyOnError The list of e-mail addresses of 498 * individuals that should be notified 499 * if this task does not complete 500 * successfully. 501 * @param alertOnStart Indicates whether the server should 502 * send an alert notification when this 503 * task starts. 504 * @param alertOnSuccess Indicates whether the server should 505 * send an alert notification if this 506 * task completes successfully. 507 * @param alertOnError Indicates whether the server should 508 * send an alert notification if this 509 * task fails to complete successfully. 510 */ 511 public ReEncodeEntriesTask(final String taskID, final String backendID, 512 final List<String> includeBranches, 513 final List<String> excludeBranches, 514 final List<String> includeFilters, 515 final List<String> excludeFilters, 516 final Long maxEntriesPerSecond, 517 final boolean skipFullyUncachedEntries, 518 final boolean skipPartiallyUncachedEntries, 519 final Date scheduledStartTime, 520 final List<String> dependencyIDs, 521 final FailedDependencyAction failedDependencyAction, 522 final List<String> notifyOnStart, 523 final List<String> notifyOnCompletion, 524 final List<String> notifyOnSuccess, 525 final List<String> notifyOnError, final Boolean alertOnStart, 526 final Boolean alertOnSuccess, final Boolean alertOnError) 527 { 528 super(taskID, RE_ENCODE_ENTRIES_TASK_CLASS, scheduledStartTime, 529 dependencyIDs, failedDependencyAction, notifyOnStart, 530 notifyOnCompletion, notifyOnSuccess, notifyOnError, alertOnStart, 531 alertOnSuccess, alertOnError); 532 533 Validator.ensureNotNull(backendID); 534 535 this.backendID = backendID; 536 this.maxEntriesPerSecond = maxEntriesPerSecond; 537 this.skipFullyUncachedEntries = skipFullyUncachedEntries; 538 this.skipPartiallyUncachedEntries = skipPartiallyUncachedEntries; 539 540 if ((includeBranches == null) || includeBranches.isEmpty()) 541 { 542 this.includeBranches = Collections.emptyList(); 543 } 544 else 545 { 546 this.includeBranches = Collections.unmodifiableList(includeBranches); 547 } 548 549 if ((excludeBranches == null) || excludeBranches.isEmpty()) 550 { 551 this.excludeBranches = Collections.emptyList(); 552 } 553 else 554 { 555 this.excludeBranches = Collections.unmodifiableList(excludeBranches); 556 } 557 558 if ((includeFilters == null) || includeFilters.isEmpty()) 559 { 560 this.includeFilters = Collections.emptyList(); 561 } 562 else 563 { 564 this.includeFilters = Collections.unmodifiableList(includeFilters); 565 } 566 567 if ((excludeFilters == null) || excludeFilters.isEmpty()) 568 { 569 this.excludeFilters = Collections.emptyList(); 570 } 571 else 572 { 573 this.excludeFilters = Collections.unmodifiableList(excludeFilters); 574 } 575 } 576 577 578 579 /** 580 * Creates a new re-encode entries task from the provided entry. 581 * 582 * @param entry The entry to use to create this re-encode entries task. 583 * 584 * @throws TaskException If the provided entry cannot be parsed as a 585 * re-encode entries task entry. 586 */ 587 public ReEncodeEntriesTask(final Entry entry) 588 throws TaskException 589 { 590 super(entry); 591 592 593 // Get the backend ID. It must be present. 594 backendID = entry.getAttributeValue(ATTR_BACKEND_ID); 595 if (backendID == null) 596 { 597 throw new TaskException(ERR_REENCODE_TASK_MISSING_REQUIRED_ATTR.get( 598 entry.getDN(), ATTR_BACKEND_ID)); 599 } 600 601 // Get the set of include branches. 602 final String[] iBranches = entry.getAttributeValues(ATTR_INCLUDE_BRANCH); 603 if (iBranches == null) 604 { 605 includeBranches = Collections.emptyList(); 606 } 607 else 608 { 609 includeBranches = Collections.unmodifiableList(Arrays.asList(iBranches)); 610 } 611 612 // Get the set of exclude branches. 613 final String[] eBranches = entry.getAttributeValues(ATTR_EXCLUDE_BRANCH); 614 if (eBranches == null) 615 { 616 excludeBranches = Collections.emptyList(); 617 } 618 else 619 { 620 excludeBranches = Collections.unmodifiableList(Arrays.asList(eBranches)); 621 } 622 623 // Get the set of include filters. 624 final String[] iFilters = entry.getAttributeValues(ATTR_INCLUDE_FILTER); 625 if (iFilters == null) 626 { 627 includeFilters = Collections.emptyList(); 628 } 629 else 630 { 631 includeFilters = Collections.unmodifiableList(Arrays.asList(iFilters)); 632 } 633 634 // Get the set of exclude filters. 635 final String[] eFilters = entry.getAttributeValues(ATTR_EXCLUDE_FILTER); 636 if (eFilters == null) 637 { 638 excludeFilters = Collections.emptyList(); 639 } 640 else 641 { 642 excludeFilters = Collections.unmodifiableList(Arrays.asList(eFilters)); 643 } 644 645 // Get the max entry rate. 646 maxEntriesPerSecond = 647 entry.getAttributeValueAsLong(ATTR_MAX_ENTRIES_PER_SECOND); 648 649 // Determine whether to skip fully uncached entries. 650 final Boolean skipFullyUncached = 651 entry.getAttributeValueAsBoolean(ATTR_SKIP_FULLY_UNCACHED); 652 if (skipFullyUncached == null) 653 { 654 skipFullyUncachedEntries = false; 655 } 656 else 657 { 658 skipFullyUncachedEntries = skipFullyUncached; 659 } 660 661 // Determine whether to skip partially uncached entries. 662 final Boolean skipPartiallyUncached = 663 entry.getAttributeValueAsBoolean(ATTR_SKIP_PARTIALLY_UNCACHED); 664 if (skipPartiallyUncached == null) 665 { 666 skipPartiallyUncachedEntries = false; 667 } 668 else 669 { 670 skipPartiallyUncachedEntries = skipPartiallyUncached; 671 } 672 } 673 674 675 676 /** 677 * Creates a new re-encode entries task from the provided set of task 678 * properties. 679 * 680 * @param properties The set of task properties and their corresponding 681 * values to use for the task. It must not be 682 * {@code null}. 683 * 684 * @throws TaskException If the provided set of properties cannot be used to 685 * create a valid re-encode entries task. 686 */ 687 public ReEncodeEntriesTask(final Map<TaskProperty,List<Object>> properties) 688 throws TaskException 689 { 690 super(RE_ENCODE_ENTRIES_TASK_CLASS, properties); 691 692 boolean skipFullyUncached = false; 693 boolean skipPartiallyUncached = false; 694 Long maxRate = null; 695 List<String> eBranches = Collections.emptyList(); 696 List<String> eFilters = Collections.emptyList(); 697 List<String> iBranches = Collections.emptyList(); 698 List<String> iFilters = Collections.emptyList(); 699 String id = null; 700 701 for (final Map.Entry<TaskProperty,List<Object>> e : properties.entrySet()) 702 { 703 final TaskProperty p = e.getKey(); 704 final String attrName = p.getAttributeName(); 705 final List<Object> values = e.getValue(); 706 707 if (attrName.equalsIgnoreCase(ATTR_BACKEND_ID)) 708 { 709 id = parseString(p, values, null); 710 } 711 else if (attrName.equalsIgnoreCase(ATTR_INCLUDE_BRANCH)) 712 { 713 final String[] branches = parseStrings(p, values, null); 714 if (branches != null) 715 { 716 iBranches = Collections.unmodifiableList(Arrays.asList(branches)); 717 } 718 } 719 else if (attrName.equalsIgnoreCase(ATTR_EXCLUDE_BRANCH)) 720 { 721 final String[] branches = parseStrings(p, values, null); 722 if (branches != null) 723 { 724 eBranches = Collections.unmodifiableList(Arrays.asList(branches)); 725 } 726 } 727 else if (attrName.equalsIgnoreCase(ATTR_INCLUDE_FILTER)) 728 { 729 final String[] filters = parseStrings(p, values, null); 730 if (filters != null) 731 { 732 iFilters = Collections.unmodifiableList(Arrays.asList(filters)); 733 } 734 } 735 else if (attrName.equalsIgnoreCase(ATTR_EXCLUDE_FILTER)) 736 { 737 final String[] filters = parseStrings(p, values, null); 738 if (filters != null) 739 { 740 eFilters = Collections.unmodifiableList(Arrays.asList(filters)); 741 } 742 } 743 else if (attrName.equalsIgnoreCase(ATTR_MAX_ENTRIES_PER_SECOND)) 744 { 745 maxRate = parseLong(p, values, null); 746 } 747 else if (attrName.equalsIgnoreCase(ATTR_SKIP_FULLY_UNCACHED)) 748 { 749 skipFullyUncached = parseBoolean(p, values, false); 750 } 751 else if (attrName.equalsIgnoreCase(ATTR_SKIP_PARTIALLY_UNCACHED)) 752 { 753 skipPartiallyUncached = parseBoolean(p, values, false); 754 } 755 } 756 757 if (id == null) 758 { 759 throw new TaskException(ERR_REENCODE_TASK_MISSING_REQUIRED_PROPERTY.get( 760 ATTR_BACKEND_ID)); 761 } 762 763 backendID = id; 764 includeBranches = iBranches; 765 excludeBranches = eBranches; 766 includeFilters = iFilters; 767 excludeFilters = eFilters; 768 maxEntriesPerSecond = maxRate; 769 skipFullyUncachedEntries = skipFullyUncached; 770 skipPartiallyUncachedEntries = skipPartiallyUncached; 771 } 772 773 774 775 /** 776 * {@inheritDoc} 777 */ 778 @Override() 779 public String getTaskName() 780 { 781 return INFO_TASK_NAME_REENCODE_ENTRIES.get(); 782 } 783 784 785 786 /** 787 * {@inheritDoc} 788 */ 789 @Override() 790 public String getTaskDescription() 791 { 792 return INFO_TASK_DESCRIPTION_REENCODE_ENTRIES.get(); 793 } 794 795 796 797 /** 798 * Retrieves the backend ID for the backend containing the entries to 799 * re-encode. 800 * 801 * @return The backend ID for the backend containing the entries to 802 * re-encode. 803 */ 804 public String getBackendID() 805 { 806 return backendID; 807 } 808 809 810 811 /** 812 * Retrieves the base DNs of the branches to include in re-encode processing, 813 * if defined. 814 * 815 * @return The base DNs of the branches to include in re-encode processing, 816 * or an empty list if there should not be any include branches. 817 */ 818 public List<String> getIncludeBranches() 819 { 820 return includeBranches; 821 } 822 823 824 825 /** 826 * Retrieves the base DNs of the branches to exclude from re-encode 827 * processing, if defined. 828 * 829 * @return The base DNs of the branches to exclude from re-encode processing, 830 * or an empty list if there should not be any exclude branches. 831 */ 832 public List<String> getExcludeBranches() 833 { 834 return excludeBranches; 835 } 836 837 838 839 /** 840 * Retrieves a set of filters to use to identify entries to include in 841 * re-encode processing, if defined. 842 * 843 * @return A set of filters to use to identify entries to include in 844 * re-encode processing, or an empty list if there should not be any 845 * include filters. 846 */ 847 public List<String> getIncludeFilters() 848 { 849 return includeFilters; 850 } 851 852 853 854 /** 855 * Retrieves a set of filters to use to identify entries to exclude from 856 * re-encode processing, if defined. 857 * 858 * @return A set of filters to use to identify entries to exclude from 859 * re-encode processing, or an empty list if there should not be any 860 * exclude filters. 861 */ 862 public List<String> getExcludeFilters() 863 { 864 return excludeFilters; 865 } 866 867 868 869 /** 870 * Retrieves the maximum number of entries that should be re-encoded per 871 * second, if defined. 872 * 873 * @return The maximum number of entries that should be re-encoded per 874 * second, or {@code null} if no rate limit should be imposed. 875 */ 876 public Long getMaxEntriesPerSecond() 877 { 878 return maxEntriesPerSecond; 879 } 880 881 882 883 /** 884 * Indicates whether to skip re-encode processing for entries that are stored 885 * as fully uncached. 886 * 887 * @return {@code true} if fully uncached entries should be skipped, or 888 * {@code false} if not. 889 */ 890 public boolean skipFullyUncachedEntries() 891 { 892 return skipFullyUncachedEntries; 893 } 894 895 896 897 /** 898 * Indicates whether to skip re-encode processing for entries that have a 899 * mix of cached and uncached attributes. 900 * 901 * @return {@code true} if partially uncached entries should be skipped, or 902 * {@code false} if not. 903 */ 904 public boolean skipPartiallyUncachedEntries() 905 { 906 return skipPartiallyUncachedEntries; 907 } 908 909 910 911 /** 912 * {@inheritDoc} 913 */ 914 @Override() 915 protected List<String> getAdditionalObjectClasses() 916 { 917 return Collections.singletonList(OC_REENCODE_ENTRIES_TASK); 918 } 919 920 921 922 /** 923 * {@inheritDoc} 924 */ 925 @Override() 926 protected List<Attribute> getAdditionalAttributes() 927 { 928 final ArrayList<Attribute> attrList = new ArrayList<>(7); 929 attrList.add(new Attribute(ATTR_BACKEND_ID, backendID)); 930 attrList.add(new Attribute(ATTR_SKIP_FULLY_UNCACHED, 931 String.valueOf(skipFullyUncachedEntries))); 932 attrList.add(new Attribute(ATTR_SKIP_PARTIALLY_UNCACHED, 933 String.valueOf(skipPartiallyUncachedEntries))); 934 935 if (! includeBranches.isEmpty()) 936 { 937 attrList.add(new Attribute(ATTR_INCLUDE_BRANCH, includeBranches)); 938 } 939 940 if (! excludeBranches.isEmpty()) 941 { 942 attrList.add(new Attribute(ATTR_EXCLUDE_BRANCH, excludeBranches)); 943 } 944 945 if (! includeFilters.isEmpty()) 946 { 947 attrList.add(new Attribute(ATTR_INCLUDE_FILTER, includeFilters)); 948 } 949 950 if (! excludeFilters.isEmpty()) 951 { 952 attrList.add(new Attribute(ATTR_EXCLUDE_FILTER, excludeFilters)); 953 } 954 955 if (maxEntriesPerSecond != null) 956 { 957 attrList.add(new Attribute(ATTR_MAX_ENTRIES_PER_SECOND, 958 String.valueOf(maxEntriesPerSecond))); 959 } 960 961 return attrList; 962 } 963 964 965 966 /** 967 * {@inheritDoc} 968 */ 969 @Override() 970 public List<TaskProperty> getTaskSpecificProperties() 971 { 972 return Collections.unmodifiableList(Arrays.asList( 973 PROPERTY_BACKEND_ID, 974 PROPERTY_INCLUDE_BRANCH, 975 PROPERTY_EXCLUDE_BRANCH, 976 PROPERTY_INCLUDE_FILTER, 977 PROPERTY_EXCLUDE_FILTER, 978 PROPERTY_MAX_ENTRIES_PER_SECOND, 979 PROPERTY_SKIP_FULLY_UNCACHED, 980 PROPERTY_SKIP_PARTIALLY_UNCACHED)); 981 } 982 983 984 985 /** 986 * {@inheritDoc} 987 */ 988 @Override() 989 public Map<TaskProperty,List<Object>> getTaskPropertyValues() 990 { 991 final LinkedHashMap<TaskProperty,List<Object>> props = 992 new LinkedHashMap<>(15); 993 994 props.put(PROPERTY_BACKEND_ID, 995 Collections.<Object>singletonList(backendID)); 996 props.put(PROPERTY_INCLUDE_BRANCH, 997 Collections.<Object>unmodifiableList(includeBranches)); 998 props.put(PROPERTY_EXCLUDE_BRANCH, 999 Collections.<Object>unmodifiableList(excludeBranches)); 1000 props.put(PROPERTY_INCLUDE_FILTER, 1001 Collections.<Object>unmodifiableList(includeFilters)); 1002 props.put(PROPERTY_EXCLUDE_FILTER, 1003 Collections.<Object>unmodifiableList(excludeFilters)); 1004 1005 if (maxEntriesPerSecond == null) 1006 { 1007 props.put(PROPERTY_MAX_ENTRIES_PER_SECOND, 1008 Collections.emptyList()); 1009 } 1010 else 1011 { 1012 props.put(PROPERTY_MAX_ENTRIES_PER_SECOND, 1013 Collections.<Object>singletonList(maxEntriesPerSecond)); 1014 } 1015 1016 props.put(PROPERTY_SKIP_FULLY_UNCACHED, 1017 Collections.<Object>singletonList(skipFullyUncachedEntries)); 1018 props.put(PROPERTY_SKIP_PARTIALLY_UNCACHED, 1019 Collections.<Object>singletonList(skipPartiallyUncachedEntries)); 1020 1021 props.putAll(super.getTaskPropertyValues()); 1022 return Collections.unmodifiableMap(props); 1023 } 1024}