001: /*
002: * This file is part of DrFTPD, Distributed FTP Daemon.
003: *
004: * DrFTPD is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU General Public License as published by
006: * the Free Software Foundation; either version 2 of the License, or
007: * (at your option) any later version.
008: *
009: * DrFTPD is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with DrFTPD; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */
018: package org.drftpd.mirroring.archivetypes;
019:
020: import net.sf.drftpd.NoAvailableSlaveException;
021: import net.sf.drftpd.ObjectNotFoundException;
022: import net.sf.drftpd.master.config.FtpConfig;
023: import net.sf.drftpd.mirroring.Job;
024: import net.sf.drftpd.mirroring.JobManager;
025:
026: import org.apache.log4j.Logger;
027:
028: import org.drftpd.PropertyHelper;
029: import org.drftpd.master.RemoteSlave;
030: import org.drftpd.mirroring.ArchiveType;
031: import org.drftpd.plugins.Archive;
032:
033: import org.drftpd.remotefile.LinkedRemoteFileInterface;
034: import org.drftpd.sections.SectionInterface;
035:
036: import java.util.ArrayList;
037: import java.util.Collection;
038: import java.util.HashSet;
039: import java.util.Iterator;
040: import java.util.Properties;
041:
042: /*
043: * @author iamn
044: * @author zubov
045: * @version $Id: ConstantMirroringAndArchive.java 1398 2006-01-14 20:54:51Z zubov $
046: */
047: public class ConstantMirroringAndArchive extends ArchiveType {
048: private static final Logger logger = Logger
049: .getLogger(ConstantMirroringAndArchive.class);
050: private long _slowAfter;
051: private ArrayList<RemoteSlave> _fastHosts;
052:
053: public ConstantMirroringAndArchive(Archive archive,
054: SectionInterface section, Properties p) {
055: super (archive, section, p);
056:
057: if (_numOfSlaves < 2) {
058: throw new IllegalArgumentException(
059: "numOfSlaves has to be > 1 for section "
060: + section.getName());
061: }
062:
063: try {
064: _slowAfter = 60000 * Long.parseLong(PropertyHelper
065: .getProperty(p, getSection().getName()
066: + ".slowAfter"));
067: } catch (NullPointerException e) {
068: _slowAfter = 0;
069: logger.error("Unable to get slowafter!!");
070: }
071:
072: _fastHosts = new ArrayList();
073:
074: for (int i = 1;; i++) {
075: String slavename = null;
076:
077: try {
078: slavename = PropertyHelper.getProperty(p, getSection()
079: .getName()
080: + ".fastHost." + i);
081: } catch (NullPointerException e) {
082: break; // done
083: }
084:
085: try {
086: _fastHosts.add(_parent.getGlobalContext()
087: .getSlaveManager().getRemoteSlave(slavename));
088: } catch (ObjectNotFoundException e) {
089: logger.error("Unable to get slave " + slavename
090: + " from the SlaveManager");
091: }
092: }
093:
094: if (_fastHosts.isEmpty()) {
095: throw new NullPointerException(
096: "Cannot continue, 0 slaves found for fastHosts ConstantMirroringAndArchiveAndArchive for for section "
097: + getSection().getName());
098: }
099: }
100:
101: public HashSet<RemoteSlave> findDestinationSlaves() {
102: HashSet<RemoteSlave> allHosts = new HashSet<RemoteSlave>(
103: _parent.getGlobalContext().getSlaveManager()
104: .getSlaves());
105:
106: HashSet returnMe = new HashSet();
107:
108: /*
109: * if ((System.currentTimeMillis() - getDirectory().lastModified()) >
110: * _slowAfter) { logger.debug("Returning list of slowhosts"); } else {
111: * logger.debug("Returning list of fasthosts"); }
112: */
113: for (Iterator iter2 = allHosts.iterator(); iter2.hasNext();) {
114: RemoteSlave rslave = (RemoteSlave) iter2.next();
115:
116: if (rslave.isAvailable()) {
117: if ((System.currentTimeMillis() - getDirectory()
118: .lastModified()) > _slowAfter) {
119: if (!_fastHosts.contains(rslave)) {
120: returnMe.add(rslave);
121: }
122: } else {
123: if (_fastHosts.contains(rslave)) {
124: returnMe.add(rslave);
125: }
126: }
127: }
128: }
129:
130: return returnMe;
131:
132: /*return new HashSet(_parent.getConnectionManager().getGlobalContext()
133: .getSlaveManager().getSlaves());*/
134: }
135:
136: protected boolean isArchivedDir(LinkedRemoteFileInterface lrf)
137: throws IncompleteDirectoryException, OfflineSlaveException {
138: boolean shouldBeFast;
139:
140: if ((System.currentTimeMillis() - lrf.lastModified()) > _slowAfter) {
141: shouldBeFast = false;
142:
143: //logger.debug("DBG File " + lrf.getPath() + " should be on slowhost");
144: } else {
145: shouldBeFast = true;
146:
147: //logger.debug("DBG File " + lrf.getPath() + " should be on fasthost");
148: }
149:
150: for (Iterator iter = lrf.getFiles().iterator(); iter.hasNext();) {
151: LinkedRemoteFileInterface src = (LinkedRemoteFileInterface) iter
152: .next();
153:
154: if (src.isFile()) {
155: /* Custom stuff: */
156: for (Iterator iter2 = _fastHosts.iterator(); iter2
157: .hasNext();) {
158: RemoteSlave fasthost = (RemoteSlave) iter2.next();
159:
160: if (fasthost == null) {
161: continue;
162: }
163:
164: if (!src.getSlaves().contains(fasthost)
165: && shouldBeFast) {
166: //logger.debug("DBG File " + src.getName() + " is on slowhost, moving to fasthost");
167: return false;
168: }
169:
170: if (src.getSlaves().contains(fasthost)
171: && !shouldBeFast) {
172: //logger.debug("DBG File " + src.getName() + " is on fasthost, moving to slowhost");
173: return false;
174: }
175: }
176:
177: /*if (!shouldBeFast) {
178: if (!src.getSlaves().contains(_fastHosts)) {
179: //logger.debug("DBG File is on fasthost, moving to slowhost");
180: return false;
181: }
182: }
183: else {
184: if (src.getSlaves().contains(_fastHosts)) {
185: //logger.debug("DBG File is on slowhost, moving to fasthost");
186: return false;
187: }
188: }*/
189: try {
190: if (src.getAvailableSlaves().size() != _numOfSlaves) {
191: logger.debug(src.getPath()
192: + " is on too few hosts, mirroring.");
193:
194: return false;
195: }
196: } catch (NoAvailableSlaveException e) {
197: throw new OfflineSlaveException(src.getName()
198: + " is not online");
199: }
200:
201: if (src.getSlaves().size() > _numOfSlaves) {
202: logger.debug(src.getPath()
203: + " is on too many hosts, cleaning up.");
204:
205: return false;
206: }
207: } else { // src.isDirectory()
208: if (!isArchivedDir(src)) {
209: return false;
210: }
211: }
212: }
213:
214: return true;
215: }
216:
217: /**
218: * Adds relevant Jobs to the JobManager and returns an ArrayList of those Job's
219: */
220: public ArrayList send() {
221: return recursiveSend(getDirectory());
222: }
223:
224: public String toString() {
225: return "ConstantMirroringAndArchive=[directory=["
226: + getDirectory().getPath() + "]dest=["
227: + outputSlaves(getRSlaves()) + "]numOfSlaves=["
228: + _numOfSlaves + "]slowAfter=[" + _slowAfter + "]]";
229: }
230: }
|