1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.directory.server.core.changelog;
20
21
22 import org.apache.directory.server.core.DirectoryService;
23 import org.apache.directory.server.core.integ.CiRunner;
24 import static org.apache.directory.server.core.integ.state.TestServiceContext.shutdown;
25 import static org.apache.directory.server.core.integ.state.TestServiceContext.startup;
26 import static org.apache.directory.server.core.integ.IntegrationUtils.getSystemContext;
27 import org.apache.directory.shared.ldap.exception.LdapNameNotFoundException;
28 import static org.junit.Assert.assertTrue;
29 import static org.junit.Assert.assertNull;
30 import static org.junit.Assert.assertNotNull;
31 import static org.junit.Assert.assertEquals;
32 import static org.junit.Assert.fail;
33 import org.junit.Test;
34 import org.junit.runner.RunWith;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 import javax.naming.NamingException;
39 import javax.naming.directory.Attribute;
40 import javax.naming.directory.Attributes;
41 import javax.naming.directory.BasicAttribute;
42 import javax.naming.directory.BasicAttributes;
43 import javax.naming.directory.DirContext;
44 import javax.naming.directory.ModificationItem;
45 import javax.naming.ldap.LdapContext;
46 import java.util.Arrays;
47
48
49
50
51
52
53
54
55
56
57 @RunWith ( CiRunner.class )
58 public class DefaultChangeLogIT
59 {
60 public static final Logger LOG = LoggerFactory.getLogger( DefaultChangeLogIT.class );
61
62 public static DirectoryService service;
63
64
65
66
67 @Test
68 public void testManyTagsPersistenceAcrossRestarts() throws Exception, InterruptedException
69 {
70 LdapContext sysRoot = getSystemContext( service );
71 long revision = service.getChangeLog().getCurrentRevision();
72
73
74 Attributes attrs = new BasicAttributes( "objectClass", "organizationalUnit", true );
75 attrs.put( "ou", "test0" );
76 sysRoot.createSubcontext( "ou=test0", attrs );
77 assertEquals( revision + 1, service.getChangeLog().getCurrentRevision() );
78
79 Tag t0 = service.getChangeLog().tag();
80 assertEquals( t0, service.getChangeLog().getLatest() );
81 assertEquals( revision + 1, service.getChangeLog().getCurrentRevision() );
82 assertEquals( revision + 1, t0.getRevision() );
83
84
85 attrs = new BasicAttributes( "objectClass", "organizationalUnit", true );
86 attrs.put( "ou", "test1" );
87 sysRoot.createSubcontext( "ou=test1", attrs );
88 assertEquals( revision + 2, service.getChangeLog().getCurrentRevision() );
89
90 Tag t1 = service.getChangeLog().tag();
91 assertEquals( t1, service.getChangeLog().getLatest() );
92 assertEquals( revision + 2, service.getChangeLog().getCurrentRevision() );
93 assertEquals( revision + 2, t1.getRevision() );
94
95 shutdown();
96 startup();
97
98 assertEquals( revision + 2, service.getChangeLog().getCurrentRevision() );
99 assertEquals( t1, service.getChangeLog().getLatest() );
100 assertEquals( revision + 2, t1.getRevision() );
101
102
103 attrs = new BasicAttributes( "objectClass", "organizationalUnit", true );
104 attrs.put( "ou", "test2" );
105 sysRoot.createSubcontext( "ou=test2", attrs );
106 assertEquals( revision + 3, service.getChangeLog().getCurrentRevision() );
107
108 service.revert();
109 sysRoot.getAttributes( "ou=test0" );
110 sysRoot.getAttributes( "ou=test1" );
111 assertNotPresent( sysRoot, "ou=test2" );
112 assertEquals( revision + 4, service.getChangeLog().getCurrentRevision() );
113 assertEquals( t1, service.getChangeLog().getLatest() );
114
115 service.revert( t0.getRevision() );
116 sysRoot.getAttributes( "ou=test0" );
117 assertNotPresent( sysRoot, "ou=test1" );
118 assertNotPresent( sysRoot, "ou=test2" );
119 assertEquals( revision + 7, service.getChangeLog().getCurrentRevision() );
120 assertEquals( t1, service.getChangeLog().getLatest() );
121
122
123 shutdown();
124 startup();
125 assertEquals( revision + 7, service.getChangeLog().getCurrentRevision() );
126 assertEquals( t1, service.getChangeLog().getLatest() );
127 assertEquals( revision + 2, t1.getRevision() );
128
129 service.revert( revision );
130 assertNotPresent( sysRoot, "ou=test0" );
131 assertNotPresent( sysRoot, "ou=test1" );
132 assertNotPresent( sysRoot, "ou=test2" );
133 assertEquals( revision + 14, service.getChangeLog().getCurrentRevision() );
134 assertEquals( t1, service.getChangeLog().getLatest() );
135 }
136
137
138 @Test
139 public void testTagPersistenceAcrossRestarts() throws Exception, InterruptedException
140 {
141 LdapContext sysRoot = getSystemContext( service );
142 long revision = service.getChangeLog().getCurrentRevision();
143
144 Tag t0 = service.getChangeLog().tag();
145 assertEquals( t0, service.getChangeLog().getLatest() );
146 assertEquals( revision, service.getChangeLog().getCurrentRevision() );
147
148
149 Attributes attrs = new BasicAttributes( "objectClass", "organizationalUnit", true );
150 attrs.put( "ou", "test" );
151 sysRoot.createSubcontext( "ou=test", attrs );
152 assertEquals( revision + 1, service.getChangeLog().getCurrentRevision() );
153
154 shutdown();
155 startup();
156
157 assertEquals( revision + 1, service.getChangeLog().getCurrentRevision() );
158 assertEquals( t0, service.getChangeLog().getLatest() );
159
160 service.revert();
161 assertNotPresent( sysRoot, "ou=test" );
162 assertEquals( revision + 2, service.getChangeLog().getCurrentRevision() );
163 assertEquals( t0, service.getChangeLog().getLatest() );
164 }
165
166
167 @Test
168 public void testRevertAddOperations() throws Exception
169 {
170 LdapContext sysRoot = getSystemContext( service );
171 Tag t0 = service.getChangeLog().tag();
172 Attributes attrs = new BasicAttributes( "objectClass", "organizationalUnit", true );
173 attrs.put( "ou", "test" );
174 sysRoot.createSubcontext( "ou=test", attrs );
175
176 assertNotNull( sysRoot.getAttributes( "ou=test" ) );
177 service.revert( t0.getRevision() );
178
179 try
180 {
181 sysRoot.getAttributes( "ou=test" );
182 fail( "Should not be able to find the entry!" );
183 }
184 catch ( NamingException ne )
185 {
186 assertTrue( ne instanceof LdapNameNotFoundException );
187 }
188 }
189
190
191 @Test
192 public void testRevertAddAndDeleteOperations() throws Exception
193 {
194 LdapContext sysRoot = getSystemContext( service );
195 Tag t0 = service.getChangeLog().tag();
196
197
198 Attributes attrs = new BasicAttributes( "objectClass", "organizationalUnit", true );
199 attrs.put( "ou", "test" );
200 sysRoot.createSubcontext( "ou=test", attrs );
201
202
203 assertNotNull( sysRoot.getAttributes( "ou=test" ) );
204
205
206 sysRoot.destroySubcontext( "ou=test" );
207 assertNotPresent( sysRoot, "ou=test" );
208
209
210 service.revert( t0.getRevision() );
211 assertNotPresent( sysRoot, "ou=test" );
212 }
213
214
215 @Test
216 public void testRevertDeleteOperations() throws Exception
217 {
218 LdapContext sysRoot = getSystemContext( service );
219 Attributes attrs = new BasicAttributes( "objectClass", "organizationalUnit", true );
220 attrs.put( "ou", "test" );
221 sysRoot.createSubcontext( "ou=test", attrs );
222
223
224 Tag t0 = service.getChangeLog().tag();
225 assertNotNull( sysRoot.getAttributes( "ou=test" ) );
226
227
228 sysRoot.destroySubcontext( "ou=test" );
229 assertNotPresent( sysRoot, "ou=test" );
230
231
232 service.revert( t0.getRevision() );
233 assertNotNull( sysRoot.getAttributes( "ou=test" ) );
234 }
235
236
237 @Test
238 public void testRevertRenameOperations() throws Exception
239 {
240 LdapContext sysRoot = getSystemContext( service );
241 Attributes attrs = new BasicAttributes( "objectClass", "organizationalUnit", true );
242 attrs.put( "ou", "oldname" );
243 sysRoot.createSubcontext( "ou=oldname", attrs );
244
245
246 Tag t0 = service.getChangeLog().tag();
247 assertNotNull( sysRoot.getAttributes( "ou=oldname" ) );
248
249
250 sysRoot.rename( "ou=oldname", "ou=newname" );
251 assertNotPresent( sysRoot, "ou=oldname" );
252 assertNotNull( sysRoot.getAttributes( "ou=newname" ) );
253
254
255 service.revert( t0.getRevision() );
256 assertNotPresent( sysRoot, "ou=newname" );
257 assertNotNull( sysRoot.getAttributes( "ou=oldname" ) );
258 }
259
260
261 @Test
262 public void testRevertModifyOperations() throws Exception
263 {
264 LdapContext sysRoot = getSystemContext( service );
265 Attributes attrs = new BasicAttributes( "objectClass", "organizationalUnit", true );
266 attrs.put( "ou", "test5" );
267 sysRoot.createSubcontext( "ou=test5", attrs );
268
269
270
271
272
273
274 Tag t0 = service.getChangeLog().tag();
275 assertNotNull( sysRoot.getAttributes( "ou=test5" ) );
276
277
278 sysRoot.modifyAttributes( "ou=test5", DirContext.ADD_ATTRIBUTE,
279 new BasicAttributes( "description", "a desc value", true ) );
280 Attributes resusitated = sysRoot.getAttributes( "ou=test5" );
281 assertNotNull( resusitated );
282 Attribute description = resusitated.get( "description" );
283 assertNotNull( description );
284 assertEquals( "a desc value", description.get() );
285
286
287 service.revert( t0.getRevision() );
288 resusitated = sysRoot.getAttributes( "ou=test5" );
289 assertNotNull( resusitated );
290 assertNull( resusitated.get( "description" ) );
291
292
293
294
295
296
297 sysRoot.modifyAttributes( "ou=test5", DirContext.ADD_ATTRIBUTE,
298 new BasicAttributes( "description", "old value", true ) );
299 resusitated = sysRoot.getAttributes( "ou=test5" );
300 assertNotNull( resusitated );
301 description = resusitated.get( "description" );
302 assertNotNull( description );
303 assertEquals( description.get(), "old value" );
304
305
306 Tag t1 = service.getChangeLog().tag();
307 sysRoot.modifyAttributes( "ou=test5", DirContext.REPLACE_ATTRIBUTE,
308 new BasicAttributes( "description", "new value", true ) );
309 resusitated = sysRoot.getAttributes( "ou=test5" );
310 assertNotNull( resusitated );
311 description = resusitated.get( "description" );
312 assertNotNull( description );
313 assertEquals( description.get(), "new value" );
314
315
316 service.revert( t1.getRevision() );
317 resusitated = sysRoot.getAttributes( "ou=test5" );
318 assertNotNull( resusitated );
319 description = resusitated.get( "description" );
320 assertNotNull( description );
321 assertEquals( description.get(), "old value" );
322
323
324
325
326
327
328 Tag t2 = service.getChangeLog().tag();
329 sysRoot.modifyAttributes( "ou=test5", DirContext.REMOVE_ATTRIBUTE,
330 new BasicAttributes( "description", "old value", true ) );
331 resusitated = sysRoot.getAttributes( "ou=test5" );
332 assertNotNull( resusitated );
333 description = resusitated.get( "description" );
334 assertNull( description );
335
336
337 service.revert( t2.getRevision() );
338 resusitated = sysRoot.getAttributes( "ou=test5" );
339 assertNotNull( resusitated );
340 description = resusitated.get( "description" );
341 assertNotNull( description );
342 assertEquals( description.get(), "old value" );
343
344
345
346
347
348
349 sysRoot.modifyAttributes( "ou=test5", DirContext.ADD_ATTRIBUTE,
350 new BasicAttributes( "userPassword", "to be replaced", true ) );
351 assertPassword( sysRoot.getAttributes( "ou=test5" ), "to be replaced" );
352
353 ModificationItem[] mods = new ModificationItem[]
354 {
355 new ModificationItem( DirContext.REMOVE_ATTRIBUTE,
356 new BasicAttribute( "description", "old value" ) ),
357 new ModificationItem( DirContext.ADD_ATTRIBUTE,
358 new BasicAttribute( "seeAlso", "ou=added" ) ),
359 new ModificationItem( DirContext.REPLACE_ATTRIBUTE,
360 new BasicAttribute( "userPassword", "a replaced value" ) )
361 };
362 Tag t3 = service.getChangeLog().tag();
363
364
365
366 sysRoot.modifyAttributes( "ou=test5", mods );
367 resusitated = sysRoot.getAttributes( "ou=test5" );
368 assertNotNull( resusitated );
369 description = resusitated.get( "description" );
370 assertNull( description );
371 assertPassword( resusitated, "a replaced value" );
372 Attribute seeAlso = resusitated.get( "seeAlso" );
373 assertNotNull( seeAlso );
374 assertEquals( seeAlso.get(), "ou=added" );
375
376
377 service.revert( t3.getRevision() );
378 resusitated = sysRoot.getAttributes( "ou=test5" );
379 assertNotNull( resusitated );
380 description = resusitated.get( "description" );
381 assertNotNull( description );
382 assertEquals( description.get(), "old value" );
383 assertPassword( resusitated, "to be replaced" );
384 seeAlso = resusitated.get( "seeAlso" );
385 assertNull( seeAlso );
386 }
387
388
389 private void assertPassword( Attributes entry, String password ) throws NamingException
390 {
391 Attribute userPassword = entry.get( "userPassword" );
392 assertNotNull( userPassword );
393 Arrays.equals( password.getBytes(), ( byte[] ) userPassword.get() );
394 }
395
396
397 private void assertNotPresent( DirContext ctx, String dn ) throws NamingException
398 {
399 try
400 {
401 ctx.getAttributes( dn );
402 fail( "Should not be able to find the entry " + dn + " but it is still there." );
403 }
404 catch ( NamingException ne )
405 {
406 assertTrue( ne instanceof LdapNameNotFoundException );
407 }
408 }
409 }