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 2010-2018 Ping Identity Corporation 026 */ 027package com.unboundid.directory.sdk.ds.api; 028 029 030 031import java.util.Collections; 032import java.util.List; 033import java.util.Map; 034 035import com.unboundid.directory.sdk.common.internal.ExampleUsageProvider; 036import com.unboundid.directory.sdk.common.internal.Reconfigurable; 037import com.unboundid.directory.sdk.common.internal.UnboundIDExtension; 038import com.unboundid.directory.sdk.common.types.Entry; 039import com.unboundid.directory.sdk.ds.config.UncachedAttributeCriteriaConfig; 040import com.unboundid.directory.sdk.ds.scripting. 041 ScriptedUncachedAttributeCriteria; 042import com.unboundid.directory.sdk.ds.types.DirectoryServerContext; 043import com.unboundid.directory.sdk.ds.internal.DirectoryServerExtension; 044import com.unboundid.ldap.sdk.Attribute; 045import com.unboundid.ldap.sdk.LDAPException; 046import com.unboundid.ldap.sdk.ResultCode; 047import com.unboundid.util.Extensible; 048import com.unboundid.util.ThreadSafety; 049import com.unboundid.util.ThreadSafetyLevel; 050import com.unboundid.util.args.ArgumentException; 051import com.unboundid.util.args.ArgumentParser; 052 053 054 055/** 056 * This class defines an API that must be implemented by extensions which have 057 * the ability to determine which attributes should be stored in the 058 * uncached-id2entry database of a local DB backend, while the remainder of the 059 * entry is stored in the id2entry database. In environments with data sets too 060 * large to fit in available memory, and in which entries have a significant 061 * amount of space consumed by attributes which are not frequently accessed, 062 * this can help the server better use the memory it does have for attributes 063 * that are more likely to be accessed. 064 * <BR> 065 * <H2>Configuring Uncached Attribute Criteria</H2> 066 * In order to configure an uncached attribute criteria object created using 067 * this API, use a command like: 068 * <PRE> 069 * dsconfig create-uncached-attribute-criteria \ 070 * --criteria-name "<I>{criteria-name}</I>" \ 071 * --type third-party \ 072 * --set enabled:true \ 073 * --set "extension-class:<I>{class-name}</I>" \ 074 * --set "extension-argument:<I>{name=value}</I>" 075 * </PRE> 076 * where "<I>{criteria-name}</I>" is the name to use for the uncached attribute 077 * criteria instance, "<I>{class-name}</I>" is the fully-qualified name of the 078 * Java class that extends 079 * {@code com.unboundid.directory.sdk.ds.api.UncachedAttributeCriteria}, 080 * and "<I>{name=value}</I>" represents name-value pairs for any arguments to 081 * provide to the uncached attribute criteria. If multiple arguments 082 * should be provided to the criteria, then the 083 * "<CODE>--set extension-argument:<I>{name=value}</I></CODE>" option should be 084 * provided multiple times. 085 * 086 * 087 * @see ScriptedUncachedAttributeCriteria 088 */ 089@Extensible() 090@DirectoryServerExtension() 091@ThreadSafety(level=ThreadSafetyLevel.INTERFACE_THREADSAFE) 092public abstract class UncachedAttributeCriteria 093 implements UnboundIDExtension, 094 Reconfigurable<UncachedAttributeCriteriaConfig>, 095 ExampleUsageProvider 096{ 097 /** 098 * Creates a new instance of this uncached attribute criteria. All uncached 099 * attribute criteria implementations must include a default constructor, but 100 * any initialization should generally be done in the 101 * {@code initializeUncachedAttributeCriteria} method. 102 */ 103 public UncachedAttributeCriteria() 104 { 105 // No implementation is required. However, we need to reference the 106 // scripted uncached attribute criteria so that checkstyle is satisfied 107 // with the import. 108 final ScriptedUncachedAttributeCriteria scriptedCriteria = null; 109 } 110 111 112 113 /** 114 * {@inheritDoc} 115 */ 116 public abstract String getExtensionName(); 117 118 119 120 /** 121 * {@inheritDoc} 122 */ 123 public abstract String[] getExtensionDescription(); 124 125 126 127 /** 128 * {@inheritDoc} 129 */ 130 public void defineConfigArguments(final ArgumentParser parser) 131 throws ArgumentException 132 { 133 // No arguments will be allowed by default. 134 } 135 136 137 138 /** 139 * Initializes this uncached attribute criteria. 140 * 141 * @param serverContext A handle to the server context for the server in 142 * which this extension is running. 143 * @param config The general configuration for this uncached 144 * attribute criteria. 145 * @param parser The argument parser which has been initialized from 146 * the configuration for this uncached attribute 147 * criteria. 148 * 149 * @throws LDAPException If a problem occurs while initializing this 150 * uncached attribute criteria. 151 */ 152 public void initializeUncachedAttributeCriteria( 153 final DirectoryServerContext serverContext, 154 final UncachedAttributeCriteriaConfig config, 155 final ArgumentParser parser) 156 throws LDAPException 157 { 158 // No initialization will be performed by default. 159 } 160 161 162 163 /** 164 * {@inheritDoc} 165 */ 166 public boolean isConfigurationAcceptable( 167 final UncachedAttributeCriteriaConfig config, 168 final ArgumentParser parser, 169 final List<String> unacceptableReasons) 170 { 171 // No extended validation will be performed by default. 172 return true; 173 } 174 175 176 177 /** 178 * {@inheritDoc} 179 */ 180 public ResultCode applyConfiguration( 181 final UncachedAttributeCriteriaConfig config, 182 final ArgumentParser parser, 183 final List<String> adminActionsRequired, 184 final List<String> messages) 185 { 186 // By default, no configuration changes will be applied. If there are any 187 // arguments, then add an admin action message indicating that the extension 188 // needs to be restarted for any changes to take effect. 189 if (! parser.getNamedArguments().isEmpty()) 190 { 191 adminActionsRequired.add( 192 "No configuration change has actually been applied. The new " + 193 "configuration will not take effect until this uncached " + 194 "attribute criteria is disabled and re-enabled or until the " + 195 "server is restarted."); 196 } 197 198 return ResultCode.SUCCESS; 199 } 200 201 202 203 /** 204 * Performs any cleanup which may be necessary when this uncached attribute 205 * criteria instance is to be taken out of service. 206 */ 207 public void finalizeUncachedAttributeCriteria() 208 { 209 // No implementation is required. 210 } 211 212 213 214 /** 215 * Indicates whether the provided attribute should be written into the 216 * uncached-id2entry database rather than into id2entry. 217 * 218 * @param attribute A read-only representation of the attribute for which to 219 * make the determination. 220 * @param entry A read-only representation of the full entry to be 221 * encoded. 222 * 223 * @return {@code true} if the attribute should be written into the 224 * uncached-id2entry database, or {@code false} if it should be 225 * written into the id2entry database. 226 */ 227 public abstract boolean shouldBeUncached(final Attribute attribute, 228 final Entry entry); 229 230 231 232 /** 233 * {@inheritDoc} 234 */ 235 public Map<List<String>,String> getExamplesArgumentSets() 236 { 237 return Collections.emptyMap(); 238 } 239}