All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.aoindustries.aoserv.backup.FileEnvironment Maven / Gradle / Ivy

/*
 * aoserv-backup - Backup client for the AOServ Platform.
 * Copyright (C) 2003-2013, 2017, 2018, 2019, 2020, 2021, 2022  AO Industries, Inc.
 *     [email protected]
 *     7262 Bull Pen Cir
 *     Mobile, AL 36695
 *
 * This file is part of aoserv-backup.
 *
 * aoserv-backup is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * aoserv-backup is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with aoserv-backup.  If not, see .
 */

package com.aoindustries.aoserv.backup;

import com.aoapps.hodgepodge.io.FilesystemIterator;
import com.aoapps.hodgepodge.io.FilesystemIteratorRule;
import com.aoapps.io.posix.PosixFile;
import com.aoapps.net.InetAddress;
import com.aoindustries.aoserv.client.AoservConnector;
import com.aoindustries.aoserv.client.backup.FileReplication;
import com.aoindustries.aoserv.client.backup.FileReplicationSetting;
import com.aoindustries.aoserv.client.mysql.Server;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

/**
 * A BackupEnvironment for files.
 *
 * @author  AO Industries, Inc.
 */
public abstract class FileEnvironment implements BackupEnvironment {

  private final Object fileCacheLock = new Object();
  private final Map lastFilenames = new HashMap<>();
  private final Map lastFiles = new HashMap<>();

  protected File getFile(FileReplication ffr, String filename) {
    if (filename == null) {
      throw new AssertionError("filename is null");
    }
    synchronized (fileCacheLock) {
      File lastFile;
      if (!filename.equals(lastFilenames.get(ffr))) {
        lastFile = new File(filename);
        lastFiles.put(ffr, lastFile);
        lastFilenames.put(ffr, filename);
      } else {
        lastFile = lastFiles.get(ffr);
      }
      return lastFile;
    }
  }

  @Override
  public long getStatMode(FileReplication ffr, String filename) throws IOException {
    File file = getFile(ffr, filename);
    if (file.isDirectory()) {
      return PosixFile.IS_DIRECTORY | 0750;
    }
    if (file.isFile()) {
      return PosixFile.IS_REGULAR_FILE | 0640;
    }
    return 0;
  }

  @Override
  public String[] getDirectoryList(FileReplication ffr, String filename) throws IOException {
    return getFile(ffr, filename).list();
  }

  @Override
  public int getUid(FileReplication ffr, String filename) throws IOException {
    return PosixFile.ROOT_UID;
  }

  @Override
  public int getGid(FileReplication ffr, String filename) throws IOException {
    return PosixFile.ROOT_GID;
  }

  @Override
  public long getModifyTime(FileReplication ffr, String filename) throws IOException {
    return getFile(ffr, filename).lastModified();
  }

  @Override
  public long getLength(FileReplication ffr, String filename) throws IOException {
    return getFile(ffr, filename).length();
  }

  @Override
  public String readLink(FileReplication ffr, String filename) throws IOException {
    throw new IOException("readLink not supported");
  }

  @Override
  public long getDeviceIdentifier(FileReplication ffr, String filename) throws IOException {
    throw new IOException("getDeviceIdentifier not supported");
  }

  @Override
  public InputStream getInputStream(FileReplication ffr, String filename) throws IOException {
    return new FileInputStream(getFile(ffr, filename));
  }

  @Override
  public String getNameOfFile(FileReplication ffr, String filename) {
    return getFile(ffr, filename).getName();
  }

  @Override
  public int getFailoverBatchSize(FileReplication ffr) throws IOException, SQLException {
    return 1000;
  }

  @Override
  @SuppressWarnings("NoopMethodInAbstractClass")
  public void preBackup(FileReplication ffr) throws IOException, SQLException {
    // Do nothing
  }

  @Override
  @SuppressWarnings("NoopMethodInAbstractClass")
  public void init(FileReplication ffr) throws IOException, SQLException {
    // Do nothing
  }

  @Override
  public void cleanup(FileReplication ffr) throws IOException, SQLException {
    synchronized (fileCacheLock) {
      lastFilenames.remove(ffr);
      lastFiles.remove(ffr);
    }
  }

  @Override
  @SuppressWarnings("NoopMethodInAbstractClass")
  public void postBackup(FileReplication ffr) throws IOException, SQLException {
    // Do nothing
  }

  @Override
  public Set getRequiredFilenames(FileReplication ffr) throws IOException, SQLException {
    Set requiredFilenames = new LinkedHashSet<>();
    for (FileReplicationSetting setting : ffr.getFileBackupSettings()) {
      String path = setting.getPath();
      if (path.length() > 1 && path.endsWith(File.separator)) {
        path = path.substring(0, path.length() - 1);
      }
      if (setting.isRequired()) {
        requiredFilenames.add(path);
      }
    }
    return Collections.unmodifiableSet(requiredFilenames);
  }

  @Override
  public Iterator getFilenameIterator(FileReplication ffr) throws IOException, SQLException {
    // Build the skip list
    Map filesystemRules = getFilesystemIteratorRules(ffr);
    Map filesystemPrefixRules = getFilesystemIteratorPrefixRules(ffr);

    for (FileReplicationSetting setting : ffr.getFileBackupSettings()) {
      filesystemRules.put(
          setting.getPath(),
          setting.getBackupEnabled() ? FilesystemIteratorRule.OK : FilesystemIteratorRule.SKIP
      );
    }

    return new FilesystemIterator(filesystemRules, filesystemPrefixRules).getFilenameIterator();
  }

  /**
   * Gets the default set of filesystem rules for this environment.
   * This should not include file backup settings, they will override the
   * values returned here.  The returned map may be modified, to maintain
   * internal consistency, return a copy of the map if needed.
   */
  protected abstract Map getFilesystemIteratorRules(FileReplication ffr) throws IOException, SQLException;

  /**
   * Gets the default set of filesystem prefix rules for this environment.
   */
  protected abstract Map getFilesystemIteratorPrefixRules(FileReplication ffr) throws IOException, SQLException;

  @Override
  public InetAddress getDefaultSourceIpAddress() throws IOException, SQLException {
    return InetAddress.UNSPECIFIED_IPV4;
  }

  @Override
  public List getReplicatedMysqlServers(FileReplication ffr) throws IOException, SQLException {
    return Collections.emptyList();
  }

  @Override
  public List getReplicatedMysqlMinorVersions(FileReplication ffr) throws IOException, SQLException {
    return Collections.emptyList();
  }

  /**
   * {@inheritDoc}
   * 

* Uses the random source from {@link AoservConnector#getFastRandom()}. *

*/ @Override public Random getFastRandom() { return AoservConnector.getFastRandom(); } @Override public String getServerPath(FileReplication ffr, String filename) { String serverPath; if (filename.length() == 0) { throw new AssertionError("Empty filename not expected"); } else if (filename.charAt(0) != File.separatorChar) { serverPath = '/' + filename.replace(File.separatorChar, '/'); } else { serverPath = filename.replace(File.separatorChar, '/'); } return serverPath; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy