blob: de1ad0c62bd72780c004de90b36526570d022d0e [file] [log] [blame]
/*-
* Copyright (C) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This file was distributed by Oracle as part of a version of Oracle Berkeley
* DB Java Edition made available at:
*
* http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html
*
* Please see the LICENSE file included in the top-level directory of the
* appropriate version of Oracle Berkeley DB Java Edition for a copy of the
* license and additional information.
*/
package com.sleepycat.je;
import java.io.File;
import java.io.IOException;
import java.net.URL;
/**
* @hidden For internal use: automatic backups
*
* Interface used by Backup to copy and verify files in an archive. The archive
* storage may be on a different physical disk on the same machine, or it could
* be implemented by some remote object storage service accessed over the
* network. The interface is intended to abstract out these storage details.
*
* <p>The class implementing this interface is also expected to have a public
* noargs constructor to facilitate dynamic allocation and initialization of
* the implementing object.
*
* <p>All implementation methods must be re-entrant to permit multiple
* concurrent operations on archive files.
*
* <p>The methods must handle interrupts by doing minimal non-blocking cleanup,
* before propagating the interrupt, to ensure that it is prompt and is not
* itself prone to hanging. The impact of an interrupt should be localized to
* the method, that is, other concurrent operations should not be impacted and
* it should be possible to use the object to perform other operations. Methods
* may be interrupted if the environment needs to be shut down in a timely
* manner, or if the copy needs to be abandoned for some reason.
*
* <p>The implementation methods are responsible for resolving any recoverable
* failures internally by retrying the operation in a manner that is
* appropriate to the underlying storage used by the archive. The methods can
* retry indefinitely, using appropriate backoff strategies. If an operation is
* taking too long, it will be interrupted by the backup process.
*
* <p>The implementation requires write access to the archive. The authn/z
* mechanism is specific to the archive storage. It's the implementation's
* responsibility to ensure that it has the appropriate credentials to permit
* writing to and reading from the archive.
*
* <p>Unexpected exceptions thrown when backup calls methods on an
* implementation of this interface will cause the backup facility to be
* shutdown, but will leave the environment open. {@link InterruptedException}
* and {@link IOException} are expected exceptions, while {@link
* IllegalArgumentException}, other runtime exceptions, and errors are treated
* as unexpected.
*/
public interface BackupFileCopy {
/**
* initialize is invoked exactly once after the creation of the object via
* its noargs constructor.
*
* @param configFile the config file used to initialize the object. It
* could, for example, contain the credentials needed to access the
* archive,the compression and encryption algorithms used to store archive
* files, etc. The format of the config file (properties, json, etc.) is
* private to the implementation.
*
* @throws InterruptedException if the initialize operation is interrupted
* @throws IllegalArgumentException if the configuration was invalid
* @throws IOException if some irrecoverable I/O issue was encountered
* during initialization.
*/
void initialize(File configFile) throws InterruptedException, IOException;
/**
* Returns the encryption algorithm used to encrypt/decrypt the archive
* file being accessed. The encryption algorithm is set via the config file
* during the call to {@link #initialize}. The algorithm name is a valid
* argument to {@link javax.crypto.Cipher#getInstance(String)} or the
* provider overloading used by the implementation.
*
* @return null (if no encryption is in use), or the name of the encryption
* algorithm.
*/
String getEncryptionAlg();
/**
* Returns the compression algorithm used to compress the archive file
* being accessed. The compression algorithm is set via the config file
* during the call to {@link #initialize}.
*
* @return null (if no compression is in use), or the name of the
* compression algorithm. The value (for now) could be one of zip or gzip.
*/
String getCompressionAlg();
/**
* Returns the checksum algorithm used to checksum the archive file
* being accessed. The checksum algorithm is set via the config file
* during the call to {@link #initialize}. The algorithm name is a valid
* argument to {@link java.security.MessageDigest#getInstance(String)} or
* the provider overloading used by the implementation.
*
* @return The name of the checksum algorithm
*/
String getChecksumAlg();
/**
* Copies the file from the local machine into the archive. The file is
* encrypted and compressed in the archive according to the configuration
* specified by {@link #initialize}.
*
* Note that {@code localFile} could be modified concurrently (for table
* row erasure) while the copy operation is in progress, so that the
* version of file that is copied is partially erased. Erasure
* modifications do not change the length of the file, just its existing
* contents. The restored environment is resilient to such pa partially
* erased state. The checksum returned for such a concurrently erased file
* thus reflects the contents of the file in the archive and will not match
* the state of the {@code localFile}.
*
* If archiveFile already exists at {@code archiveURL}, say because of an
* earlier aborted attempt, the file is overwritten by the copy operation.
* The overwrite need not be atomic. The implementation can delete the
* partial archiveFile before copying it anew.
*
* An IOException may leave the archiveFile in an inconsistent state. For
* example, the archive storage may become unavailable, fail, etc. The
* caller is expected to be handle such failures and not trust the archive
* file contents (if the file exists at all) following an IOException.
*
* If archive storage has the notion of a container, like a directory, or a
* storage bucket, the implementation may create the container before
* creating the file, or arrange for the container to be in place before
* backup is enabled.
*
* @param localFile the file to be copied
* @param archiveURL the target path for the copy; it must be an absolute
* URL
* @return the checksum of the contents of localFile as they were at the
* time of the copy.
*
* @throws InterruptedException if the copy is interrupted
* @throws IOException if some irrecoverable I/O issue was encountered
* either while reading or writing the file.
*/
byte[] copy(File localFile,
URL archiveURL) throws InterruptedException, IOException;
/**
* Returns the checksum computed by reading archiveFile. The file is
* assumed to be encrypted and compressed in the archive according to the
* configuration specified by {@link #initialize}
*
* @param archiveURL the archive file being read to compute the checksum
* value; it must be an absolute URL
* @return the checksum value
*
* @throws InterruptedException if the checksum operation is interrupted
* @throws IOException if some irrecoverable I/O issue was encountered
* while reading the archiveFile
*/
byte[] checksum(URL archiveURL) throws InterruptedException, IOException;
}