Created
September 29, 2016 14:24
-
-
Save aldaris/ae5c323cdfb501768701bfd84ccff30d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* The contents of this file are subject to the terms of the Common Development and | |
* Distribution License (the License). You may not use this file except in compliance with the | |
* License. | |
* | |
* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the | |
* specific language governing permission and limitations under the License. | |
* | |
* When distributing Covered Software, include this CDDL Header Notice in each file and include | |
* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL | |
* Header, with the fields enclosed by brackets [] replaced by your own identifying | |
* information: "Portions copyright [year] [name of copyright owner]". | |
* | |
* Copyright 2016 ForgeRock AS. | |
*/ | |
package org.forgerock.opendj.plugins; | |
import static org.forgerock.opendj.plugins.ExamplePluginMessages.*; | |
import static org.opends.server.util.StaticUtils.getExceptionMessage; | |
import java.util.concurrent.LinkedBlockingQueue; | |
import java.util.concurrent.TimeUnit; | |
import org.forgerock.i18n.slf4j.LocalizedLogger; | |
import org.forgerock.opendj.config.server.ConfigException; | |
import org.forgerock.opendj.io.ASN1; | |
import org.forgerock.opendj.io.ASN1Reader; | |
import org.forgerock.opendj.ldap.ByteString; | |
import org.forgerock.opendj.ldap.ResultCode; | |
import org.forgerock.opendj.ldap.SearchScope; | |
import org.forgerock.opendj.server.config.server.SearchAndDeleteExtendedOperationHandlerCfg; | |
import org.opends.server.api.ExtendedOperationHandler; | |
import org.opends.server.controls.PagedResultsControl; | |
import org.opends.server.core.ExtendedOperation; | |
import org.opends.server.protocols.internal.InternalClientConnection; | |
import org.opends.server.protocols.internal.InternalSearchListener; | |
import org.opends.server.protocols.internal.InternalSearchOperation; | |
import org.opends.server.protocols.internal.Requests; | |
import org.opends.server.protocols.internal.SearchRequest; | |
import org.opends.server.types.AuthenticationInfo; | |
import org.opends.server.types.DirectoryException; | |
import org.opends.server.types.InitializationException; | |
import org.opends.server.types.SearchResultEntry; | |
import org.opends.server.types.SearchResultReference; | |
public class SearchAndDeleteExtendedOperation | |
extends ExtendedOperationHandler<SearchAndDeleteExtendedOperationHandlerCfg> { | |
public static final byte TYPE_SEARCH_BASE_ELEMENT = (byte) 0x80; | |
public static final byte TYPE_SEARCH_FILTER_ELEMENT = (byte) 0x81; | |
private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); | |
@Override | |
public void initializeExtendedOperationHandler(SearchAndDeleteExtendedOperationHandlerCfg config) | |
throws ConfigException, InitializationException { | |
super.initializeExtendedOperationHandler(config); | |
} | |
@Override | |
public void processExtendedOperation(ExtendedOperation operation) { | |
// Parse the encoded request, if there is one. | |
ByteString requestValue = operation.getRequestValue(); | |
if (requestValue == null) { | |
operation.setResultCode(ResultCode.PROTOCOL_ERROR); | |
operation.appendErrorMessage(ExamplePluginMessages.ERR_MISSING_REQUEST_VALUE.get()); | |
return; | |
} | |
ByteString searchBase = null; | |
ByteString searchFilter = null; | |
try { | |
ASN1Reader reader = ASN1.getReader(requestValue); | |
reader.readStartSequence(); | |
if (reader.hasNextElement() && reader.peekType() == TYPE_SEARCH_BASE_ELEMENT) { | |
searchBase = reader.readOctetString(); | |
} | |
if (reader.hasNextElement() && reader.peekType() == TYPE_SEARCH_FILTER_ELEMENT) { | |
searchFilter = reader.readOctetString(); | |
} | |
reader.readEndSequence(); | |
} catch (Exception ae) { | |
logger.traceException(ae); | |
operation.setResultCode(ResultCode.PROTOCOL_ERROR); | |
operation.appendErrorMessage(ERR_PARSING_ERROR.get(getExceptionMessage(ae))); | |
return; | |
} | |
if (searchBase.isEmpty()) { | |
operation.setResultCode(ResultCode.PROTOCOL_ERROR); | |
operation.appendErrorMessage(ERR_MISSING_SEARCH_BASE.get()); | |
return; | |
} else if (searchFilter.isEmpty()) { | |
operation.setResultCode(ResultCode.PROTOCOL_ERROR); | |
operation.appendErrorMessage(ERR_MISSING_SEARCH_FILTER.get()); | |
return; | |
} | |
final AuthenticationInfo authenticationInfo = operation.getClientConnection().getAuthenticationInfo(); | |
if (!authenticationInfo.isAuthenticated()) { | |
operation.setResultCode(ResultCode.UNWILLING_TO_PERFORM); | |
operation.appendErrorMessage(ERR_UNAUTHENTICATED_REQUEST.get()); | |
} | |
final InternalClientConnection icc = new InternalClientConnection(authenticationInfo); | |
try { | |
final SearchRequest searchRequest = Requests.newSearchRequest(searchBase.toString(), | |
SearchScope.WHOLE_SUBTREE, searchFilter.toString()); | |
searchRequest.addAttribute("1.1"); | |
searchRequest.addControl(new PagedResultsControl(true, 500, null)); | |
final LinkedBlockingQueue<InternalClientConnection> queue = new LinkedBlockingQueue<>(10); | |
for (int i = 0; i < 10; i++) { | |
queue.offer(new InternalClientConnection(authenticationInfo)); | |
} | |
final InternalSearchOperation searchOperation = icc.processSearch(searchRequest, new InternalSearchListener() { | |
@Override | |
public void handleInternalSearchEntry(InternalSearchOperation searchOperation, SearchResultEntry searchEntry) throws DirectoryException { | |
final InternalClientConnection conn = queue.poll(); | |
try { | |
conn.processDelete(searchEntry.getName()); | |
} finally { | |
queue.offer(conn); | |
} | |
} | |
@Override | |
public void handleInternalSearchReference(InternalSearchOperation searchOperation, SearchResultReference searchReference) throws DirectoryException { | |
} | |
}); | |
} catch (DirectoryException de) { | |
logger.traceException(de); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment