org.dashbuilder.migration.DashbuilderDataMigration Maven / Gradle / Ivy
/*
* Copyright 2019 Red Hat, Inc. and/or its affiliates.
*
* 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 org.dashbuilder.migration;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import java.io.File;
import java.net.URI;
import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.inject.Named;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.uberfire.backend.server.spaces.SpacesAPIImpl;
import org.uberfire.commons.services.cdi.Startup;
import org.uberfire.io.IOService;
import org.uberfire.java.nio.file.Path;
import org.uberfire.java.nio.file.FileSystem;
import org.uberfire.java.nio.file.FileSystemAlreadyExistsException;
import org.uberfire.java.nio.file.SimpleFileVisitor;
import org.uberfire.java.nio.file.attribute.BasicFileAttributes;
import org.uberfire.java.nio.fs.jgit.FileSystemLock;
import org.uberfire.java.nio.fs.jgit.FileSystemLockManager;
import org.uberfire.java.nio.fs.jgit.JGitFileSystem;
import org.uberfire.java.nio.fs.jgit.JGitPathImpl;
import org.uberfire.mvp.Command;
import org.uberfire.java.nio.file.FileVisitResult;
import org.uberfire.java.nio.file.Files;
import org.uberfire.spaces.Space;
import org.uberfire.spaces.SpacesAPI;
import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull;
@ApplicationScoped
@Startup
public class DashbuilderDataMigration {
private static final Logger LOGGER = LoggerFactory.getLogger(DashbuilderDataMigration.class);
private IOService ioService;
private FileSystem datasetsFS;
private FileSystem pluginsFS;
private FileSystem perspectivesFS;
private FileSystem navigationFS;
public DashbuilderDataMigration() {
}
@Inject
public DashbuilderDataMigration(
final @Named("ioStrategy") IOService ioService,
final @Named("datasetsFS") FileSystem datasetsFS,
final @Named("pluginsFS") FileSystem pluginsFS,
final @Named("perspectivesFS") FileSystem perspectivesFS,
final @Named("navigationFS") FileSystem navigationFS) {
this.ioService = ioService;
this.datasetsFS = datasetsFS;
this.pluginsFS = pluginsFS;
this.perspectivesFS = perspectivesFS;
this.navigationFS = navigationFS;
}
@PostConstruct
private void init() {
runWithLock(() -> {
migrateDatasets();
migratePerspectives();
migrateNavigation();
});
}
private void migrateDatasets() {
FileSystem oldDatasetsFS = lookupFileSystem(SpacesAPI.DEFAULT_SPACE, "datasets");
this.migrateDatasets(oldDatasetsFS, datasetsFS);
cleanupFileSystem(oldDatasetsFS);
}
private FileSystem lookupFileSystem(Space space, String name) {
FileSystem fs;
URI uri = new SpacesAPIImpl().resolveFileSystemURI(
SpacesAPI.Scheme.GIT,
space,
name);
HashMap env = new HashMap<>();
env.put("init", Boolean.TRUE);
env.put("internal", Boolean.TRUE);
try {
fs = ioService.newFileSystem(uri, env);
} catch (FileSystemAlreadyExistsException e) {
fs = ioService.getFileSystem(uri);
}
return fs;
}
private void cleanupFileSystem(FileSystem fs) {
Path root = getRoot(fs);
if (root != null && fs instanceof JGitFileSystem) {
try {
Path fsPath = fs.getPath("");
Files.delete(fsPath);
} catch (Exception e) {
LOGGER.error("Failed to remove the datasets git repository.");
LOGGER.debug("Error during dashbuilder migration", e);
}
}
}
private void migratePerspectives() {
this.migratePerspectives(pluginsFS, perspectivesFS);
}
private void migrateNavigation() {
this.migrateNavigation(pluginsFS, navigationFS);
}
public void migrateDatasets(FileSystem sourceFS, FileSystem targetFS) {
LOGGER.info("attempt to migrate datasets");
migrate(sourceFS,
targetFS,
path -> !path.getFileName().toString().equals("readme.md"));
}
public void migratePerspectives(FileSystem sourceFS, FileSystem targetFS) {
LOGGER.info("attempt to migrate perspectives");
migrate(sourceFS,
targetFS,
path -> path.getFileName().toString().startsWith("perspective_layout"));
}
public void migrateNavigation(FileSystem sourceFS, FileSystem targetFS) {
LOGGER.info("attempt to migrate navigation");
migrate(sourceFS,
targetFS,
path -> path.getFileName().toString().equals("navtree.json"));
}
private void migrate(FileSystem sourceFS, FileSystem targetFS, Predicate predicate) {
Path sourceRoot = getRoot(sourceFS);
Path targetRoot = getRoot(targetFS);
if (sourceRoot == null) {
LOGGER.info("source does not exists");
return;
}
if (targetRoot == null) {
LOGGER.error("target does not exists");
return;
}
LOGGER.info("moving from " + sourceFS.getName() + " to " + targetFS.getName());
Files.walkFileTree(sourceRoot, new SimpleFileVisitor() {
@Override
public FileVisitResult visitFile(final Path path, final BasicFileAttributes attrs) {
checkNotNull("file", path);
checkNotNull("attrs", attrs);
Path targetPath = targetRoot.resolve(path.toString());
if (!predicate.test(path)) {
LOGGER.debug("skip file " + path.toString());
} else if (ioService.exists(targetPath)) {
LOGGER.debug("file " + path.toString() + " already exists on target");
Files.delete(path);
} else {
LOGGER.debug("moving file " + path.toString());
Files.copy(path, targetPath);
Files.delete(path);
}
return FileVisitResult.CONTINUE;
}
});
}
private Path getRoot(FileSystem fileSystem) {
try {
return fileSystem.getRootDirectories().iterator().next();
} catch (Exception e) {
LOGGER.debug("could not get filesystem root", e);
return null;
}
}
private void runWithLock(Command command) {
String lockName = "data-migration.lock";
String markerName = "data-migration.done";
TimeUnit lastAccessTimeUnit = TimeUnit.SECONDS;
int lastAccessThreshold = 1;
// get .niogit/dashbuilder path
File dir = ((JGitPathImpl) navigationFS.getPath("/"))
.getFileSystem()
.getGit()
.getRepository()
.getDirectory()
.getParentFile();
File marker = new File(dir, markerName);
FileSystemLock lock = FileSystemLockManager
.getInstance()
.getFileSystemLock(
dir,
lockName,
lastAccessTimeUnit,
lastAccessThreshold);
try {
lock.lock();
if (!marker.exists()) {
marker.createNewFile();
command.execute();
}
} catch (java.io.IOException e) {
LOGGER.error(e.getMessage(), e);
} finally {
lock.unlock();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy