001/* 002 * Copyright 2014-2023 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2014-2023 Ping Identity Corporation 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020/* 021 * Copyright (C) 2014-2023 Ping Identity Corporation 022 * 023 * This program is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU General Public License (GPLv2 only) 025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 026 * as published by the Free Software Foundation. 027 * 028 * This program is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 031 * GNU General Public License for more details. 032 * 033 * You should have received a copy of the GNU General Public License 034 * along with this program; if not, see <http://www.gnu.org/licenses>. 035 */ 036package com.unboundid.ldap.listener.interceptor; 037 038 039 040import java.util.List; 041import java.util.HashMap; 042import java.util.Map; 043 044import com.unboundid.ldap.listener.IntermediateResponseTransformer; 045import com.unboundid.ldap.listener.LDAPListenerClientConnection; 046import com.unboundid.ldap.listener.LDAPListenerRequestHandler; 047import com.unboundid.ldap.listener.SearchEntryTransformer; 048import com.unboundid.ldap.listener.SearchReferenceTransformer; 049import com.unboundid.ldap.protocol.AddRequestProtocolOp; 050import com.unboundid.ldap.protocol.AddResponseProtocolOp; 051import com.unboundid.ldap.protocol.BindRequestProtocolOp; 052import com.unboundid.ldap.protocol.BindResponseProtocolOp; 053import com.unboundid.ldap.protocol.CompareRequestProtocolOp; 054import com.unboundid.ldap.protocol.CompareResponseProtocolOp; 055import com.unboundid.ldap.protocol.DeleteRequestProtocolOp; 056import com.unboundid.ldap.protocol.DeleteResponseProtocolOp; 057import com.unboundid.ldap.protocol.ExtendedRequestProtocolOp; 058import com.unboundid.ldap.protocol.ExtendedResponseProtocolOp; 059import com.unboundid.ldap.protocol.IntermediateResponseProtocolOp; 060import com.unboundid.ldap.protocol.LDAPMessage; 061import com.unboundid.ldap.protocol.ModifyRequestProtocolOp; 062import com.unboundid.ldap.protocol.ModifyResponseProtocolOp; 063import com.unboundid.ldap.protocol.ModifyDNRequestProtocolOp; 064import com.unboundid.ldap.protocol.ModifyDNResponseProtocolOp; 065import com.unboundid.ldap.protocol.SearchRequestProtocolOp; 066import com.unboundid.ldap.protocol.SearchResultDoneProtocolOp; 067import com.unboundid.ldap.protocol.SearchResultEntryProtocolOp; 068import com.unboundid.ldap.protocol.SearchResultReferenceProtocolOp; 069import com.unboundid.ldap.sdk.AddRequest; 070import com.unboundid.ldap.sdk.CompareRequest; 071import com.unboundid.ldap.sdk.Control; 072import com.unboundid.ldap.sdk.DeleteRequest; 073import com.unboundid.ldap.sdk.LDAPException; 074import com.unboundid.ldap.sdk.ModifyRequest; 075import com.unboundid.ldap.sdk.ModifyDNRequest; 076import com.unboundid.ldap.sdk.ResultCode; 077import com.unboundid.ldap.sdk.SearchRequest; 078import com.unboundid.util.Debug; 079import com.unboundid.util.NotNull; 080import com.unboundid.util.Nullable; 081import com.unboundid.util.ObjectPair; 082import com.unboundid.util.ThreadSafety; 083import com.unboundid.util.ThreadSafetyLevel; 084import com.unboundid.util.StaticUtils; 085 086import static com.unboundid.ldap.listener.interceptor.InterceptorMessages.*; 087 088 089 090/** 091 * This class provides an LDAP listener request handler that may be used to 092 * invoke any in-memory operation interceptors in the course of processing 093 * operations for the in-memory directory server. 094 */ 095@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 096public final class InMemoryOperationInterceptorRequestHandler 097 extends LDAPListenerRequestHandler 098 implements IntermediateResponseTransformer, SearchEntryTransformer, 099 SearchReferenceTransformer 100{ 101 // The set of interceptors to be used to transform requests and responses. 102 @NotNull private final InMemoryOperationInterceptor[] interceptors; 103 104 // The client connection associated with this request handler instance. 105 @Nullable private final LDAPListenerClientConnection connection; 106 107 // The request handler that will be used to ensure that operations actually 108 // get processed. 109 @NotNull private final LDAPListenerRequestHandler wrappedHandler; 110 111 // A map containing active operations mapped by message ID. 112 @NotNull private final Map<Integer,InterceptedOperation> activeOperations; 113 114 115 116 /** 117 * Creates a new instance of this LDAP listener request handler that will be 118 * used to process the provided set of operation interceptors. 119 * 120 * @param interceptors The set of operation interceptors that will be used 121 * to transform requests and responses. If there are 122 * multiple interceptors, then they will be invoked in 123 * the same order as elements in the provided list 124 * when processing both requests and results. 125 * @param wrappedHandler The request handler that will be used to ensure 126 * that operations actually get processed. 127 */ 128 public InMemoryOperationInterceptorRequestHandler( 129 @NotNull final List<InMemoryOperationInterceptor> interceptors, 130 @NotNull final LDAPListenerRequestHandler wrappedHandler) 131 { 132 this.wrappedHandler = wrappedHandler; 133 134 this.interceptors = new InMemoryOperationInterceptor[interceptors.size()]; 135 interceptors.toArray(this.interceptors); 136 137 connection = null; 138 activeOperations = new HashMap<>(StaticUtils.computeMapCapacity(5)); 139 } 140 141 142 143 /** 144 * Creates a new instance of this LDAP listener request handler that will be 145 * used to process the provided set of operation interceptors. 146 * 147 * @param interceptors The set of operation interceptors that will be used 148 * to transform requests and responses. If there are 149 * multiple interceptors, then they will be invoked in 150 * the same order as elements in the provided list 151 * when processing both requests and results. 152 * @param wrappedHandler The request handler that will be used to ensure 153 * that operations actually get processed. 154 * @param connection The client connection associated with this request 155 * handler instance. 156 */ 157 private InMemoryOperationInterceptorRequestHandler( 158 @NotNull final InMemoryOperationInterceptor[] interceptors, 159 @NotNull final LDAPListenerRequestHandler wrappedHandler, 160 @NotNull final LDAPListenerClientConnection connection) 161 { 162 this.interceptors = interceptors; 163 this.wrappedHandler = wrappedHandler; 164 this.connection = connection; 165 166 activeOperations = new HashMap<>(StaticUtils.computeMapCapacity(5)); 167 } 168 169 170 171 /** 172 * {@inheritDoc} 173 */ 174 @Override() 175 @NotNull() 176 public InMemoryOperationInterceptorRequestHandler newInstance( 177 @NotNull final LDAPListenerClientConnection connection) 178 throws LDAPException 179 { 180 final InMemoryOperationInterceptorRequestHandler handler = 181 new InMemoryOperationInterceptorRequestHandler(interceptors, 182 wrappedHandler.newInstance(connection), connection); 183 184 connection.addSearchEntryTransformer(handler); 185 connection.addSearchReferenceTransformer(handler); 186 connection.addIntermediateResponseTransformer(handler); 187 188 return handler; 189 } 190 191 192 193 /** 194 * {@inheritDoc} 195 */ 196 @Override() 197 @NotNull() 198 public LDAPMessage processAddRequest(final int messageID, 199 @NotNull final AddRequestProtocolOp request, 200 @NotNull final List<Control> controls) 201 { 202 final InterceptedAddOperation op = new InterceptedAddOperation(connection, 203 messageID, request, toArray(controls)); 204 activeOperations.put(messageID, op); 205 206 try 207 { 208 for (final InMemoryOperationInterceptor i : interceptors) 209 { 210 try 211 { 212 i.processAddRequest(op); 213 } 214 catch (final LDAPException le) 215 { 216 Debug.debugException(le); 217 return new LDAPMessage(messageID, 218 new AddResponseProtocolOp(le.toLDAPResult()), 219 le.getResponseControls()); 220 } 221 catch (final Exception e) 222 { 223 Debug.debugException(e); 224 return new LDAPMessage(messageID, 225 new AddResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, 226 ERR_DS_INTERCEPTOR_REQUEST_ERROR.get( 227 String.valueOf(op), i.getClass().getName(), 228 StaticUtils.getExceptionMessage(e)), 229 null 230 ) 231 ); 232 } 233 } 234 235 final LDAPMessage resultMessage = wrappedHandler.processAddRequest( 236 messageID, 237 new AddRequestProtocolOp((AddRequest) op.getRequest()), 238 op.getRequest().getControlList()); 239 op.setResult(resultMessage.getAddResponseProtocolOp().toLDAPResult( 240 toArray(resultMessage.getControls()))); 241 for (final InMemoryOperationInterceptor i : interceptors) 242 { 243 try 244 { 245 i.processAddResult(op); 246 } 247 catch (final Exception e) 248 { 249 Debug.debugException(e); 250 return new LDAPMessage(messageID, 251 new AddResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, 252 ERR_DS_INTERCEPTOR_RESULT_ERROR.get( 253 String.valueOf(op), i.getClass().getName(), 254 StaticUtils.getExceptionMessage(e)), 255 null 256 ) 257 ); 258 } 259 } 260 261 return new LDAPMessage(messageID, 262 new AddResponseProtocolOp(op.getResult()), 263 op.getResult().getResponseControls()); 264 } 265 finally 266 { 267 activeOperations.remove(messageID); 268 } 269 } 270 271 272 273 /** 274 * {@inheritDoc} 275 */ 276 @Override() 277 @NotNull() 278 public LDAPMessage processBindRequest(final int messageID, 279 @NotNull final BindRequestProtocolOp request, 280 @NotNull final List<Control> controls) 281 { 282 if (request.getCredentialsType() == BindRequestProtocolOp.CRED_TYPE_SIMPLE) 283 { 284 final InterceptedSimpleBindOperation op = 285 new InterceptedSimpleBindOperation(connection, messageID, request, 286 toArray(controls)); 287 activeOperations.put(messageID, op); 288 289 try 290 { 291 for (final InMemoryOperationInterceptor i : interceptors) 292 { 293 try 294 { 295 i.processSimpleBindRequest(op); 296 } 297 catch (final LDAPException le) 298 { 299 Debug.debugException(le); 300 return new LDAPMessage(messageID, 301 new BindResponseProtocolOp(le.toLDAPResult()), 302 le.getResponseControls()); 303 } 304 catch (final Exception e) 305 { 306 Debug.debugException(e); 307 return new LDAPMessage(messageID, 308 new BindResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, 309 ERR_DS_INTERCEPTOR_REQUEST_ERROR.get( 310 String.valueOf(op), i.getClass().getName(), 311 StaticUtils.getExceptionMessage(e)), 312 null, null)); 313 } 314 } 315 316 final LDAPMessage resultMessage = wrappedHandler.processBindRequest( 317 messageID, 318 new BindRequestProtocolOp(op.getRequest()), 319 op.getRequest().getControlList()); 320 op.setResult(resultMessage.getBindResponseProtocolOp().toBindResult( 321 toArray(resultMessage.getControls()))); 322 for (final InMemoryOperationInterceptor i : interceptors) 323 { 324 try 325 { 326 i.processSimpleBindResult(op); 327 } 328 catch (final Exception e) 329 { 330 Debug.debugException(e); 331 return new LDAPMessage(messageID, 332 new BindResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, 333 ERR_DS_INTERCEPTOR_RESULT_ERROR.get( 334 String.valueOf(op), i.getClass().getName(), 335 StaticUtils.getExceptionMessage(e)), 336 null, null)); 337 } 338 } 339 340 return new LDAPMessage(messageID, 341 new BindResponseProtocolOp(op.getResult()), 342 op.getResult().getResponseControls()); 343 } 344 finally 345 { 346 activeOperations.remove(messageID); 347 } 348 } 349 else 350 { 351 final InterceptedSASLBindOperation op = 352 new InterceptedSASLBindOperation(connection, messageID, request, 353 toArray(controls)); 354 activeOperations.put(messageID, op); 355 356 try 357 { 358 for (final InMemoryOperationInterceptor i : interceptors) 359 { 360 try 361 { 362 i.processSASLBindRequest(op); 363 } 364 catch (final LDAPException le) 365 { 366 Debug.debugException(le); 367 return new LDAPMessage(messageID, 368 new BindResponseProtocolOp(le.toLDAPResult()), 369 le.getResponseControls()); 370 } 371 catch (final Exception e) 372 { 373 Debug.debugException(e); 374 return new LDAPMessage(messageID, 375 new BindResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, 376 ERR_DS_INTERCEPTOR_REQUEST_ERROR.get( 377 String.valueOf(op), i.getClass().getName(), 378 StaticUtils.getExceptionMessage(e)), 379 null, null)); 380 } 381 } 382 383 final LDAPMessage resultMessage = wrappedHandler.processBindRequest( 384 messageID, 385 new BindRequestProtocolOp(op.getRequest()), 386 op.getRequest().getControlList()); 387 op.setResult(resultMessage.getBindResponseProtocolOp().toBindResult( 388 toArray(resultMessage.getControls()))); 389 for (final InMemoryOperationInterceptor i : interceptors) 390 { 391 try 392 { 393 i.processSASLBindResult(op); 394 } 395 catch (final Exception e) 396 { 397 Debug.debugException(e); 398 return new LDAPMessage(messageID, 399 new BindResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, 400 ERR_DS_INTERCEPTOR_RESULT_ERROR.get( 401 String.valueOf(op), i.getClass().getName(), 402 StaticUtils.getExceptionMessage(e)), 403 null, null)); 404 } 405 } 406 407 return new LDAPMessage(messageID, 408 new BindResponseProtocolOp(op.getResult()), 409 op.getResult().getResponseControls()); 410 } 411 finally 412 { 413 activeOperations.remove(messageID); 414 } 415 } 416 } 417 418 419 420 /** 421 * {@inheritDoc} 422 */ 423 @Override() 424 @NotNull() 425 public LDAPMessage processCompareRequest(final int messageID, 426 @NotNull final CompareRequestProtocolOp request, 427 @NotNull final List<Control> controls) 428 { 429 final InterceptedCompareOperation op = 430 new InterceptedCompareOperation(connection, messageID, request, 431 toArray(controls)); 432 activeOperations.put(messageID, op); 433 434 try 435 { 436 for (final InMemoryOperationInterceptor i : interceptors) 437 { 438 try 439 { 440 i.processCompareRequest(op); 441 } 442 catch (final LDAPException le) 443 { 444 Debug.debugException(le); 445 return new LDAPMessage(messageID, 446 new CompareResponseProtocolOp(le.toLDAPResult()), 447 le.getResponseControls()); 448 } 449 catch (final Exception e) 450 { 451 Debug.debugException(e); 452 return new LDAPMessage(messageID, 453 new CompareResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, 454 ERR_DS_INTERCEPTOR_REQUEST_ERROR.get( 455 String.valueOf(op), i.getClass().getName(), 456 StaticUtils.getExceptionMessage(e)), 457 null)); 458 } 459 } 460 461 final LDAPMessage resultMessage = wrappedHandler.processCompareRequest( 462 messageID, 463 new CompareRequestProtocolOp((CompareRequest) op.getRequest()), 464 op.getRequest().getControlList()); 465 op.setResult(resultMessage.getCompareResponseProtocolOp().toLDAPResult( 466 toArray(resultMessage.getControls()))); 467 for (final InMemoryOperationInterceptor i : interceptors) 468 { 469 try 470 { 471 i.processCompareResult(op); 472 } 473 catch (final Exception e) 474 { 475 Debug.debugException(e); 476 return new LDAPMessage(messageID, 477 new CompareResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, 478 ERR_DS_INTERCEPTOR_RESULT_ERROR.get( 479 String.valueOf(op), i.getClass().getName(), 480 StaticUtils.getExceptionMessage(e)), 481 null)); 482 } 483 } 484 485 return new LDAPMessage(messageID, 486 new CompareResponseProtocolOp(op.getResult()), 487 op.getResult().getResponseControls()); 488 } 489 finally 490 { 491 activeOperations.remove(messageID); 492 } 493 } 494 495 496 497 /** 498 * {@inheritDoc} 499 */ 500 @Override() 501 @NotNull() 502 public LDAPMessage processDeleteRequest(final int messageID, 503 @NotNull final DeleteRequestProtocolOp request, 504 @NotNull final List<Control> controls) 505 { 506 final InterceptedDeleteOperation op = 507 new InterceptedDeleteOperation(connection, messageID, request, 508 toArray(controls)); 509 activeOperations.put(messageID, op); 510 511 try 512 { 513 for (final InMemoryOperationInterceptor i : interceptors) 514 { 515 try 516 { 517 i.processDeleteRequest(op); 518 } 519 catch (final LDAPException le) 520 { 521 Debug.debugException(le); 522 return new LDAPMessage(messageID, 523 new DeleteResponseProtocolOp(le.toLDAPResult()), 524 le.getResponseControls()); 525 } 526 catch (final Exception e) 527 { 528 Debug.debugException(e); 529 return new LDAPMessage(messageID, 530 new DeleteResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, 531 ERR_DS_INTERCEPTOR_REQUEST_ERROR.get( 532 String.valueOf(op), i.getClass().getName(), 533 StaticUtils.getExceptionMessage(e)), 534 null)); 535 } 536 } 537 538 final LDAPMessage resultMessage = wrappedHandler.processDeleteRequest( 539 messageID, 540 new DeleteRequestProtocolOp((DeleteRequest) op.getRequest()), 541 op.getRequest().getControlList()); 542 op.setResult(resultMessage.getDeleteResponseProtocolOp().toLDAPResult( 543 toArray(resultMessage.getControls()))); 544 for (final InMemoryOperationInterceptor i : interceptors) 545 { 546 try 547 { 548 i.processDeleteResult(op); 549 } 550 catch (final Exception e) 551 { 552 Debug.debugException(e); 553 return new LDAPMessage(messageID, 554 new DeleteResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, 555 ERR_DS_INTERCEPTOR_RESULT_ERROR.get( 556 String.valueOf(op), i.getClass().getName(), 557 StaticUtils.getExceptionMessage(e)), 558 null)); 559 } 560 } 561 562 return new LDAPMessage(messageID, 563 new DeleteResponseProtocolOp(op.getResult()), 564 op.getResult().getResponseControls()); 565 } 566 finally 567 { 568 activeOperations.remove(messageID); 569 } 570 } 571 572 573 574 /** 575 * {@inheritDoc} 576 */ 577 @Override() 578 @NotNull() 579 public LDAPMessage processExtendedRequest(final int messageID, 580 @NotNull final ExtendedRequestProtocolOp request, 581 @NotNull final List<Control> controls) 582 { 583 final InterceptedExtendedOperation op = 584 new InterceptedExtendedOperation(connection, messageID, request, 585 toArray(controls)); 586 activeOperations.put(messageID, op); 587 588 try 589 { 590 for (final InMemoryOperationInterceptor i : interceptors) 591 { 592 try 593 { 594 i.processExtendedRequest(op); 595 } 596 catch (final LDAPException le) 597 { 598 Debug.debugException(le); 599 return new LDAPMessage(messageID, 600 new ExtendedResponseProtocolOp(le.toLDAPResult()), 601 le.getResponseControls()); 602 } 603 catch (final Exception e) 604 { 605 Debug.debugException(e); 606 return new LDAPMessage(messageID, 607 new ExtendedResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, 608 ERR_DS_INTERCEPTOR_REQUEST_ERROR.get( 609 String.valueOf(op), i.getClass().getName(), 610 StaticUtils.getExceptionMessage(e)), 611 null, null, null)); 612 } 613 } 614 615 final LDAPMessage resultMessage = wrappedHandler.processExtendedRequest( 616 messageID, 617 new ExtendedRequestProtocolOp(op.getRequest()), 618 op.getRequest().getControlList()); 619 op.setResult( 620 resultMessage.getExtendedResponseProtocolOp().toExtendedResult( 621 toArray(resultMessage.getControls()))); 622 for (final InMemoryOperationInterceptor i : interceptors) 623 { 624 try 625 { 626 i.processExtendedResult(op); 627 } 628 catch (final Exception e) 629 { 630 Debug.debugException(e); 631 return new LDAPMessage(messageID, 632 new ExtendedResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, 633 ERR_DS_INTERCEPTOR_RESULT_ERROR.get( 634 String.valueOf(op), i.getClass().getName(), 635 StaticUtils.getExceptionMessage(e)), 636 null, null, null)); 637 } 638 } 639 640 return new LDAPMessage(messageID, 641 new ExtendedResponseProtocolOp(op.getResult()), 642 op.getResult().getResponseControls()); 643 } 644 finally 645 { 646 activeOperations.remove(messageID); 647 } 648 } 649 650 651 652 /** 653 * {@inheritDoc} 654 */ 655 @Override() 656 @NotNull() 657 public LDAPMessage processModifyRequest(final int messageID, 658 @NotNull final ModifyRequestProtocolOp request, 659 @NotNull final List<Control> controls) 660 { 661 final InterceptedModifyOperation op = 662 new InterceptedModifyOperation(connection, messageID, request, 663 toArray(controls)); 664 activeOperations.put(messageID, op); 665 666 try 667 { 668 for (final InMemoryOperationInterceptor i : interceptors) 669 { 670 try 671 { 672 i.processModifyRequest(op); 673 } 674 catch (final LDAPException le) 675 { 676 Debug.debugException(le); 677 return new LDAPMessage(messageID, 678 new ModifyResponseProtocolOp(le.toLDAPResult()), 679 le.getResponseControls()); 680 } 681 catch (final Exception e) 682 { 683 Debug.debugException(e); 684 return new LDAPMessage(messageID, 685 new ModifyResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, 686 ERR_DS_INTERCEPTOR_REQUEST_ERROR.get( 687 String.valueOf(op), i.getClass().getName(), 688 StaticUtils.getExceptionMessage(e)), 689 null)); 690 } 691 } 692 693 final LDAPMessage resultMessage = wrappedHandler.processModifyRequest( 694 messageID, 695 new ModifyRequestProtocolOp((ModifyRequest) op.getRequest()), 696 op.getRequest().getControlList()); 697 op.setResult(resultMessage.getModifyResponseProtocolOp().toLDAPResult( 698 toArray(resultMessage.getControls()))); 699 for (final InMemoryOperationInterceptor i : interceptors) 700 { 701 try 702 { 703 i.processModifyResult(op); 704 } 705 catch (final Exception e) 706 { 707 Debug.debugException(e); 708 return new LDAPMessage(messageID, 709 new ModifyResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, 710 ERR_DS_INTERCEPTOR_RESULT_ERROR.get( 711 String.valueOf(op), i.getClass().getName(), 712 StaticUtils.getExceptionMessage(e)), 713 null)); 714 } 715 } 716 717 return new LDAPMessage(messageID, 718 new ModifyResponseProtocolOp(op.getResult()), 719 op.getResult().getResponseControls()); 720 } 721 finally 722 { 723 activeOperations.remove(messageID); 724 } 725 } 726 727 728 729 /** 730 * {@inheritDoc} 731 */ 732 @Override() 733 @NotNull() 734 public LDAPMessage processModifyDNRequest(final int messageID, 735 @NotNull final ModifyDNRequestProtocolOp request, 736 @NotNull final List<Control> controls) 737 { 738 final InterceptedModifyDNOperation op = 739 new InterceptedModifyDNOperation(connection, messageID, request, 740 toArray(controls)); 741 activeOperations.put(messageID, op); 742 743 try 744 { 745 for (final InMemoryOperationInterceptor i : interceptors) 746 { 747 try 748 { 749 i.processModifyDNRequest(op); 750 } 751 catch (final LDAPException le) 752 { 753 Debug.debugException(le); 754 return new LDAPMessage(messageID, 755 new ModifyDNResponseProtocolOp(le.toLDAPResult()), 756 le.getResponseControls()); 757 } 758 catch (final Exception e) 759 { 760 Debug.debugException(e); 761 return new LDAPMessage(messageID, 762 new ModifyDNResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, 763 ERR_DS_INTERCEPTOR_REQUEST_ERROR.get( 764 String.valueOf(op), i.getClass().getName(), 765 StaticUtils.getExceptionMessage(e)), 766 null)); 767 } 768 } 769 770 final LDAPMessage resultMessage = wrappedHandler.processModifyDNRequest( 771 messageID, 772 new ModifyDNRequestProtocolOp((ModifyDNRequest) op.getRequest()), 773 op.getRequest().getControlList()); 774 op.setResult(resultMessage.getModifyDNResponseProtocolOp().toLDAPResult( 775 toArray(resultMessage.getControls()))); 776 for (final InMemoryOperationInterceptor i : interceptors) 777 { 778 try 779 { 780 i.processModifyDNResult(op); 781 } 782 catch (final Exception e) 783 { 784 Debug.debugException(e); 785 return new LDAPMessage(messageID, 786 new ModifyDNResponseProtocolOp(ResultCode.OTHER_INT_VALUE, null, 787 ERR_DS_INTERCEPTOR_RESULT_ERROR.get( 788 String.valueOf(op), i.getClass().getName(), 789 StaticUtils.getExceptionMessage(e)), 790 null)); 791 } 792 } 793 794 return new LDAPMessage(messageID, 795 new ModifyDNResponseProtocolOp(op.getResult()), 796 op.getResult().getResponseControls()); 797 } 798 finally 799 { 800 activeOperations.remove(messageID); 801 } 802 } 803 804 805 806 /** 807 * {@inheritDoc} 808 */ 809 @Override() 810 @NotNull() 811 public LDAPMessage processSearchRequest(final int messageID, 812 @NotNull final SearchRequestProtocolOp request, 813 @NotNull final List<Control> controls) 814 { 815 final InterceptedSearchOperation op = 816 new InterceptedSearchOperation(connection, messageID, request, 817 toArray(controls)); 818 activeOperations.put(messageID, op); 819 820 try 821 { 822 for (final InMemoryOperationInterceptor i : interceptors) 823 { 824 try 825 { 826 i.processSearchRequest(op); 827 } 828 catch (final LDAPException le) 829 { 830 Debug.debugException(le); 831 return new LDAPMessage(messageID, 832 new SearchResultDoneProtocolOp(le.toLDAPResult()), 833 le.getResponseControls()); 834 } 835 catch (final Exception e) 836 { 837 Debug.debugException(e); 838 return new LDAPMessage(messageID, 839 new SearchResultDoneProtocolOp(ResultCode.OTHER_INT_VALUE, null, 840 ERR_DS_INTERCEPTOR_REQUEST_ERROR.get( 841 String.valueOf(op), i.getClass().getName(), 842 StaticUtils.getExceptionMessage(e)), 843 null)); 844 } 845 } 846 847 final LDAPMessage resultMessage = wrappedHandler.processSearchRequest( 848 messageID, 849 new SearchRequestProtocolOp((SearchRequest) op.getRequest()), 850 op.getRequest().getControlList()); 851 op.setResult(resultMessage.getSearchResultDoneProtocolOp().toLDAPResult( 852 toArray(resultMessage.getControls()))); 853 for (final InMemoryOperationInterceptor i : interceptors) 854 { 855 try 856 { 857 i.processSearchResult(op); 858 } 859 catch (final Exception e) 860 { 861 Debug.debugException(e); 862 return new LDAPMessage(messageID, 863 new SearchResultDoneProtocolOp(ResultCode.OTHER_INT_VALUE, null, 864 ERR_DS_INTERCEPTOR_RESULT_ERROR.get( 865 String.valueOf(op), i.getClass().getName(), 866 StaticUtils.getExceptionMessage(e)), 867 null)); 868 } 869 } 870 871 return new LDAPMessage(messageID, 872 new SearchResultDoneProtocolOp(op.getResult()), 873 op.getResult().getResponseControls()); 874 } 875 finally 876 { 877 activeOperations.remove(messageID); 878 } 879 } 880 881 882 883 /** 884 * {@inheritDoc} 885 */ 886 @Override() 887 @Nullable() 888 public ObjectPair<SearchResultEntryProtocolOp,Control[]> transformEntry( 889 final int messageID, 890 @NotNull final SearchResultEntryProtocolOp entry, 891 @NotNull final Control[] controls) 892 { 893 final InterceptedSearchOperation op = 894 (InterceptedSearchOperation) activeOperations.get(messageID); 895 if (op == null) 896 { 897 return new ObjectPair<>(entry, controls); 898 } 899 900 final InterceptedSearchEntry e = 901 new InterceptedSearchEntry(op, entry, controls); 902 for (final InMemoryOperationInterceptor i : interceptors) 903 { 904 try 905 { 906 i.processSearchEntry(e); 907 if (e.getSearchEntry() == null) 908 { 909 return null; 910 } 911 } 912 catch (final Exception ex) 913 { 914 Debug.debugException(ex); 915 return null; 916 } 917 } 918 919 return new ObjectPair<>(new SearchResultEntryProtocolOp(e.getSearchEntry()), 920 e.getSearchEntry().getControls()); 921 } 922 923 924 925 /** 926 * {@inheritDoc} 927 */ 928 @Override() 929 @Nullable() 930 public ObjectPair<SearchResultReferenceProtocolOp,Control[]> 931 transformReference(final int messageID, 932 @NotNull final SearchResultReferenceProtocolOp reference, 933 @NotNull final Control[] controls) 934 { 935 final InterceptedSearchOperation op = 936 (InterceptedSearchOperation) activeOperations.get(messageID); 937 if (op == null) 938 { 939 return new ObjectPair<>(reference, controls); 940 } 941 942 final InterceptedSearchReference r = 943 new InterceptedSearchReference(op, reference, controls); 944 for (final InMemoryOperationInterceptor i : interceptors) 945 { 946 try 947 { 948 i.processSearchReference(r); 949 if (r.getSearchReference() == null) 950 { 951 return null; 952 } 953 } 954 catch (final Exception ex) 955 { 956 Debug.debugException(ex); 957 return null; 958 } 959 } 960 961 return new ObjectPair<>( 962 new SearchResultReferenceProtocolOp(r.getSearchReference()), 963 r.getSearchReference().getControls()); 964 } 965 966 967 968 /** 969 * Transforms the provided intermediate response and/or set of controls to 970 * alter what will be returned to the client. 971 * 972 * @param messageID The message ID for the associated search operation. 973 * @param response The intermediate response to be processed. It will not 974 * be {@code null}. 975 * @param controls The set of controls to be processed. It will not be 976 * {@code null} but may be empty if there are no controls. 977 * 978 * @return An {@link ObjectPair} containing a possibly updated intermediate 979 * response and set of controls, or {@code null} to indicate that the 980 * response should not be returned to the client. 981 */ 982 @Override() 983 @Nullable() 984 public ObjectPair<IntermediateResponseProtocolOp,Control[]> 985 transformIntermediateResponse(final int messageID, 986 @NotNull final IntermediateResponseProtocolOp response, 987 @NotNull final Control[] controls) 988 { 989 final InterceptedOperation op = activeOperations.get(messageID); 990 if (op == null) 991 { 992 return new ObjectPair<>(response, controls); 993 } 994 995 final InterceptedIntermediateResponse r = 996 new InterceptedIntermediateResponse(op, response, controls); 997 for (final InMemoryOperationInterceptor i : interceptors) 998 { 999 try 1000 { 1001 i.processIntermediateResponse(r); 1002 if (r.getIntermediateResponse() == null) 1003 { 1004 return null; 1005 } 1006 } 1007 catch (final Exception ex) 1008 { 1009 Debug.debugException(ex); 1010 return null; 1011 } 1012 } 1013 1014 return new ObjectPair<>( 1015 new IntermediateResponseProtocolOp(r.getIntermediateResponse()), 1016 r.getIntermediateResponse().getControls()); 1017 } 1018 1019 1020 1021 /** 1022 * Converts the provided control list to a control array. 1023 * 1024 * @param controls The list of controls to be converted to an array. 1025 * 1026 * @return The resulting array of controls. 1027 */ 1028 @NotNull() 1029 private static Control[] toArray(@NotNull final List<Control> controls) 1030 { 1031 if ((controls == null) || controls.isEmpty()) 1032 { 1033 return StaticUtils.NO_CONTROLS; 1034 } 1035 1036 final Control[] controlArray = new Control[controls.size()]; 1037 return controls.toArray(controlArray); 1038 } 1039}