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.config; 021 022 023import java.io.IOException; 024import java.io.InputStream; 025import java.util.Iterator; 026import java.util.UUID; 027 028import org.apache.directory.api.ldap.model.constants.SchemaConstants; 029import org.apache.directory.api.ldap.model.entry.DefaultEntry; 030import org.apache.directory.api.ldap.model.entry.Entry; 031import org.apache.directory.api.ldap.model.exception.LdapException; 032import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException; 033import org.apache.directory.api.ldap.model.exception.LdapOtherException; 034import org.apache.directory.api.ldap.model.ldif.LdifEntry; 035import org.apache.directory.api.ldap.model.ldif.LdifReader; 036import org.apache.directory.api.ldap.model.name.Dn; 037import org.apache.directory.api.ldap.model.schema.SchemaManager; 038import org.apache.directory.server.core.api.interceptor.context.AddOperationContext; 039import org.apache.directory.server.core.api.interceptor.context.DeleteOperationContext; 040import org.apache.directory.server.core.api.interceptor.context.ModifyOperationContext; 041import org.apache.directory.server.core.api.interceptor.context.MoveAndRenameOperationContext; 042import org.apache.directory.server.core.api.interceptor.context.MoveOperationContext; 043import org.apache.directory.server.core.api.interceptor.context.RenameOperationContext; 044import org.apache.directory.server.core.api.partition.PartitionTxn; 045import org.apache.directory.server.core.partition.ldif.AbstractLdifPartition; 046 047 048/** 049 * This class implements a read-only configuration partition. 050 * 051 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 052 */ 053public class ReadOnlyConfigurationPartition extends AbstractLdifPartition 054{ 055 /** The input stream */ 056 private InputStream inputStream; 057 058 059 /** 060 * Creates a new instance of ReadOnlyConfigurationPartition. 061 * 062 * @param inputStream 063 * the input stream 064 * @param schemaManager 065 * the schema manager 066 */ 067 public ReadOnlyConfigurationPartition( InputStream inputStream, SchemaManager schemaManager ) 068 { 069 super( schemaManager ); 070 this.inputStream = inputStream; 071 id = "config"; 072 073 try 074 { 075 suffixDn = new Dn( schemaManager, "ou=config" ); 076 } 077 catch ( LdapInvalidDnException lide ) 078 { 079 // Nothing to do 080 } 081 } 082 083 084 /** 085 * {@inheritDoc} 086 */ 087 protected void doInit() throws LdapException 088 { 089 if ( !initialized ) 090 { 091 // Initializing the wrapped partition 092 super.doInit(); 093 094 // Load LDIF entries 095 loadLdifEntries(); 096 } 097 } 098 099 100 /** 101 * Loads the LDIF entries from the input stream. 102 * 103 * @throws Exception 104 */ 105 private void loadLdifEntries() throws LdapException 106 { 107 if ( inputStream != null ) 108 { 109 // Initializing the reader and the entry iterator 110 try ( LdifReader reader = new LdifReader( inputStream ) ) 111 { 112 Iterator<LdifEntry> itr = reader.iterator(); 113 114 // Exiting if there's no entry 115 if ( !itr.hasNext() ) 116 { 117 return; 118 } 119 120 // Getting the context entry 121 LdifEntry ldifEntry = itr.next(); 122 Entry contextEntry = new DefaultEntry( schemaManager, ldifEntry.getEntry() ); 123 124 // Checking the context entry 125 if ( suffixDn.equals( contextEntry.getDn() ) ) 126 { 127 addMandatoryOpAt( contextEntry ); 128 129 super.add( new AddOperationContext( null, contextEntry ) ); 130 } 131 else 132 { 133 throw new LdapException( "The given LDIF file doesn't contain the context entry" ); 134 } 135 136 // Iterating on all entries 137 while ( itr.hasNext() ) 138 { 139 Entry entry = new DefaultEntry( schemaManager, itr.next().getEntry() ); 140 addMandatoryOpAt( entry ); 141 142 super.add( new AddOperationContext( null, entry ) ); 143 } 144 } 145 catch ( IOException ioe ) 146 { 147 throw new LdapOtherException( ioe.getMessage(), ioe ); 148 } 149 } 150 } 151 152 153 /** 154 * Adds the CSN and UUID attributes to the entry if they are not present. 155 */ 156 private void addMandatoryOpAt( Entry entry ) throws LdapException 157 { 158 // entryCSN 159 if ( entry.get( SchemaConstants.ENTRY_CSN_AT ) == null ) 160 { 161 entry.add( SchemaConstants.ENTRY_CSN_AT, defaultCSNFactory.newInstance().toString() ); 162 } 163 164 // entryUUID 165 if ( entry.get( SchemaConstants.ENTRY_UUID_AT ) == null ) 166 { 167 String uuid = UUID.randomUUID().toString(); 168 entry.add( SchemaConstants.ENTRY_UUID_AT, uuid ); 169 } 170 } 171 172 173 //--------------------------------------------------------------------------------------------- 174 // Operations 175 //--------------------------------------------------------------------------------------------- 176 /** 177 * {@inheritDoc} 178 */ 179 @Override 180 public void add( AddOperationContext arg0 ) throws LdapException 181 { 182 // Does nothing (Read-Only) 183 } 184 185 186 /** 187 * {@inheritDoc} 188 */ 189 @Override 190 public Entry delete( PartitionTxn partitionTxn, String id ) throws LdapException 191 { 192 // Does nothing (Read-Only) 193 return null; 194 } 195 196 197 /** 198 * {@inheritDoc} 199 */ 200 @Override 201 public Entry delete( DeleteOperationContext deleteContext ) throws LdapException 202 { 203 // Does nothing (Read-Only) 204 return null; 205 } 206 207 208 /** 209 * {@inheritDoc} 210 */ 211 @Override 212 public void modify( ModifyOperationContext arg0 ) throws LdapException 213 { 214 // Does nothing (Read-Only) 215 } 216 217 218 /** 219 * {@inheritDoc} 220 */ 221 @Override 222 public void move( MoveOperationContext arg0 ) throws LdapException 223 { 224 // Does nothing (Read-Only) 225 } 226 227 228 /** 229 * {@inheritDoc} 230 */ 231 @Override 232 public void moveAndRename( MoveAndRenameOperationContext arg0 ) throws LdapException 233 { 234 // Does nothing (Read-Only) 235 } 236 237 238 /** 239 * {@inheritDoc} 240 */ 241 @Override 242 public void rename( RenameOperationContext arg0 ) throws LdapException 243 { 244 // Does nothing (Read-Only) 245 } 246}