1
package org.apache.lucene.index;
4
* Licensed to the Apache Software Foundation (ASF) under one or more
5
* contributor license agreements. See the NOTICE file distributed with
6
* this work for additional information regarding copyright ownership.
7
* The ASF licenses this file to You under the Apache License, Version 2.0
8
* (the "License"); you may not use this file except in compliance with
9
* the License. You may obtain a copy of the License at
11
* http://www.apache.org/licenses/LICENSE-2.0
13
* Unless required by applicable law or agreed to in writing, software
14
* distributed under the License is distributed on an "AS IS" BASIS,
15
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
* See the License for the specific language governing permissions and
17
* limitations under the License.
21
import java.io.IOException;
22
import java.util.BitSet;
23
import java.util.Collection;
24
import java.util.Iterator;
25
import java.util.List;
27
import java.util.HashMap;
29
import org.apache.lucene.util.LuceneTestCase;
30
import org.apache.lucene.analysis.MockAnalyzer;
31
import org.apache.lucene.document.Document;
32
import org.apache.lucene.document.Field;
33
import org.apache.lucene.store.Directory;
36
* Test class to illustrate using IndexDeletionPolicy to provide multi-level rollback capability.
37
* This test case creates an index of records 1 to 100, introducing a commit point every 10 records.
39
* A "keep all" deletion policy is used to ensure we keep all commit points for testing purposes
42
public class TestTransactionRollback extends LuceneTestCase {
44
private static final String FIELD_RECORD_ID = "record_id";
45
private Directory dir;
47
//Rolls back index to a chosen ID
48
private void rollBackLast(int id) throws Exception {
50
// System.out.println("Attempting to rollback to "+id);
52
IndexCommit last=null;
53
Collection<IndexCommit> commits = IndexReader.listCommits(dir);
54
for (Iterator<IndexCommit> iterator = commits.iterator(); iterator.hasNext();) {
55
IndexCommit commit = iterator.next();
56
Map<String,String> ud=commit.getUserData();
58
if (ud.get("index").endsWith(ids))
63
throw new RuntimeException("Couldn't find commit point "+id);
65
IndexWriter w = new IndexWriter(dir, newIndexWriterConfig(
66
TEST_VERSION_CURRENT, new MockAnalyzer(random)).setIndexDeletionPolicy(
67
new RollbackDeletionPolicy(id)).setIndexCommit(last));
68
Map<String,String> data = new HashMap<String,String>();
69
data.put("index", "Rolled back to 1-"+id);
74
public void testRepeatedRollBacks() throws Exception {
76
int expectedLastRecordId=100;
77
while (expectedLastRecordId>10) {
78
expectedLastRecordId -=10;
79
rollBackLast(expectedLastRecordId);
81
BitSet expecteds = new BitSet(100);
82
expecteds.set(1,(expectedLastRecordId+1),true);
83
checkExpecteds(expecteds);
87
private void checkExpecteds(BitSet expecteds) throws Exception {
88
IndexReader r = IndexReader.open(dir, true);
90
//Perhaps not the most efficient approach but meets our needs here.
91
for (int i = 0; i < r.maxDoc(); i++) {
93
String sval=r.document(i).get(FIELD_RECORD_ID);
95
int val=Integer.parseInt(sval);
96
assertTrue("Did not expect document #"+val, expecteds.get(val));
97
expecteds.set(val,false);
102
assertEquals("Should have 0 docs remaining ", 0 ,expecteds.cardinality());
106
private void showAvailableCommitPoints() throws Exception {
107
Collection commits = IndexReader.listCommits(dir);
108
for (Iterator iterator = commits.iterator(); iterator.hasNext();) {
109
IndexCommit comm = (IndexCommit) iterator.next();
110
System.out.print("\t Available commit point:["+comm.getUserData()+"] files=");
111
Collection files = comm.getFileNames();
112
for (Iterator iterator2 = files.iterator(); iterator2.hasNext();) {
113
String filename = (String) iterator2.next();
114
System.out.print(filename+", ");
116
System.out.println();
122
public void setUp() throws Exception {
124
dir = newDirectory();
125
//Build index, of records 1 to 100, committing after each batch of 10
126
IndexDeletionPolicy sdp=new KeepAllDeletionPolicy();
127
IndexWriter w=new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random)).setIndexDeletionPolicy(sdp));
128
for(int currentRecordId=1;currentRecordId<=100;currentRecordId++) {
129
Document doc=new Document();
130
doc.add(newField(FIELD_RECORD_ID,""+currentRecordId,Field.Store.YES,Field.Index.ANALYZED));
133
if (currentRecordId%10 == 0) {
134
Map<String,String> data = new HashMap<String,String>();
135
data.put("index", "records 1-"+currentRecordId);
144
public void tearDown() throws Exception {
149
// Rolls back to previous commit point
150
class RollbackDeletionPolicy implements IndexDeletionPolicy {
151
private int rollbackPoint;
153
public RollbackDeletionPolicy(int rollbackPoint) {
154
this.rollbackPoint = rollbackPoint;
157
public void onCommit(List<? extends IndexCommit> commits) throws IOException {
160
public void onInit(List<? extends IndexCommit> commits) throws IOException {
161
for (final IndexCommit commit : commits) {
162
Map<String,String> userData=commit.getUserData();
163
if (userData.size() > 0) {
164
// Label for a commit point is "Records 1-30"
165
// This code reads the last id ("30" in this example) and deletes it
166
// if it is after the desired rollback point
167
String x = userData.get("index");
168
String lastVal = x.substring(x.lastIndexOf("-")+1);
169
int last = Integer.parseInt(lastVal);
170
if (last>rollbackPoint) {
172
System.out.print("\tRolling back commit point:" +
173
" UserData="+commit.getUserData() +") ("+(commits.size()-1)+" commit points left) files=");
174
Collection files = commit.getFileNames();
175
for (Iterator iterator2 = files.iterator(); iterator2.hasNext();) {
176
System.out.print(" "+iterator2.next());
178
System.out.println();
188
class DeleteLastCommitPolicy implements IndexDeletionPolicy {
190
public void onCommit(List<? extends IndexCommit> commits) throws IOException {}
192
public void onInit(List<? extends IndexCommit> commits) throws IOException {
193
commits.get(commits.size()-1).delete();
197
public void testRollbackDeletionPolicy() throws Exception {
198
for(int i=0;i<2;i++) {
199
// Unless you specify a prior commit point, rollback
201
new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random))
202
.setIndexDeletionPolicy(new DeleteLastCommitPolicy())).close();
203
IndexReader r = IndexReader.open(dir, true);
204
assertEquals(100, r.numDocs());
209
// Keeps all commit points (used to build index)
210
class KeepAllDeletionPolicy implements IndexDeletionPolicy {
211
public void onCommit(List<? extends IndexCommit> commits) throws IOException {}
212
public void onInit(List<? extends IndexCommit> commits) throws IOException {}