/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.core.instancemanagement.internal;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileLock;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
*
* Decorator for {@link InstanceOperationsImpl#shutdownInstance(java.util.List, long)} and
* {@link InstanceOperationsImpl#startInstanceUsingInstallation(java.util.List, java.io.File, long)} to centralise instancemanagment.lock
* file release.
*
* @author David Scholz
*/
public final class InstanceOperationsImplReleaseLockDecorator extends AbstractInstanceOperationsDecorator {
private final Log log = LogFactory.getLog(getClass());
public InstanceOperationsImplReleaseLockDecorator(InstanceOperations delegate) {
super(delegate);
registerInstanceOperationCallbackListener(new InstanceOperationCallbackListener() {
@Override
public void onCommandFinish(File profile) throws IOException {
try {
releaseAndDeleteLockFile(profile);
} catch (IOException e) {
log.debug("Failed to release and delete instancemanagement.lock file.", e);
throw e;
}
}
});
}
/**
*
* Delegates to {@link InstanceOperationsImpl#startInstanceUsingInstallation(List, File, long)} and releases lock file after
* {@link InstanceOperationCallbackListener#onCommandFinish(File)} is called.
*
* @param profileDirList the profiles to start.
* @param installationDir the installation directory of the instance installation.
* @param timeout the maximum time this job is allowed to take.
*/
@Override
public void beforeStart(final List<File> profileDirList, final File installationDir, final long timeout) {
// nothing to decorate
}
/**
*
* Delegates to {@link InstanceOperationsImpl#shutdownInstance(List, long)} and releases lock file after
* {@link InstanceOperationCallbackListener#onCommandFinish(File)} is called.
*
* @param profileDirList the profiles to shutdown.
* @param timeout the maximum time this job is allowed to take.
*/
@Override
public void beforeShutdown(final List<File> profileDirList, final long timeout) {
// nothing to decorate
}
private void releaseIMLockFile(final File profile) throws IOException {
File lockfile = new File(profile.getAbsolutePath() + "/" + INSTANCEMANAGEMENT_LOCK);
FileLock lock = null;
if (!lockfile.isFile()) {
return;
}
try (RandomAccessFile randomAccessFile = new RandomAccessFile(lockfile, "rw")) {
synchronized (profile) {
lock = randomAccessFile.getChannel().tryLock();
if (lock != null) {
lock.release();
} else {
throw new IOException("Could not release lock as it's hold by another instance.");
}
}
} catch (IOException e) {
throw new IOException(UNEXPECTED_ERROR_WHEN_TRYING_TO_ACQUIRE_A_FILE_LOCK_ON + lockfile, e);
}
}
private void deleteIMFile(final File profile, final String name) throws IOException {
if (profile.isDirectory()) {
String fileName = "";
if (name.equals("installation")) {
fileName = name;
} else {
fileName = INSTANCEMANAGEMENT_LOCK;
}
for (File f : profile.listFiles()) {
if (f.getName().equals(fileName)) {
log.info("try to delete " + fileName + " file of profile: " + profile.getName());
synchronized (profile) {
boolean success = f.delete();
if (!success) {
throw new IOException("Failed to delete " + fileName + " file.");
}
break;
}
}
}
}
}
private void releaseAndDeleteLockFile(final File profile) throws IOException {
releaseIMLockFile(profile);
deleteIMFile(profile, INSTANCEMANAGEMENT_LOCK);
}
@Override
public void onStartupFailure(List<File> profileDirList) throws InstanceOperationException {
for (File profile : profileDirList) {
try {
releaseAndDeleteLockFile(profile);
} catch (IOException e1) {
throw new InstanceOperationException(e1, null);
}
}
}
@Override
public void onShutdownFailure(List<File> profileDirList) throws InstanceOperationException {
for (File profile : profileDirList) {
try {
releaseAndDeleteLockFile(profile);
deleteIMFile(profile, "installation");
} catch (IOException e) {
throw new InstanceOperationException(e, null);
}
}
}
}