~slub.team/goobi-indexserver/3.x

« back to all changes in this revision

Viewing changes to solr/core/src/java/org/apache/solr/handler/SnapShooter.java

  • Committer: Sebastian Meyer
  • Date: 2012-08-03 09:12:40 UTC
  • Revision ID: sebastian.meyer@slub-dresden.de-20120803091240-x6861b0vabq1xror
Remove Lucene and Solr source code and add patches instead
Fix Bug #985487: Auto-suggestion for the search interface

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 
 * contributor license agreements.  See the NOTICE file distributed with
4
 
 * this work for additional information regarding copyright ownership.
5
 
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 
 * (the "License"); you may not use this file except in compliance with
7
 
 * the License.  You may obtain a copy of the License at
8
 
 *
9
 
 *     http://www.apache.org/licenses/LICENSE-2.0
10
 
 *
11
 
 * Unless required by applicable law or agreed to in writing, software
12
 
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 
 * See the License for the specific language governing permissions and
15
 
 * limitations under the License.
16
 
 */
17
 
package org.apache.solr.handler;
18
 
 
19
 
import java.io.File;
20
 
import java.io.FileInputStream;
21
 
import java.io.FileNotFoundException;
22
 
import java.io.FileOutputStream;
23
 
import java.io.IOException;
24
 
import java.text.SimpleDateFormat;
25
 
import java.util.ArrayList;
26
 
import java.util.Collection;
27
 
import java.util.Collections;
28
 
import java.util.Date;
29
 
import java.util.List;
30
 
import java.util.Locale;
31
 
import java.util.regex.Matcher;
32
 
import java.util.regex.Pattern;
33
 
 
34
 
import org.apache.commons.io.IOUtils;
35
 
import org.apache.lucene.index.IndexCommit;
36
 
import org.apache.lucene.store.Lock;
37
 
import org.apache.lucene.store.SimpleFSLockFactory;
38
 
import org.apache.solr.common.util.NamedList;
39
 
import org.apache.solr.core.IndexDeletionPolicyWrapper;
40
 
import org.apache.solr.core.SolrCore;
41
 
import org.slf4j.Logger;
42
 
import org.slf4j.LoggerFactory;
43
 
 
44
 
/**
45
 
 * <p/> Provides functionality equivalent to the snapshooter script </p>
46
 
 *
47
 
 * @version $Id: SnapShooter.java 1203003 2011-11-17 01:50:33Z hossman $
48
 
 * @since solr 1.4
49
 
 */
50
 
public class SnapShooter {
51
 
  private static final Logger LOG = LoggerFactory.getLogger(SnapShooter.class.getName());
52
 
  private String snapDir = null;
53
 
  private SolrCore solrCore;
54
 
  private SimpleFSLockFactory lockFactory;
55
 
  
56
 
  public SnapShooter(SolrCore core, String location) throws IOException {
57
 
    solrCore = core;
58
 
    if (location == null) snapDir = core.getDataDir();
59
 
    else  {
60
 
      File base = new File(core.getCoreDescriptor().getInstanceDir());
61
 
      snapDir = org.apache.solr.common.util.FileUtils.resolvePath(base, location).getAbsolutePath();
62
 
      File dir = new File(snapDir);
63
 
      if (!dir.exists())  dir.mkdirs();
64
 
    }
65
 
    lockFactory = new SimpleFSLockFactory(snapDir);
66
 
  }
67
 
  
68
 
  void createSnapAsync(final IndexCommit indexCommit, final ReplicationHandler replicationHandler) {
69
 
    createSnapAsync(indexCommit, Integer.MAX_VALUE, replicationHandler);
70
 
  }
71
 
 
72
 
  void createSnapAsync(final IndexCommit indexCommit, final int numberToKeep, final ReplicationHandler replicationHandler) {
73
 
    replicationHandler.core.getDeletionPolicy().saveCommitPoint(indexCommit.getVersion());
74
 
 
75
 
    new Thread() {
76
 
      @Override
77
 
      public void run() {
78
 
        createSnapshot(indexCommit, numberToKeep, replicationHandler);
79
 
      }
80
 
    }.start();
81
 
  }
82
 
 
83
 
  void createSnapshot(final IndexCommit indexCommit, int numberToKeep, ReplicationHandler replicationHandler) {
84
 
    NamedList details = new NamedList();
85
 
    details.add("startTime", new Date().toString());
86
 
    File snapShotDir = null;
87
 
    String directoryName = null;
88
 
    Lock lock = null;
89
 
    try {
90
 
      if(numberToKeep<Integer.MAX_VALUE) {
91
 
        deleteOldBackups(numberToKeep);
92
 
      }
93
 
      SimpleDateFormat fmt = new SimpleDateFormat(DATE_FMT, Locale.US);
94
 
      directoryName = "snapshot." + fmt.format(new Date());
95
 
      lock = lockFactory.makeLock(directoryName + ".lock");
96
 
      if (lock.isLocked()) return;
97
 
      snapShotDir = new File(snapDir, directoryName);
98
 
      if (!snapShotDir.mkdir()) {
99
 
        LOG.warn("Unable to create snapshot directory: " + snapShotDir.getAbsolutePath());
100
 
        return;
101
 
      }
102
 
      Collection<String> files = indexCommit.getFileNames();
103
 
      FileCopier fileCopier = new FileCopier(solrCore.getDeletionPolicy(), indexCommit);
104
 
      fileCopier.copyFiles(files, snapShotDir);
105
 
 
106
 
      details.add("fileCount", files.size());
107
 
      details.add("status", "success");
108
 
      details.add("snapshotCompletedAt", new Date().toString());
109
 
    } catch (Exception e) {
110
 
      SnapPuller.delTree(snapShotDir);
111
 
      LOG.error("Exception while creating snapshot", e);
112
 
      details.add("snapShootException", e.getMessage());
113
 
    } finally {
114
 
      replicationHandler.core.getDeletionPolicy().releaseCommitPoint(indexCommit.getVersion());   
115
 
      replicationHandler.snapShootDetails = details;
116
 
      if (lock != null) {
117
 
        try {
118
 
          lock.release();
119
 
        } catch (IOException e) {
120
 
          LOG.error("Unable to release snapshoot lock: " + directoryName + ".lock");
121
 
        }
122
 
      }
123
 
    }
124
 
  }
125
 
