001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * docs/licenses/cddl.txt 011 * or http://www.opensource.org/licenses/cddl1.php. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * docs/licenses/cddl.txt. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2012-2017 Ping Identity Corporation 026 */ 027package com.unboundid.directory.sdk.ds.scripting; 028 029 030 031import java.util.List; 032 033import com.unboundid.directory.sdk.common.internal.Reconfigurable; 034import com.unboundid.directory.sdk.common.types.Entry; 035import com.unboundid.directory.sdk.ds.config.UncachedEntryCriteriaConfig; 036import com.unboundid.directory.sdk.ds.internal.DirectoryServerExtension; 037import com.unboundid.directory.sdk.ds.types.DirectoryServerContext; 038import com.unboundid.ldap.sdk.LDAPException; 039import com.unboundid.ldap.sdk.ResultCode; 040import com.unboundid.util.Extensible; 041import com.unboundid.util.ThreadSafety; 042import com.unboundid.util.ThreadSafetyLevel; 043import com.unboundid.util.args.ArgumentException; 044import com.unboundid.util.args.ArgumentParser; 045 046 047 048/** 049 * This class defines an API that must be implemented by scripted extensions 050 * which have the ability to determine which entries should be stored in the 051 * uncached-id2entry database of a local DB backend, rather than in the id2entry 052 * database. In environments with data sets too large to fit in available 053 * memory, this can help the server better use the memory it does have for 054 * entries that are more likely to be accessed. 055 * <BR> 056 * <H2>Configuring Groovy-Scripted Uncached Entry Criteria</H2> 057 * In order to configure a scripted uncached entry criteria object based on 058 * this API and written in the Groovy scripting language, use a command like: 059 * <PRE> 060 * dsconfig create-uncached-entry-criteria \ 061 * --criteria-name "<I>{criteria-name}</I>" \ 062 * --type groovy-scripted \ 063 * --set enabled:true \ 064 * --set "script-class:<I>{class-name}</I>" \ 065 * --set "script-argument:<I>{name=value}</I>" 066 * </PRE> 067 * where "<I>{handler-name}</I>" is the name to use for the uncached entry 068 * criteria instance, "<I>{class-name}</I>" is the fully-qualified name of the 069 * Groovy class written using this API, and "<I>{name=value}</I>" represents 070 * name-value pairs for any arguments to provide to the uncached entry criteria 071 * object. If multiple arguments should be provided to the uncached entry 072 * criteria, then the "<CODE>--set script-argument:<I>{name=value}</I></CODE>" 073 * option should be provided multiple times. 074 * 075 * @see com.unboundid.directory.sdk.ds.api.UncachedEntryCriteria 076 */ 077@Extensible() 078@DirectoryServerExtension() 079@ThreadSafety(level=ThreadSafetyLevel.INTERFACE_THREADSAFE) 080public abstract class ScriptedUncachedEntryCriteria 081 implements Reconfigurable<UncachedEntryCriteriaConfig> 082{ 083 /** 084 * Creates a new instance of this uncached entry criteria. All uncached entry 085 * criteria implementations must include a default constructor, but any 086 * initialization should generally be done in the 087 * {@code initializeUncachedEntryCriteria} method. 088 */ 089 public ScriptedUncachedEntryCriteria() 090 { 091 // No implementation is required. 092 } 093 094 095 096 /** 097 * {@inheritDoc} 098 */ 099 public void defineConfigArguments(final ArgumentParser parser) 100 throws ArgumentException 101 { 102 // No arguments will be allowed by default. 103 } 104 105 106 107 /** 108 * Initializes this uncached entry criteria. 109 * 110 * @param serverContext A handle to the server context for the server in 111 * which this extension is running. 112 * @param config The general configuration for this uncached entry 113 * criteria. 114 * @param parser The argument parser which has been initialized from 115 * the configuration for this uncached entry criteria. 116 * 117 * @throws LDAPException If a problem occurs while initializing this 118 * uncached entry criteria. 119 */ 120 public void initializeUncachedEntryCriteria( 121 final DirectoryServerContext serverContext, 122 final UncachedEntryCriteriaConfig config, 123 final ArgumentParser parser) 124 throws LDAPException 125 { 126 // No initialization will be performed by default. 127 } 128 129 130 131 /** 132 * {@inheritDoc} 133 */ 134 public boolean isConfigurationAcceptable( 135 final UncachedEntryCriteriaConfig config, 136 final ArgumentParser parser, 137 final List<String> unacceptableReasons) 138 { 139 // No extended validation will be performed. 140 return true; 141 } 142 143 144 145 /** 146 * {@inheritDoc} 147 */ 148 public ResultCode applyConfiguration( 149 final UncachedEntryCriteriaConfig config, 150 final ArgumentParser parser, 151 final List<String> adminActionsRequired, 152 final List<String> messages) 153 { 154 // By default, no configuration changes will be applied. If there are any 155 // arguments, then add an admin action message indicating that the extension 156 // needs to be restarted for any changes to take effect. 157 if (! parser.getNamedArguments().isEmpty()) 158 { 159 adminActionsRequired.add( 160 "No configuration change has actually been applied. The new " + 161 "configuration will not take effect until this uncached " + 162 "entry criteria is disabled and re-enabled or until the " + 163 "server is restarted."); 164 } 165 166 return ResultCode.SUCCESS; 167 } 168 169 170 171 /** 172 * Performs any cleanup which may be necessary when this uncached entry 173 * criteria instance is to be taken out of service. 174 */ 175 public void finalizeUncachedEntryCriteria() 176 { 177 // No implementation is required. 178 } 179 180 181 182 /** 183 * Indicates whether the provided entry should be written into the 184 * uncached-id2entry database rather than into id2entry. This method may be 185 * used both for new entries (e.g., from add operations or LDIF imports) or 186 * existing entries (e.g., from modify, modify DN, or soft delete operations, 187 * or from re-encode processing). 188 * 189 * @param previousEntry A read-only representation of the entry as it 190 * existed before the update. If the entry is 191 * unchanged or did not previously exist, then this 192 * will be the same as {@code updatedEntry}. 193 * @param updatedEntry A read-only representation of the entry as it will 194 * be written into either the id2entry or 195 * uncached-id2entry database. 196 * 197 * @return {@code true} if the entry should be written into the 198 * uncached-id2entry database, or {@code false} if it should be 199 * written into the id2entry database. 200 */ 201 public abstract boolean shouldBeUncached(final Entry previousEntry, 202 final Entry updatedEntry); 203}