/*
* Copyright © 2015 Cask Data, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package co.cask.cdap.data.tools;
import co.cask.cdap.common.io.Locations;
import co.cask.cdap.common.namespace.NamespacedLocationFactory;
import org.apache.twill.filesystem.Location;
import org.apache.twill.filesystem.LocationFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import javax.annotation.Nullable;
/**
* Abstract class for Upgrade
*/
public abstract class AbstractUpgrader {
private static final Logger LOG = LoggerFactory.getLogger(AbstractUpgrader.class);
protected final LocationFactory locationFactory;
protected final NamespacedLocationFactory namespacedLocationFactory;
public AbstractUpgrader(LocationFactory locationFactory, NamespacedLocationFactory namespacedLocationFactory) {
this.locationFactory = locationFactory;
this.namespacedLocationFactory = namespacedLocationFactory;
}
/**
* Modules which want to upgrade should provide a definition for this
*
* @throws Exception if the upgrade failed
*/
abstract void upgrade() throws Exception;
/**
* Renames the old location to new location if old location exists and the new one does not
*
* @param oldLocation the old {@link Location}
* @param newLocation the new {@link Location}
* @return new location if and only if the file or directory is successfully moved; null otherwise.
* @throws IOException
*/
@Nullable
protected Location renameLocation(Location oldLocation, Location newLocation) throws IOException {
// if the newLocation does not exists or the oldLocation does we try to rename. If either one of them is false then
// the underlying call to renameTo will throw IOException which we re-throw.
if (!newLocation.exists() && oldLocation.exists()) {
Locations.getParent(newLocation).mkdirs();
try {
return oldLocation.renameTo(newLocation);
} catch (IOException ioe) {
newLocation.delete();
LOG.warn("Failed to rename {} to {}", oldLocation, newLocation);
throw ioe;
}
} else {
LOG.debug("Failed to perform rename. Either the new location {} already exists or old location {} " +
"does not exist.", newLocation, oldLocation);
return null;
}
}
}