  private void deleteOldBackups(int numberToKeep) {
126
 
    File[] files = new File(snapDir).listFiles();
127
 
    List<OldBackupDirectory> dirs = new ArrayList<OldBackupDirectory>();
128
 
    for(File f : files) {
129
 
      OldBackupDirectory obd = new OldBackupDirectory(f);
130
 
      if(obd.dir != null) {
131
 
        dirs.add(obd);
132
 
      }
133
 
    }
134
 
    Collections.sort(dirs);
135
 
    int i=1;
136
 
    for(OldBackupDirectory dir : dirs) {
137
 
      if( i > numberToKeep-1 ) {
138
 
        SnapPuller.delTree(dir.dir);
139
 
      }
140
 
    }   
141
 
  }
142
 
  private class OldBackupDirectory implements Comparable<OldBackupDirectory>{
143
 
    File dir;
144
 
    Date timestamp;
145
 
    final Pattern dirNamePattern = Pattern.compile("^snapshot[.](.*)$");
146
 
    
147
 
    OldBackupDirectory(File dir) {
148
 
      if(dir.isDirectory()) {
149
 
        Matcher m = dirNamePattern.matcher(dir.getName());
150
 
        if(m.find()) {
151
 
          try {
152
 
            this.dir = dir;
153
 
            this.timestamp = new SimpleDateFormat(DATE_FMT).parse(m.group(1));
154
 
          } catch(Exception e) {
155
 
            this.dir = null;
156
 
            this.timestamp = null;
157
 
          }
158
 
        }
159
 
      }
160
 
    }
161
 
    public int compareTo(OldBackupDirectory that) {
162
 
      return that.timestamp.compareTo(this.timestamp);
163
 
    }
164
 
  }
165
 
 
166
 
  public static final String SNAP_DIR = "snapDir";
167
 
  public static final String DATE_FMT = "yyyyMMddHHmmss";
168
 
  
169
 
 
170
 
  private class FileCopier {
171
 
    private static final int DEFAULT_BUFFER_SIZE = 32768;
172
 
    private byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
173
 
    private IndexCommit indexCommit;
174
 
    private IndexDeletionPolicyWrapper delPolicy;
175
 
 
176
 
    public FileCopier(IndexDeletionPolicyWrapper delPolicy, IndexCommit commit) {
177
 
      this.delPolicy = delPolicy;
178
 
      this.indexCommit = commit;
179
 
    }
180
 
    
181
 
    public void copyFiles(Collection<String> files, File destDir) throws IOException {
182
 
      for (String indexFile : files) {
183
 
        File source = new File(solrCore.getIndexDir(), indexFile);
184
 
        copyFile(source, new File(destDir, source.getName()), true);
185
 
      }
186
 
    }
187
 
    
188
 
    public void copyFile(File source, File destination, boolean preserveFileDate)
189
 
      throws IOException {
190
 
      // check source exists
191
 
      if (!source.exists()) {
192
 
        String message = "File " + source + " does not exist";
193
 
        throw new FileNotFoundException(message);
194
 
      }
195
 
 
196
 
      // does destinations directory exist ?
197
 
      if (destination.getParentFile() != null
198
 
          && !destination.getParentFile().exists()) {
199
 
        destination.getParentFile().mkdirs();
200
 
      }
201
 
 
202
 
      // make sure we can write to destination
203
 
      if (destination.exists() && !destination.canWrite()) {
204
 
        String message = "Unable to open file " + destination + " for writing.";
205
 
        throw new IOException(message);
206
 
      }
207
 
 
208
 
      FileInputStream input = null;
209
 
      FileOutputStream output = null;
210
 
      try {
211
 
        input = new FileInputStream(source);
212
 
        output = new FileOutputStream(destination);
213
 
 
214
 
        int count = 0;
215
 
        int n = 0;
216
 
        int rcnt = 0;
217
 
        while (-1 != (n = input.read(buffer))) {
218
 
          output.write(buffer, 0, n);
219
 
          count += n;
220
 
          rcnt++;
221
 
          /***
222
 
          // reserve every 4.6875 MB
223
 
          if (rcnt == 150) {
224
 
            rcnt = 0;
225
 
            delPolicy.setReserveDuration(indexCommit.getVersion(), reserveTime);
226
 
          }
227
 
           ***/
228
 
        }
229
 
      } finally {
230
 
        try {
231
 
          IOUtils.closeQuietly(input);
232
 
        } finally {
233
 
          IOUtils.closeQuietly(output);
234
 
        }
235
 
      }
236
 
 
237
 
      if (source.length() != destination.length()) {
238
 
        String message = "Failed to copy full contents from " + source + " to "
239
 
          + destination;
240
 
        throw new IOException(message);
241
 
      }
242
 
 
243
 
      if (preserveFileDate) {
244
 
        // file copy should preserve file date
245
 
        destination.setLastModified(source.lastModified());
246
 
      }
247
 
    }
248
 
  }
249
 
  
250
 
 
251
 
}