Mercurial Hosting > luan
annotate src/goodjava/lucene/backup/Backup.java @ 2023:544ccce564f6 default tip
minor
| author | Franklin Schmidt <fschmidt@gmail.com> | 
|---|---|
| date | Mon, 20 Oct 2025 17:34:14 -0600 | 
| parents | aff2309ae510 | 
| children | 
| rev | line source | 
|---|---|
| 1499 | 1 package goodjava.lucene.backup; | 
| 2 | |
| 3 import java.io.File; | |
| 1509 | 4 import java.io.InputStream; | 
| 5 import java.io.FileInputStream; | |
| 1499 | 6 import java.io.IOException; | 
| 7 import java.util.List; | |
| 8 import java.util.ArrayList; | |
| 9 import java.util.Map; | |
| 10 import java.util.Arrays; | |
| 11 import goodjava.io.IoUtils; | |
| 1509 | 12 import goodjava.io.BufferedInputStream; | 
| 1499 | 13 import goodjava.rpc.RpcServer; | 
| 14 import goodjava.rpc.RpcCall; | |
| 15 import goodjava.rpc.RpcResult; | |
| 1512 | 16 import goodjava.rpc.RpcException; | 
| 1499 | 17 import goodjava.logging.Logger; | 
| 18 import goodjava.logging.LoggerFactory; | |
| 19 import goodjava.lucene.logging.LogFile; | |
| 20 import goodjava.lucene.logging.LoggingIndexWriter; | |
| 21 import goodjava.lucene.logging.LogOutputStream; | |
| 22 | |
| 23 | |
| 1672 | 24 final class Backup { | 
| 1499 | 25 private static final Logger logger = LoggerFactory.getLogger(Backup.class); | 
| 26 | |
| 27 private final File dir; | |
| 1677 
ea7075b7afe1
switch to index.json
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1674diff
changeset | 28 private final File indexFile; | 
| 1697 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 29 private boolean updated = false; | 
| 1499 | 30 | 
| 31 Backup(File dir) { | |
| 32 this.dir = dir; | |
| 1677 
ea7075b7afe1
switch to index.json
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1674diff
changeset | 33 this.indexFile = new File(dir,"index.json"); | 
| 1499 | 34 } | 
| 35 | |
| 1509 | 36 void handle(RpcServer rpc,RpcCall call) { | 
| 1697 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 37 synchronized(this) { | 
| 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 38 if( !updated ) { | 
| 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 39 dir.setLastModified(System.currentTimeMillis()); | 
| 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 40 updated = true; | 
| 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 41 } | 
| 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 42 } | 
| 1499 | 43 try { | 
| 1509 | 44 IoUtils.mkdirs(dir); | 
| 45 if( call.cmd.equals("zip") ) { | |
| 46 handleZip(rpc); | |
| 47 } else { | |
| 48 handle2(rpc,call); | |
| 49 } | |
| 1499 | 50 } catch(IOException e) { | 
| 51 throw new RuntimeException(e); | |
| 52 } | |
| 53 } | |
| 54 | |
| 1509 | 55 private static final RpcResult OK = new RpcResult(new Object[]{"ok"}); | 
| 56 | |
| 1697 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 57 private synchronized void handle2(RpcServer rpc,RpcCall call) throws IOException { | 
| 1499 | 58 //logger.info(call.cmd+" "+Arrays.asList(call.args)); | 
| 59 String fileName = null; | |
| 60 if( call.cmd.equals("check") ) { | |
| 61 // nothing | |
| 62 } else if( call.cmd.equals("add") || call.cmd.equals("append") ) { | |
| 1512 | 63 fileName = (String)call.args[1]; | 
| 1499 | 64 File f = new File(dir,fileName); | 
| 1508 
86c5e7000ecf
lucene.backup checksum
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1501diff
changeset | 65 if( call.cmd.equals("add") ) | 
| 
86c5e7000ecf
lucene.backup checksum
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1501diff
changeset | 66 IoUtils.delete(f); | 
| 1499 | 67 LogFile log = new LogFile(f); | 
| 68 LogOutputStream out = log.output(); | |
| 69 IoUtils.copyAll(call.in,out); | |
| 70 out.commit(); | |
| 71 out.close(); | |
| 1512 | 72 //logger.info(call.cmd+" "+fileName+" "+call.lenIn); | 
| 73 } else { | |
| 74 logger.error("bad cmd '"+call.cmd+"'"); | |
| 75 rpc.write( new RpcException("bad cmd '"+call.cmd+"'") ); | |
| 76 return; | |
| 77 } | |
| 78 List logInfo = (List)call.args[0]; | |
| 79 //logger.info("check "+logInfo); | |
| 1509 | 80 RpcResult result = OK; | 
| 1499 | 81 for( Object obj : logInfo ) { | 
| 82 Map fileInfo = (Map)obj; | |
| 83 String name = (String)fileInfo.get("name"); | |
| 84 File f = new File(dir,name); | |
| 85 if( !f.exists() ) { | |
| 86 if( name.equals(fileName) ) logger.error("missing"); | |
| 1509 | 87 result = new RpcResult(new Object[]{"missing",name}); | 
| 1499 | 88 break; | 
| 89 } | |
| 90 long end = (Long)fileInfo.get("end"); | |
| 91 LogFile log = new LogFile(f); | |
| 92 long logEnd = log.end(); | |
| 93 if( logEnd > end ) { | |
| 94 logger.error("logEnd > end - shouldn't happen, file="+name+" logEnd="+logEnd+" end="+end); | |
| 1509 | 95 result = new RpcResult(new Object[]{"missing",name}); | 
| 1499 | 96 break; | 
| 97 } | |
| 98 if( logEnd < end ) { | |
| 99 if( name.equals(fileName) ) logger.error("incomplete"); | |
| 1509 | 100 result = new RpcResult(new Object[]{"incomplete",name,logEnd}); | 
| 1499 | 101 break; | 
| 102 } | |
| 1508 
86c5e7000ecf
lucene.backup checksum
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1501diff
changeset | 103 Object checksumObj = fileInfo.get("checksum"); | 
| 
86c5e7000ecf
lucene.backup checksum
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1501diff
changeset | 104 if( checksumObj != null ) { | 
| 
86c5e7000ecf
lucene.backup checksum
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1501diff
changeset | 105 long checksum = (Long)checksumObj; | 
| 
86c5e7000ecf
lucene.backup checksum
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1501diff
changeset | 106 if( log.checksum() != checksum ) { | 
| 1677 
ea7075b7afe1
switch to index.json
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1674diff
changeset | 107 indexFile.delete(); | 
| 1509 | 108 result = new RpcResult(new Object[]{"bad_checksum",name}); | 
| 1508 
86c5e7000ecf
lucene.backup checksum
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1501diff
changeset | 109 break; | 
| 
86c5e7000ecf
lucene.backup checksum
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1501diff
changeset | 110 } | 
| 
86c5e7000ecf
lucene.backup checksum
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1501diff
changeset | 111 } | 
| 1499 | 112 } | 
| 113 if( call.cmd.equals("add") ) { | |
| 114 boolean complete = true; | |
| 1548 | 115 final LogFile[] logs = new LogFile[logInfo.size()]; | 
| 116 for( int i=0; i<logs.length; i++ ) { | |
| 117 Map fileInfo = (Map)logInfo.get(i); | |
| 1499 | 118 String name = (String)fileInfo.get("name"); | 
| 119 File f = new File(dir,name); | |
| 120 if( !f.exists() ) { | |
| 121 complete = false; | |
| 122 break; | |
| 123 } | |
| 1548 | 124 logs[i] = new LogFile(f); | 
| 1499 | 125 } | 
| 126 if( complete ) { | |
| 1677 
ea7075b7afe1
switch to index.json
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1674diff
changeset | 127 LoggingIndexWriter.writeIndex(logs,indexFile); | 
| 1512 | 128 //logger.info("write index"); | 
| 1499 | 129 } | 
| 130 } | |
| 131 rpc.write(result); | |
| 132 } | |
| 133 | |
| 1697 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 134 private void handleZip(RpcServer rpc) throws IOException { | 
| 1509 | 135 File zip = File.createTempFile("luan_",".zip"); | 
| 136 IoUtils.delete(zip); | |
| 1674 | 137 String cmd = "zip " + zip + " *"; | 
| 1509 | 138 synchronized(this) { | 
| 1674 | 139 Process proc = Runtime.getRuntime().exec(new String[]{"bash","-c",cmd},null,dir); | 
| 1509 | 140 IoUtils.waitFor(proc); | 
| 141 } | |
| 142 InputStream in = new BufferedInputStream(new FileInputStream(zip)); | |
| 143 RpcResult result = new RpcResult(in,zip.length(),new Object[0]); | |
| 144 rpc.write(result); | |
| 145 IoUtils.delete(zip); | |
| 146 } | |
| 1499 | 147 | 
| 1697 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 148 synchronized void copyTo(File dirTo) throws IOException { | 
| 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 149 IoUtils.mkdirs(dirTo); | 
| 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 150 for( File f : dir.listFiles() ) { | 
| 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 151 String name = f.getName(); | 
| 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 152 File to = new File(dirTo,name); | 
| 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 153 if( name.equals("index.json") ) { | 
| 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 154 IoUtils.copy(f,to); | 
| 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 155 } else { | 
| 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 156 IoUtils.link(f,to); | 
| 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 157 } | 
| 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 158 } | 
| 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 159 } | 
| 
aff2309ae510
add copy_backups.luan
 Franklin Schmidt <fschmidt@gmail.com> parents: 
1677diff
changeset | 160 | 
| 1499 | 161 } | 
