001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 * 
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 * 
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 * 
019 */
020package org.apache.directory.server.core.api.partition;
021
022
023import java.io.IOException;
024import java.io.OutputStream;
025import java.util.UUID;
026
027import org.apache.directory.api.ldap.model.entry.Entry;
028import org.apache.directory.api.ldap.model.exception.LdapException;
029import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
030import org.apache.directory.api.ldap.model.name.Dn;
031import org.apache.directory.api.ldap.model.schema.SchemaManager;
032import org.apache.directory.server.core.api.filtering.EntryFilteringCursor;
033import org.apache.directory.server.core.api.interceptor.context.AddOperationContext;
034import org.apache.directory.server.core.api.interceptor.context.DeleteOperationContext;
035import org.apache.directory.server.core.api.interceptor.context.HasEntryOperationContext;
036import org.apache.directory.server.core.api.interceptor.context.LookupOperationContext;
037import org.apache.directory.server.core.api.interceptor.context.ModifyOperationContext;
038import org.apache.directory.server.core.api.interceptor.context.MoveAndRenameOperationContext;
039import org.apache.directory.server.core.api.interceptor.context.MoveOperationContext;
040import org.apache.directory.server.core.api.interceptor.context.RenameOperationContext;
041import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext;
042import org.apache.directory.server.core.api.interceptor.context.UnbindOperationContext;
043
044
045/**
046 * Interface for entry stores containing a part of the DIB (Directory
047 * Information Base).  Partitions are associated with a specific suffix, and
048 * all entries contained in the them have the same Dn suffix in common.
049 *
050 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
051 */
052public interface Partition
053{
054    /** root ID common to all partitions */
055    String ROOT_ID = new UUID( 0L, 0L ).toString();
056
057    /** Default id used for context entry if context entry doesn't exists */
058    String DEFAULT_ID = new UUID( 0L, 1L ).toString();
059
060    /**
061     * Start a read transaction
062     * 
063     * @return a read transaction instance
064     */
065    PartitionReadTxn beginReadTransaction();
066
067    
068    /**
069     * Start a write transaction
070     * 
071     * @return A write transaction instance
072     */
073    PartitionWriteTxn beginWriteTransaction();
074    
075
076    // -----------------------------------------------------------------------
077    // C O N F I G U R A T I O N   M E T H O D S
078    // -----------------------------------------------------------------------
079
080    /**
081     * Gets the unique identifier for this partition.
082     *
083     * @return the unique identifier for this partition
084     */
085    String getId();
086
087
088    /**
089     * Sets the unique identifier for this partition.
090     *
091     * @param id the unique identifier for this partition
092     */
093    void setId( String id );
094
095
096    /**
097     * Gets the schema manager assigned to this Partition.
098     *
099     * @return the schema manager
100     */
101    SchemaManager getSchemaManager();
102
103
104    /**
105     * Sets the schema manager assigned to this Partition.
106     *
107     * @param schemaManager The SchemaManager instance
108     */
109    void setSchemaManager( SchemaManager schemaManager );
110
111
112    // -----------------------------------------------------------------------
113    // E N D   C O N F I G U R A T I O N   M E T H O D S
114    // -----------------------------------------------------------------------
115
116    /**
117     * Initializes this partition. <code>isInitialized()</code> will return <tt>true</tt> if
118     * <code>doInit()</code> returns without any errors. <code>destroy()</code> is called automatically
119     * as a clean-up process if <code>doInit()</code> throws an exception.
120     *
121     * @throws LdapException if initialization fails in any way
122     */
123    void initialize() throws LdapException;
124
125    /**
126     * Repair this partition. 
127     *
128     * @throws Exception if repair fails in any way
129     */
130    void repair() throws Exception;
131
132
133    /**
134     * Gets the normalized suffix as an Dn for this Partition after it has
135     * been initialized.  Attempts to get this Dn before initialization
136     * throw an IllegalStateException.
137     *
138     * @return the suffix for this Partition.
139     * @throws IllegalStateException if the Partition has not been initialized
140     */
141    Dn getSuffixDn();
142
143
144    /**
145     * Sets the suffix Dn, must be normalized.
146     * 
147     * @param suffixDn the new suffix Dn
148     * @throws LdapInvalidDnException If the Dn is invalid
149     */
150    void setSuffixDn( Dn suffixDn ) throws LdapInvalidDnException;
151
152
153    /**
154     * Instructs this Partition to synchronize with it's persistent store, and
155     * destroy all held resources, in preparation for a shutdown event.
156     * 
157     * @param partitionTxn The transaction to use
158     * @throws LdapException If we can't destroy the partition
159     */
160    void destroy( PartitionTxn partitionTxn ) throws LdapException;
161
162
163    /**
164     * Checks to see if this partition is initialized or not.
165     * 
166     * @return <tt>true</tt> if the partition is initialized, false otherwise
167     */
168    boolean isInitialized();
169
170
171    /**
172     * Flushes any changes made to this partition now.
173     * 
174     * @throws LdapException if buffers cannot be flushed to disk
175     */
176    void sync() throws LdapException;
177
178
179    /**
180     * Deletes a leaf entry from this ContextPartition: non-leaf entries cannot be
181     * deleted until this operation has been applied to their children.
182     *
183     * @param deleteContext the context of the entry to
184     * delete from this ContextPartition.
185     * @return The delete Entry, if found
186     * @throws LdapException if there are any problems
187     */
188    Entry delete( DeleteOperationContext deleteContext ) throws LdapException;
189
190
191    /**
192     * Adds an entry to this ContextPartition.
193     *
194     * @param addContext the context used  to add and entry to this ContextPartition
195     * @throws LdapException if there are any problems
196     */
197    void add( AddOperationContext addContext ) throws LdapException;
198
199
200    /**
201     * Modifies an entry by adding, removing or replacing a set of attributes.
202     *
203     * @param modifyContext The context containing the modification operation
204     * to perform on the entry which is one of constants specified by the
205     * DirContext interface:
206     * <code>ADD_ATTRIBUTE, REMOVE_ATTRIBUTE, REPLACE_ATTRIBUTE</code>.
207     * @throws LdapException if there are any problems
208     */
209    void modify( ModifyOperationContext modifyContext ) throws LdapException;
210
211
212    /**
213     * Conducts a search against this ContextPartition.  Namespace specific
214     * parameters for search are contained within the environment using
215     * namespace specific keys into the hash.  For example in the LDAP namespace
216     * a ContextPartition implementation may look for search Controls using a
217     * namespace specific or implementation specific key for the set of LDAP
218     * Controls.
219     *
220     * @param searchContext The context containing the information used by the operation
221     * @return a NamingEnumeration containing objects of type
222     * @throws LdapException if there are any problems
223     */
224    EntryFilteringCursor search( SearchOperationContext searchContext ) throws LdapException;
225
226
227    /**
228     * Looks up an entry by distinguished/absolute name.  This is a simplified
229     * version of the search operation used to point read an entry used for
230     * convenience.
231     * 
232     * Depending on the context parameters, we my look for a simple entry,
233     * or for a restricted set of attributes for this entry
234     *
235     * @param lookupContext The context containing the parameters
236     * @return an Attributes object representing the entry
237     * @throws LdapException if there are any problems
238     */
239    Entry lookup( LookupOperationContext lookupContext ) throws LdapException;
240
241
242    /**
243     * Fast operation to check and see if a particular entry exists.
244     *
245     * @param hasEntryContext The context used to pass informations
246     * @return true if the entry exists, false if it does not
247     * @throws LdapException if there are any problems
248     */
249    boolean hasEntry( HasEntryOperationContext hasEntryContext ) throws LdapException;
250
251
252    /**
253     * Modifies an entry by changing its relative name. Optionally attributes
254     * associated with the old relative name can be removed from the entry.
255     * This makes sense only in certain namespaces like LDAP and will be ignored
256     * if it is irrelevant.
257     *
258     * @param renameContext the modify Dn context
259     * @throws LdapException if there are any problems
260     */
261    void rename( RenameOperationContext renameContext ) throws LdapException;
262
263
264    /**
265     * Transplants a child entry, to a position in the namespace under a new
266     * parent entry.
267     *
268     * @param moveContext The context containing the DNs to move
269     * @throws LdapException if there are any problems
270     */
271    void move( MoveOperationContext moveContext ) throws LdapException;
272
273
274    /**
275     * Transplants a child entry, to a position in the namespace under a new
276     * parent entry and changes the RN of the child entry which can optionally
277     * have its old RN attributes removed.  The removal of old RN attributes
278     * may not make sense in all namespaces.  If the concept is undefined in a
279     * namespace this parameters is ignored.  An example of a namespace where
280     * this parameter is significant is the LDAP namespace.
281     *
282     * @param moveAndRenameContext The context contain all the information about
283     * the modifyDN operation
284     * @throws LdapException if there are any problems
285     */
286    void moveAndRename( MoveAndRenameOperationContext moveAndRenameContext ) throws LdapException;
287
288
289    /**
290     * Represents an unbind operation issued by an authenticated client.  Partitions
291     * need not support this operation.  This operation is here to enable those
292     * interested in implementing virtual directories with ApacheDS.
293     * 
294     * @param unbindContext the context used to unbind
295     * @throws LdapException if something goes wrong
296     */
297    void unbind( UnbindOperationContext unbindContext ) throws LdapException;
298
299
300    /**
301     * Dump the requested index to a given stream
302     * 
303     * @param partitionTxn The transaction to use
304     * @param stream The Stream used to dump the index
305     * @param name The index to dump to stdout
306     * @throws IOException if we can't write the data
307     */
308    void dumpIndex( PartitionTxn partitionTxn, OutputStream stream, String name ) throws IOException;
309
310
311    
312    /**
313     * Get the contextCSN
314     * 
315     * @param partitionTxn The transaction to use
316     * @return the current highest committed CSN value
317     */
318    String getContextCsn( PartitionTxn partitionTxn );
319
320    
321    /**
322     * Saves the context CSN value in the context entry of the partition
323     * 
324     * @param partitionTxn The transaction to use
325     * @throws LdapException If the context can't be saved
326     */
327    void saveContextCsn( PartitionTxn partitionTxn ) throws LdapException;
328    
329    
330    /**
331     * Return the number of children and subordinates for a given entry
332     *
333     * @param partitionTxn The transaction to use
334     * @param entry The entry
335     * @return The Subordinate instance that contains the values.
336     * @throws LdapException If we had an issue while processing the request
337     */
338    Subordinates getSubordinates( PartitionTxn partitionTxn, Entry entry ) throws LdapException;
339}