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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.backends.jeb; 028 import org.opends.messages.Message; 029 030 import static org.opends.server.loggers.debug.DebugLogger.*; 031 import org.opends.server.loggers.debug.DebugTracer; 032 import static org.opends.messages.JebMessages.*; 033 034 import com.sleepycat.je.*; 035 036 import org.opends.server.types.DirectoryException; 037 import org.opends.server.types.Entry; 038 039 /** 040 * Represents the database containing the LDAP entries. The database key is 041 * the entry ID and the value is the entry contents. 042 * 043 */ 044 public class ID2Entry extends DatabaseContainer 045 { 046 /** 047 * The tracer object for the debug logger. 048 */ 049 private static final DebugTracer TRACER = getTracer(); 050 051 /** 052 * Parameters for compression and encryption. 053 */ 054 private DataConfig dataConfig; 055 056 /** 057 * Create a new ID2Entry object. 058 * 059 * @param name The name of the entry database. 060 * @param dataConfig The desired compression and encryption options for data 061 * stored in the entry database. 062 * @param env The JE Environment. 063 * @param entryContainer The entryContainer of the entry database. 064 * @throws DatabaseException If an error occurs in the JE database. 065 * 066 */ 067 ID2Entry(String name, DataConfig dataConfig, 068 Environment env, EntryContainer entryContainer) 069 throws DatabaseException 070 { 071 super(name, env, entryContainer); 072 this.dataConfig = dataConfig; 073 074 DatabaseConfig dbNodupsConfig = new DatabaseConfig(); 075 076 if(env.getConfig().getReadOnly()) 077 { 078 dbNodupsConfig.setReadOnly(true); 079 dbNodupsConfig.setAllowCreate(false); 080 dbNodupsConfig.setTransactional(false); 081 } 082 else if(!env.getConfig().getTransactional()) 083 { 084 dbNodupsConfig.setAllowCreate(true); 085 dbNodupsConfig.setTransactional(false); 086 dbNodupsConfig.setDeferredWrite(true); 087 } 088 else 089 { 090 dbNodupsConfig.setAllowCreate(true); 091 dbNodupsConfig.setTransactional(true); 092 } 093 094 this.dbConfig = dbNodupsConfig; 095 } 096 097 /** 098 * Convert an entry to its database format. 099 * 100 * @param entry The LDAP entry to be converted. 101 * @return The database entry. 102 * 103 * @throws DirectoryException If a problem occurs while attempting to encode 104 * the entry. 105 */ 106 public DatabaseEntry entryData(Entry entry) 107 throws DirectoryException 108 { 109 byte[] entryBytes; 110 entryBytes = JebFormat.entryToDatabase(entry, dataConfig); 111 return new DatabaseEntry(entryBytes); 112 } 113 114 /** 115 * Insert a record into the entry database. 116 * 117 * @param txn The database transaction or null if none. 118 * @param id The entry ID which forms the key. 119 * @param entry The LDAP entry. 120 * @return true if the entry was inserted, false if a record with that 121 * ID already existed. 122 * @throws DatabaseException If an error occurs in the JE database. 123 * @throws DirectoryException If a problem occurs while attempting to encode 124 * the entry. 125 */ 126 public boolean insert(Transaction txn, EntryID id, Entry entry) 127 throws DatabaseException, DirectoryException 128 { 129 DatabaseEntry key = id.getDatabaseEntry(); 130 DatabaseEntry data = entryData(entry); 131 132 OperationStatus status; 133 status = insert(txn, key, data); 134 if (status != OperationStatus.SUCCESS) 135 { 136 return false; 137 } 138 return true; 139 } 140 141 /** 142 * Write a record in the entry database. 143 * 144 * @param txn The database transaction or null if none. 145 * @param id The entry ID which forms the key. 146 * @param entry The LDAP entry. 147 * @return true if the entry was written, false if it was not. 148 * @throws DatabaseException If an error occurs in the JE database. 149 * @throws DirectoryException If a problem occurs while attempting to encode 150 * the entry. 151 */ 152 public boolean put(Transaction txn, EntryID id, Entry entry) 153 throws DatabaseException, DirectoryException 154 { 155 DatabaseEntry key = id.getDatabaseEntry(); 156 DatabaseEntry data = entryData(entry); 157 158 OperationStatus status; 159 status = put(txn, key, data); 160 if (status != OperationStatus.SUCCESS) 161 { 162 return false; 163 } 164 return true; 165 } 166 167 /** 168 * Write a pre-formatted record into the entry database. 169 * 170 * @param txn The database transaction or null if none. 171 * @param key The key containing a pre-formatted entry ID. 172 * @param data The data value containing a pre-formatted LDAP entry. 173 * @return true if the entry was written, false if it was not. 174 * @throws DatabaseException If an error occurs in the JE database. 175 */ 176 public boolean putRaw(Transaction txn, DatabaseEntry key, DatabaseEntry data) 177 throws DatabaseException 178 { 179 OperationStatus status; 180 status = put(txn, key, data); 181 if (status != OperationStatus.SUCCESS) 182 { 183 return false; 184 } 185 return true; 186 } 187 188 /** 189 * Remove a record from the entry database. 190 * 191 * @param txn The database transaction or null if none. 192 * @param id The entry ID which forms the key. 193 * @return true if the entry was removed, false if it was not. 194 * @throws DatabaseException If an error occurs in the JE database. 195 */ 196 public boolean remove(Transaction txn, EntryID id) 197 throws DatabaseException 198 { 199 DatabaseEntry key = id.getDatabaseEntry(); 200 201 OperationStatus status = delete(txn, key); 202 if (status != OperationStatus.SUCCESS) 203 { 204 return false; 205 } 206 return true; 207 } 208 209 /** 210 * Fetch a record from the entry database. 211 * 212 * @param txn The database transaction or null if none. 213 * @param id The desired entry ID which forms the key. 214 * @param lockMode The JE locking mode to be used for the read. 215 * @return The requested entry, or null if there is no such record. 216 * @throws JebException If an error occurs in the JE backend. 217 * @throws DatabaseException If an error occurs in the JE database. 218 */ 219 public Entry get(Transaction txn, EntryID id, LockMode lockMode) 220 throws JebException, DatabaseException 221 { 222 DatabaseEntry key = id.getDatabaseEntry(); 223 DatabaseEntry data = new DatabaseEntry(); 224 225 OperationStatus status; 226 status = read(txn, key, data, 227 LockMode.DEFAULT); 228 229 if (status != OperationStatus.SUCCESS) 230 { 231 return null; 232 } 233 234 byte[] entryBytes = data.getData(); 235 byte entryVersion = JebFormat.getEntryVersion(entryBytes); 236 237 //Try to decode the entry based on the version number. On later versions, 238 //a case could be written to upgrade entries if it is not the current 239 //version 240 Entry entry = null; 241 switch(entryVersion) 242 { 243 case JebFormat.FORMAT_VERSION : 244 try 245 { 246 entry = JebFormat.entryFromDatabase(entryBytes, 247 entryContainer.getRootContainer().getCompressedSchema()); 248 } 249 catch (Exception e) 250 { 251 Message message = ERR_JEB_ENTRY_DATABASE_CORRUPT.get(id.toString()); 252 throw new JebException(message); 253 } 254 break; 255 256 //case 0x00 : 257 // Call upgrade method? Call 0x00 decode method? 258 default : 259 Message message = 260 ERR_JEB_INCOMPATIBLE_ENTRY_VERSION.get(id.toString(), entryVersion); 261 throw new JebException(message); 262 } 263 264 if (entry != null) 265 { 266 entry.processVirtualAttributes(); 267 } 268 269 return entry; 270 } 271 272 /** 273 * Set the desired compression and encryption options for data 274 * stored in the entry database. 275 * 276 * @param dataConfig The desired compression and encryption options for data 277 * stored in the entry database. 278 */ 279 public void setDataConfig(DataConfig dataConfig) 280 { 281 this.dataConfig = dataConfig; 282 } 283 }