Mercurial Hosting > luan
view src/goodjava/lucene/backup/Backup.java @ 1769:9d9683e76496
bug fix
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sun, 11 Jun 2023 19:17:26 -0600 |
parents | aff2309ae510 |
children |
line wrap: on
line source
package goodjava.lucene.backup; import java.io.File; import java.io.InputStream; import java.io.FileInputStream; import java.io.IOException; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.Arrays; import goodjava.io.IoUtils; import goodjava.io.BufferedInputStream; import goodjava.rpc.RpcServer; import goodjava.rpc.RpcCall; import goodjava.rpc.RpcResult; import goodjava.rpc.RpcException; import goodjava.logging.Logger; import goodjava.logging.LoggerFactory; import goodjava.lucene.logging.LogFile; import goodjava.lucene.logging.LoggingIndexWriter; import goodjava.lucene.logging.LogOutputStream; final class Backup { private static final Logger logger = LoggerFactory.getLogger(Backup.class); private final File dir; private final File indexFile; private boolean updated = false; Backup(File dir) { this.dir = dir; this.indexFile = new File(dir,"index.json"); } void handle(RpcServer rpc,RpcCall call) { synchronized(this) { if( !updated ) { dir.setLastModified(System.currentTimeMillis()); updated = true; } } try { IoUtils.mkdirs(dir); if( call.cmd.equals("zip") ) { handleZip(rpc); } else { handle2(rpc,call); } } catch(IOException e) { throw new RuntimeException(e); } } private static final RpcResult OK = new RpcResult(new Object[]{"ok"}); private synchronized void handle2(RpcServer rpc,RpcCall call) throws IOException { //logger.info(call.cmd+" "+Arrays.asList(call.args)); String fileName = null; if( call.cmd.equals("check") ) { // nothing } else if( call.cmd.equals("add") || call.cmd.equals("append") ) { fileName = (String)call.args[1]; File f = new File(dir,fileName); if( call.cmd.equals("add") ) IoUtils.delete(f); LogFile log = new LogFile(f); LogOutputStream out = log.output(); IoUtils.copyAll(call.in,out); out.commit(); out.close(); //logger.info(call.cmd+" "+fileName+" "+call.lenIn); } else { logger.error("bad cmd '"+call.cmd+"'"); rpc.write( new RpcException("bad cmd '"+call.cmd+"'") ); return; } List logInfo = (List)call.args[0]; //logger.info("check "+logInfo); RpcResult result = OK; for( Object obj : logInfo ) { Map fileInfo = (Map)obj; String name = (String)fileInfo.get("name"); File f = new File(dir,name); if( !f.exists() ) { if( name.equals(fileName) ) logger.error("missing"); result = new RpcResult(new Object[]{"missing",name}); break; } long end = (Long)fileInfo.get("end"); LogFile log = new LogFile(f); long logEnd = log.end(); if( logEnd > end ) { logger.error("logEnd > end - shouldn't happen, file="+name+" logEnd="+logEnd+" end="+end); result = new RpcResult(new Object[]{"missing",name}); break; } if( logEnd < end ) { if( name.equals(fileName) ) logger.error("incomplete"); result = new RpcResult(new Object[]{"incomplete",name,logEnd}); break; } Object checksumObj = fileInfo.get("checksum"); if( checksumObj != null ) { long checksum = (Long)checksumObj; if( log.checksum() != checksum ) { indexFile.delete(); result = new RpcResult(new Object[]{"bad_checksum",name}); break; } } } if( call.cmd.equals("add") ) { boolean complete = true; final LogFile[] logs = new LogFile[logInfo.size()]; for( int i=0; i<logs.length; i++ ) { Map fileInfo = (Map)logInfo.get(i); String name = (String)fileInfo.get("name"); File f = new File(dir,name); if( !f.exists() ) { complete = false; break; } logs[i] = new LogFile(f); } if( complete ) { LoggingIndexWriter.writeIndex(logs,indexFile); //logger.info("write index"); } } rpc.write(result); } private void handleZip(RpcServer rpc) throws IOException { File zip = File.createTempFile("luan_",".zip"); IoUtils.delete(zip); String cmd = "zip " + zip + " *"; synchronized(this) { Process proc = Runtime.getRuntime().exec(new String[]{"bash","-c",cmd},null,dir); IoUtils.waitFor(proc); } InputStream in = new BufferedInputStream(new FileInputStream(zip)); RpcResult result = new RpcResult(in,zip.length(),new Object[0]); rpc.write(result); IoUtils.delete(zip); } synchronized void copyTo(File dirTo) throws IOException { IoUtils.mkdirs(dirTo); for( File f : dir.listFiles() ) { String name = f.getName(); File to = new File(dirTo,name); if( name.equals("index.json") ) { IoUtils.copy(f,to); } else { IoUtils.link(f,to); } } } }