/* * [PersistSenderState.java] * * Summary: Persist sender state in sender.ser, i.e. which zips/files have been uploaded. * * Copyright: (c) 2007-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 1.0 2007-07-18 Created with IntelliJ IDEA. */ package com.mindprod.replicatorsender; import com.mindprod.common18.EIO; import com.mindprod.fastcat.FastCat; import com.mindprod.filter.ClamFilter; import com.mindprod.replicatorcommon.Config; import com.mindprod.replicatorcommon.MiniFD; import com.mindprod.replicatorcommon.MiniZD; import com.mindprod.replicatorcommon.ReplicatorCommon; import com.mindprod.sorted.SortedArrayList; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import static com.mindprod.replicatorsender.ConfigForSender.*; import static java.lang.System.*; /** * Persist sender state in sender.ser, i.e. which zips/files have been uploaded. * * @author Roedy Green, Canadian Mind Products * @version 1.0 2007-07-18 Created with IntelliJ IDEA. * @since 2007 */ final class PersistSenderState { /** * delete all zips in the staging directory. */ private static void deleteAllZips() { // get rid of all zips in the staging dir. final String[] zips = new File( SENDER_ZIP_STAGING_DIR ) .list( new ClamFilter( "z", ".zip" ) ); for ( String zip : zips ) { //noinspection ResultOfMethodCallIgnored new File( SENDER_ZIP_STAGING_DIR, zip ).delete(); } } /** * restore state of master sender. serial state will be in order Zips will be in order by zip number, * filesToDistribute by clumping and filesToDelete by clumping. */ @SuppressWarnings( "unchecked" ) // no ; not javaDoc static void restoreStateFromSenderSer() { // todo: save/restore arrays instead of Arraylists // restore for master. Receiver is a smaller file. try { final ObjectInputStream ois = EIO.getObjectInputStream( new File( qualifyInSenderPersist( SENDER_SER ) ), 2 * 1024, false ); // not compressed. // check array of 6 serialVersionUIDs ids on front for match. final long[] fileSerialVersionUIDs = ( long[] ) ois.readObject(); if ( fileSerialVersionUIDs.length != 6 || fileSerialVersionUIDs[ 0 ] != MiniZD.serialVersionUID || fileSerialVersionUIDs[ 1 ] != MaxiZD.serialVersionUID || fileSerialVersionUIDs[ 2 ] != ZDStatus.serialVersionUID || fileSerialVersionUIDs[ 3 ] != MiniFD.serialVersionUID || fileSerialVersionUIDs[ 4 ] != MaxiFD.serialVersionUID || fileSerialVersionUIDs[ 5 ] != SortedArrayList .serialVersionUID ) { // extra info err.println( "UID got : wanted" ); err.println( fileSerialVersionUIDs[ 0 ] + ":" + MiniZD .serialVersionUID + " MiniZD" ); err.println( fileSerialVersionUIDs[ 1 ] + ":" + MaxiZD .serialVersionUID + " MaxiZD" ); err.println( fileSerialVersionUIDs[ 2 ] + ":" + ZDStatus .serialVersionUID + " ZDStatsD" ); err.println( fileSerialVersionUIDs[ 3 ] + ":" + MiniFD .serialVersionUID + " MiniFD" ); err.println( fileSerialVersionUIDs[ 4 ] + ":" + MaxiFD .serialVersionUID + " MaxiFD" ); err.println( fileSerialVersionUIDs[ 5 ] + ":" + SortedArrayList.serialVersionUID + " SortedArrayList" ); throw new IOException( "Incompatible version of " + qualifyInSenderPersist( SENDER_SER ) ); } ReplicatorSender.nextZipNumber = ( Integer ) ois.readObject(); ReplicatorSender.estimates = ( int[] ) ois.readObject(); // read serialised array and convert it back to an ArrayList ReplicatorSender.allZips = new ArrayList<>( Arrays.asList( ( MaxiZD[] ) ois.readObject() ) ); ReplicatorSender.oldFilesDistributed = new SortedArrayList<>( Arrays.asList( ( MaxiFD[] ) ois .readObject() ) ); ReplicatorSender.oldFilesDeleted = new SortedArrayList<>( Arrays.asList( ( MaxiFD[] ) ois .readObject() ) ); ois.close(); } catch ( Exception e ) { err.println( "Unable to retrieve previous program state from " + qualifyInSenderPersist( SENDER_SER ) + "\n" + e.getMessage() + "\n" + "Starting from scratch." ); deleteAllZips(); ReplicatorSender.nextZipNumber = 1; ReplicatorSender.allZips = new ArrayList<>( 100 ); ReplicatorSender.oldFilesDistributed = new SortedArrayList<>( 0 ); ReplicatorSender.oldFilesDeleted = new SortedArrayList<>( 0 ); return; } ReplicatorSender.cutOffTimestamp = ReplicatorSender.calcCutOffTimestamp(); } /** * Save state of master, namely all files we distribute and the state of all zips in human-readable form. Zips will * be in order by zip number, filesToDistribute by clumping and filesToDelete by clumping. */ static void saveStateToSenderLog() { // should already be in order. Does no work if is. ReplicatorSender.filesToDistribute .sort( MaxiFD.BY_CLUMPING_AND_FILENAME ); ReplicatorSender.filesToDelete.sort( MaxiFD.BY_CLUMPING_AND_FILENAME ); try { final File logFile = new File( qualifyInSenderPersist( SENDER_LOG ) ); final PrintWriter log = EIO.getPrintWriter( logFile, 4 * 1024, EIO.UTF8 ); log.println( "S E N D E R L O G" ); log.println( "current time: " + Config.TIMESTAMP_MILLISECOND_FORMAT .format( System.currentTimeMillis() ) ); log.println( "nextZipNumber:" + ReplicatorSender.nextZipNumber ); log.println( "estimates: 0=wanted tree 1=unwanted tree 2=wanted dirs 3=unwanted dirs 4=wanted files 5=unwanted" + " files" ); for ( int estimate : ReplicatorSender.estimates ) { log.print( estimate + " " ); } log.println(); log.println( dumpConfig() ); log.println(); // display stats on how many files processed log.println( StatsForSender.dump() ); log.println(); log.println( "A L L Z I P S" ); for ( MaxiZD maxiZD : ReplicatorSender.allZips ) { log.println( maxiZD.dump() ); } log.println(); log.println( "A L L F I L E S" ); for ( MaxiFD maxiFD : ReplicatorSender.filesToDistribute ) { log.println( maxiFD.dump() ); } log.println(); log.println( "A L L D E L E T I O N S" ); for ( MaxiFD maxiFD : ReplicatorSender.filesToDelete ) { log.println( maxiFD.dump() ); } log.println( "-30-" ); log.close(); } catch ( IOException e ) { final FastCat sb = new FastCat( 5 ); sb.append( "Unable to save system log in " ); sb.append( qualifyInSenderPersist( SENDER_SER ) ); sb.append( "." ); sb.append( "\n" ); sb.append( e.getMessage() ); ReplicatorCommon.fatal( sb.toString() ); } } /** * Save state of master, namely all files we distribute and the state of all zips. Ig change this format, fix * ReplicatorValidate to match. Zips will be in order by zip number, filesToDistribute by clumping and filesToDelete * by clumping. */ static void saveStateToSenderSer() { // should already be sorted. Does no work if already sorted. ReplicatorSender.filesToDistribute .sort( MaxiFD.BY_CLUMPING_AND_FILENAME ); ReplicatorSender.filesToDelete.sort( MaxiFD.BY_CLUMPING_AND_FILENAME ); try { final FileOutputStream fos = new FileOutputStream( qualifyInSenderPersist( SENDER_SER ) ); final ObjectOutputStream oos = new ObjectOutputStream( fos ); // version marker on head so can easily tell if have wrong version // or wrong file type. final long[] fileSerialVersionUIDs = new long[ 6 ]; fileSerialVersionUIDs[ 0 ] = MiniZD.serialVersionUID; fileSerialVersionUIDs[ 1 ] = MaxiZD.serialVersionUID; fileSerialVersionUIDs[ 2 ] = ZDStatus.serialVersionUID; fileSerialVersionUIDs[ 3 ] = MiniFD.serialVersionUID; fileSerialVersionUIDs[ 4 ] = MaxiFD.serialVersionUID; fileSerialVersionUIDs[ 5 ] = SortedArrayList.serialVersionUID; oos.writeObject( fileSerialVersionUIDs ); oos.writeObject( ReplicatorSender.nextZipNumber ); oos.writeObject( ReplicatorSender.estimates ); // no longer write ArrayLists, export raw arrays instead. oos.writeObject( ReplicatorSender.allZips.toArray( new MaxiZD[ ReplicatorSender.allZips.size() ] ) ); // there is a slight asymmetry. // We write filesToDistribute and read oldFilesDistributed. oos.writeObject( ReplicatorSender.filesToDistribute.toArray( new MaxiFD[ ReplicatorSender .filesToDistribute.size() ] ) ); // We write filesToDelete and read oldFilesDeleted. oos.writeObject( ReplicatorSender.filesToDelete.toArray( new MaxiFD[ ReplicatorSender.filesToDelete.size () ] ) ); oos.close(); } catch ( IOException e ) { ReplicatorCommon .fatal( "Unable to save system state in " + qualifyInSenderPersist( SENDER_SER ) + "." + "\n" + e.getMessage() ); } } }