
com.jaeksoft.searchlib.replication.ReplicationThread Maven / Gradle / Ivy
/**
* License Agreement for OpenSearchServer
*
* Copyright (C) 2010-2012 Emmanuel Keller / Jaeksoft
*
* http://www.open-search-server.com
*
* This file is part of OpenSearchServer.
*
* OpenSearchServer is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenSearchServer 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenSearchServer.
* If not, see .
**/
package com.jaeksoft.searchlib.replication;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.jaeksoft.searchlib.Client;
import com.jaeksoft.searchlib.SearchLibException;
import com.jaeksoft.searchlib.process.ThreadAbstract;
import com.jaeksoft.searchlib.scheduler.TaskLog;
import com.jaeksoft.searchlib.util.FileUtils;
import com.jaeksoft.searchlib.util.InfoCallback;
import com.jaeksoft.searchlib.util.LastModifiedAndSize;
import com.jaeksoft.searchlib.util.ReadWriteLock;
import com.jaeksoft.searchlib.util.RecursiveDirectoryBrowser;
import com.jaeksoft.searchlib.web.PushServlet;
public class ReplicationThread extends ThreadAbstract
implements RecursiveDirectoryBrowser.CallBack {
final private ReadWriteLock rwl = new ReadWriteLock();
private volatile Client client;
private volatile double totalSize;
private volatile int filesSent;
private volatile long bytesSent;
private volatile double checkedSize;
private volatile InfoCallback infoCallback;
private volatile List filesNotPushed;
private volatile List dirsNotPushed;
private volatile File sourceDirectory;
private final ReplicationType replicationType;
private final long initVersion;
protected ReplicationThread(Client client,
ReplicationMaster replicationMaster,
ReplicationItem replicationItem, InfoCallback infoCallback)
throws SearchLibException {
super(client, replicationMaster, replicationItem, infoCallback);
this.sourceDirectory = replicationItem.getDirectory(client);
this.replicationType = replicationItem.getReplicationType();
this.client = client;
initVersion = client.getIndex().getVersion();
totalSize = 0;
filesSent = 0;
checkedSize = 0;
filesNotPushed = null;
dirsNotPushed = null;
this.infoCallback = infoCallback;
}
public int getProgress() {
rwl.r.lock();
try {
if (checkedSize == 0 || totalSize == 0)
return 0;
int p = (int) ((checkedSize / totalSize) * 100);
return p;
} finally {
rwl.r.unlock();
}
}
private void incFilesSent(long bytesSent) {
rwl.w.lock();
try {
filesSent++;
this.bytesSent += bytesSent;
} finally {
rwl.w.unlock();
}
}
public ReplicationItem getReplicationItem() {
return (ReplicationItem) getThreadItem();
}
private void initNotPushedList() {
filesNotPushed = new ArrayList(0);
dirsNotPushed = new ArrayList(0);
getReplicationItem().getReplicationType().addNotPushedPath(
sourceDirectory, filesNotPushed, dirsNotPushed);
}
@Override
public void runner() throws Exception {
setInfo("Running");
if (replicationType == ReplicationType.MAIN_DATA_COPY)
throw new Exception("Not yet implemented");
else {
initNotPushedList();
client.push(this);
}
}
@Override
public void release() {
Exception e = getException();
if (e != null)
setInfo("Error: " + e.getMessage() != null ? e.getMessage() : e
.toString());
else if (isAborted())
setInfo("Aborted");
else
setInfo("Completed");
}
public void push() throws SearchLibException {
ReplicationItem replicationItem = getReplicationItem();
try {
setTotalSize(new LastModifiedAndSize(sourceDirectory, false)
.getSize());
addCheckedSize(sourceDirectory.length());
PushServlet.call_init(getReplicationItem());
new RecursiveDirectoryBrowser(sourceDirectory, this);
checkVersion();
switch (replicationItem.getReplicationType().getFinalMode()) {
case MERGE:
PushServlet.call_merge(replicationItem);
break;
case SWITCH:
PushServlet.call_switch(replicationItem);
break;
}
} catch (Exception e) {
PushServlet.call_abort(replicationItem);
if (e instanceof SearchLibException)
throw (SearchLibException) e;
else
throw new SearchLibException(e);
}
}
private void setTotalSize(long size) {
rwl.w.lock();
try {
totalSize = size;
} finally {
rwl.w.unlock();
}
}
private void addCheckedSize(long length) {
rwl.w.lock();
try {
checkedSize += length;
} finally {
rwl.w.unlock();
}
}
final private boolean checkFilePush(final File file) throws IOException {
if (!checkDirPush(file))
return false;
for (File fileNotPushed : filesNotPushed)
if (file.equals(fileNotPushed))
return false;
return true;
}
final private boolean checkDirPush(final File dir) throws IOException {
for (File dirNotPushed : dirsNotPushed) {
if (dir.equals(dirNotPushed))
return false;
if (FileUtils.isSubDirectory(dirNotPushed, dir))
return false;
}
return true;
}
public String getStatInfo() {
rwl.r.lock();
try {
return getProgress() + "% completed - " + filesSent
+ " file(s) sent - "
+ FileUtils.byteCountToDisplaySize(bytesSent) + " sent";
} finally {
rwl.r.unlock();
}
}
private void checkVersion() throws SearchLibException {
if (initVersion != client.getIndex().getVersion())
throw new SearchLibException(
"Replication process aborted. The index has changed.");
}
@Override
public void file(File file) throws SearchLibException {
try {
checkVersion();
ReplicationItem replicationItem = getReplicationItem();
long length = file.length();
if (file.isFile()) {
if (checkFilePush(file)) {
if (!PushServlet.call_file_exist(client, replicationItem,
file)) {
PushServlet.call_file(client, replicationItem, file);
incFilesSent(length);
}
}
} else {
if (replicationType.isNotPushedFolder(file))
dirsNotPushed.add(file);
if (checkDirPush(file))
PushServlet.call_directory(client, replicationItem, file);
}
addCheckedSize(length);
if (infoCallback != null) {
infoCallback.setInfo(getStatInfo());
if (infoCallback instanceof TaskLog)
if (((TaskLog) infoCallback).isAbortRequested())
throw new SearchLibException.AbortException();
}
} catch (IllegalStateException e) {
throw new SearchLibException(e);
} catch (IOException e) {
throw new SearchLibException(e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy