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