/* * Copyright 2015-2016 OpenCB * * 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.opencb.opencga.catalog.io; import org.opencb.opencga.catalog.config.Configuration; import org.opencb.opencga.catalog.exceptions.CatalogIOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.*; import java.net.URI; import java.net.URISyntaxException; import java.util.Date; import java.util.List; import java.util.Properties; import java.util.stream.Stream; public abstract class CatalogIOManager { /** * OpenCGA folders are created in the ROOTDIR. * OPENCGA_USERS_FOLDER contains users workspaces organized by 'userId' * OPENCGA_ANONYMOUS_USERS_FOLDER contains anonymous users workspaces organized by 'randomStringId' * OPENCGA_BIN_FOLDER contains all packaged binaries delivered within OpenCGA */ protected static final String OPENCGA_USERS_FOLDER = "users/"; protected static final String OPENCGA_ANONYMOUS_USERS_FOLDER = "anonymous/"; protected static final String OPENCGA_BIN_FOLDER = "bin/"; /** * Users folders are created inside user workspace. * USER_PROJECTS_FOLDER this folder stores all the projects with the studies and files * USER_BIN_FOLDER contains user specific binaries */ protected static final String USER_PROJECTS_FOLDER = "projects/"; protected static final String USER_BIN_FOLDER = "bin/"; protected static final String SHARED_DATA_FOLDER = "shared_data/"; protected static final String DEFAULT_OPENCGA_JOBS_FOLDER = "jobs/"; protected static Logger logger; // private Path opencgaRootDirPath; protected URI rootDir; protected URI jobsDir; // protected URI rootDir; protected URI tmp; @Deprecated protected Properties properties; protected Configuration configuration; private CatalogIOManager() { logger = LoggerFactory.getLogger(this.getClass()); } public CatalogIOManager(String catalogConfigurationFile) throws CatalogIOException { this(); this.configuration = new Configuration(); //this.properties = new Properties(); try { this.configuration.load(new FileInputStream(catalogConfigurationFile)); //this.properties.load(new FileInputStream(propertiesFile)); } catch (IOException e) { throw new CatalogIOException("Error loading Catalog Configuration file", e); } setup(); } @Deprecated public CatalogIOManager(Properties properties) throws CatalogIOException { this(); this.properties = properties; setup(); } public CatalogIOManager(Configuration configuration) throws CatalogIOException { this(); this.configuration = configuration; setup(); } protected abstract void setConfiguration(Configuration configuration) throws CatalogIOException; /** * This method creates the folders and workspace structure for storing the OpenCGA data. I * * @throws CatalogIOException CatalogIOException */ public void setup() throws CatalogIOException { setConfiguration(configuration); if (!exists(rootDir)) { logger.info("Initializing CatalogIOManager. Creating main folder '" + rootDir + "'"); createDirectory(rootDir, true); } checkDirectoryUri(rootDir, true); if (!exists(jobsDir)) { logger.info("Initializing CatalogIOManager. Creating jobs folder '" + jobsDir + "'"); createDirectory(jobsDir); } checkDirectoryUri(jobsDir, true); if (!exists(rootDir.resolve(OPENCGA_USERS_FOLDER))) { createDirectory(rootDir.resolve(OPENCGA_USERS_FOLDER)); } if (!exists(rootDir.resolve(OPENCGA_ANONYMOUS_USERS_FOLDER))) { createDirectory(rootDir.resolve(OPENCGA_ANONYMOUS_USERS_FOLDER)); } if (!exists(rootDir.resolve(OPENCGA_BIN_FOLDER))) { createDirectory(rootDir.resolve(OPENCGA_BIN_FOLDER)); } } protected void checkParam(String param) throws CatalogIOException { if (param == null || param.equals("")) { throw new CatalogIOException("Parameter '" + param + "' not valid"); } } protected abstract void checkUriExists(URI uri) throws CatalogIOException; protected abstract void checkUriScheme(URI uri) throws CatalogIOException; protected abstract void checkDirectoryUri(URI uri, boolean writable) throws CatalogIOException; public abstract boolean exists(URI uri); public abstract URI createDirectory(URI uri, boolean parents) throws CatalogIOException; public URI createDirectory(URI uri) throws CatalogIOException { return createDirectory(uri, false); } public abstract void deleteDirectory(URI uri) throws CatalogIOException; public abstract void deleteFile(URI fileUri) throws CatalogIOException; public abstract void rename(URI oldName, URI newName) throws CatalogIOException; public abstract boolean isDirectory(URI uri); public abstract void copyFile(URI source, URI target) throws IOException, CatalogIOException; public abstract void moveFile(URI source, URI target) throws IOException, CatalogIOException; public URI getUsersUri() throws CatalogIOException { return rootDir.resolve(OPENCGA_USERS_FOLDER); } public URI getAnonymousUsersUri() throws CatalogIOException { return rootDir.resolve(OPENCGA_ANONYMOUS_USERS_FOLDER); } public URI getUserUri(String userId) throws CatalogIOException { checkParam(userId); try { return getUsersUri().resolve(new URI(null, userId.endsWith("/") ? userId : (userId + "/"), null)); } catch (URISyntaxException e) { throw CatalogIOException.uriSyntaxException(userId, e); } } public URI getAnonymousUserUri(String userId) throws CatalogIOException { // FIXME: Should replicate to getAnonymousPojectUri, // ...Study..., etc ? checkParam(userId); try { return getAnonymousUsersUri().resolve(new URI(null, userId.endsWith("/") ? userId : (userId + "/"), null)); } catch (URISyntaxException e) { throw CatalogIOException.uriSyntaxException(userId, e); } } public URI getProjectsUri(String userId) throws CatalogIOException { return getUserUri(userId).resolve(USER_PROJECTS_FOLDER); } public URI getProjectUri(String userId, String projectId) throws CatalogIOException { try { return getProjectsUri(userId).resolve(new URI(null, projectId.endsWith("/") ? projectId : (projectId + "/"), null)); } catch (URISyntaxException e) { throw CatalogIOException.uriSyntaxException(userId, e); } } @Deprecated public URI getStudyUri(String userId, String projectId, String studyId) throws CatalogIOException { checkParam(studyId); try { return getProjectUri(userId, projectId).resolve(new URI(null, studyId.endsWith("/") ? studyId : (studyId + "/"), null)); } catch (URISyntaxException e) { throw CatalogIOException.uriSyntaxException(studyId, e); } } public URI getFileUri(URI studyUri, String relativeFilePath) throws CatalogIOException { checkUriExists(studyUri); checkParam(relativeFilePath); try { return studyUri.resolve(new URI(null, relativeFilePath, null)); } catch (URISyntaxException e) { throw CatalogIOException.uriSyntaxException(relativeFilePath, e); } } public URI getJobsUri(String userId) throws CatalogIOException { checkParam(userId); return jobsDir; } public abstract URI getTmpUri(); // FIXME Still used? public URI createUser(String userId) throws CatalogIOException { checkParam(userId); // //just to show the previous version // Path usersPath = Paths.get(opencgaRootDir, CatalogIOManager.OPENCGA_USERS_FOLDER); // checkDirectoryUri(usersPath, true); // // Path userPath = usersPath.resolve(userId); // try { // if(!Files.exists(userPath)) { // Files.createDirectory(userPath); // Files.createDirectory(Paths.get(userPath.toString(), CatalogIOManager.USER_PROJECTS_FOLDER)); // Files.createDirectory(Paths.get(userPath.toString(), CatalogIOManager.USER_BIN_FOLDER)); // // return userPath; // } // } catch (IOException e) { // throw new CatalogIOManagerException("IOException" + e.toString()); // } // return null; // URI opencgaPath = new URI(opencgaRootDir); URI usersUri = getUsersUri(); checkDirectoryUri(usersUri, true); URI userPath = getUserUri(userId); try { if (!exists(userPath)) { createDirectory(userPath); createDirectory(userPath.resolve(CatalogIOManager.USER_PROJECTS_FOLDER)); createDirectory(userPath.resolve(CatalogIOManager.USER_BIN_FOLDER)); return userPath; } } catch (CatalogIOException e) { throw e; } return null; } public void deleteUser(String userId) throws CatalogIOException { URI userUri = getUserUri(userId); checkUriExists(userUri); deleteDirectory(userUri); } public URI createAnonymousUser(String anonymousUserId) throws CatalogIOException { checkParam(anonymousUserId); URI usersUri = getAnonymousUsersUri(); checkDirectoryUri(usersUri, true); URI userUri = getAnonymousUserUri(anonymousUserId); try { if (!exists(userUri)) { createDirectory(userUri); createDirectory(userUri.resolve(USER_PROJECTS_FOLDER)); createDirectory(userUri.resolve(USER_BIN_FOLDER)); return userUri; } } catch (CatalogIOException e) { throw e; } return null; } public void deleteAnonymousUser(String anonymousUserId) throws CatalogIOException { URI anonymousUserUri = getAnonymousUserUri(anonymousUserId); checkUriExists(anonymousUserUri); deleteDirectory(anonymousUserUri); // return anonymousUserPath; } public URI createProject(String userId, String projectId) throws CatalogIOException { checkParam(projectId); // URI projectRootUri = getProjectsUri(userId); // checkDirectoryUri(projectRootUri, true); //assuming catalogManager has checked it // URI projectUri = projectRootUri.resolve(projectId); URI projectUri = getProjectUri(userId, projectId); try { if (!exists(projectUri)) { projectUri = createDirectory(projectUri, true); //createDirectory(projectUri.resolve(SHARED_DATA_FOLDER)); } } catch (CatalogIOException e) { throw new CatalogIOException("createProject(): could not create the project folder", e); } return projectUri; } public void deleteProject(String userId, String projectId) throws CatalogIOException { URI projectUri = getProjectUri(userId, projectId); checkUriExists(projectUri); deleteDirectory(projectUri); } public void renameProject(String userId, String oldProjectId, String newProjectId) throws CatalogIOException { URI oldFolder = getProjectUri(userId, oldProjectId); URI newFolder = getProjectUri(userId, newProjectId); rename(oldFolder, newFolder); } public boolean existProject(String userId, String projectId) throws CatalogIOException { return exists(getProjectUri(userId, projectId)); } public URI createStudy(String userId, String projectId, String studyId) throws CatalogIOException { checkParam(studyId); URI projectUri = getProjectUri(userId, projectId); checkDirectoryUri(projectUri, true); URI studyUri = getStudyUri(userId, projectId, studyId); return createStudy(studyUri); } public URI createStudy(URI studyUri) throws CatalogIOException { checkUriScheme(studyUri); try { if (!exists(studyUri)) { studyUri = createDirectory(studyUri); } } catch (CatalogIOException e) { throw new CatalogIOException("createStudy method: could not create the study folder: " + e.toString(), e); } return studyUri; } public void deleteStudy(URI studyUri) throws CatalogIOException { checkUriScheme(studyUri); checkUriExists(studyUri); deleteDirectory(studyUri); } // public void renameStudy(String userId, String projectId, String oldStudyId, String newStudyId) // throws CatalogIOManagerException { // URI oldFolder = getStudyUri(userId, projectId, oldStudyId); // URI newFolder = getStudyUri(userId, projectId, newStudyId); // // try { // rename(oldFolder, newFolder); // } catch (IOException e) { // throw new CatalogIOManagerException("renameStudy(): could not rename the study folder: " + e.toString()); // } // } public URI createJobOutDir(String userId, String folderName) throws CatalogIOException { checkParam(folderName); URI jobsFolderUri = getJobsUri(userId); checkDirectoryUri(jobsFolderUri, true); URI jobUri; try { jobUri = jobsFolderUri.resolve(new URI(null, folderName, null)); } catch (URISyntaxException e) { throw CatalogIOException.uriSyntaxException(folderName, e); } if (!exists(jobUri)) { try { jobUri = createDirectory(jobUri, true); } catch (CatalogIOException e) { throw new CatalogIOException("createStudy method: could not create the study folder: " + e.toString(), e); } } else { throw new CatalogIOException("createJobOutDir method: Job folder " + folderName + "already exists."); } return jobUri; } public URI createFolder(URI studyUri, String folderName, boolean parent) throws CatalogIOException { checkParam(folderName); if (!folderName.endsWith("/")) { folderName += "/"; } checkDirectoryUri(studyUri, true); // Path fullFolderPath = getFileUri(userid, projectId, studyId, objectId); URI folderUri = null; try { folderUri = studyUri.resolve(new URI(null, folderName, null)); } catch (URISyntaxException e) { throw CatalogIOException.uriSyntaxException(folderName, e); } try { if (!exists(folderUri)) { if (parent) { createDirectory(folderUri, true); } else { checkDirectoryUri(folderUri.resolve(".."), true); createDirectory(folderUri); } } } catch (CatalogIOException e) { throw new CatalogIOException("createFolder(): could not create the directory", e); } return folderUri; } public void createFile(URI studyUri, String filePath, InputStream inputStream) throws CatalogIOException { URI fileUri = getFileUri(studyUri, filePath); createFile(fileUri, inputStream); } public abstract void createFile(URI fileUri, InputStream inputStream) throws CatalogIOException; public void deleteFile(URI studyUri, String filePath) throws CatalogIOException { URI fileUri = getFileUri(studyUri, filePath); checkUriExists(fileUri); logger.debug("Deleting {}", fileUri.toString()); if (isDirectory(fileUri)) { deleteDirectory(fileUri); } else { deleteFile(fileUri); } } public DataInputStream getFileObject(URI studyUri, String objectId, int start, int limit) throws CatalogIOException { URI fileUri = getFileUri(studyUri, objectId); return getFileObject(fileUri, start, limit); } public abstract DataInputStream getFileObject(URI fileUri, int start, int limit) throws CatalogIOException; public DataInputStream getGrepFileObject(URI studyUri, String objectId, String pattern, boolean ignoreCase, boolean multi) throws CatalogIOException { URI fileUri = getFileUri(studyUri, objectId); return getGrepFileObject(fileUri, pattern, ignoreCase, multi); } public abstract DataInputStream getGrepFileObject(URI fileUri, String pattern, boolean ignoreCase, boolean multi) throws CatalogIOException; // // public abstract DataInputStream getFileFromJob(Path jobPath, String filename, String zip) // throws CatalogIOManagerException,FileNotFoundException; // // public abstract DataInputStream getGrepFileFromJob(Path jobPath, String filename, String pattern, boolean ignoreCase, // boolean multi) throws CatalogIOManagerException,IOException; // // public abstract InputStream getJobZipped(Path jobPath, String jobId) throws CatalogIOManagerException, IOException; public abstract DataOutputStream createOutputStream(URI fileUri, boolean overwrite) throws CatalogIOException; public abstract String calculateChecksum(URI file) throws CatalogIOException; public abstract List<URI> listFiles(URI directory) throws CatalogIOException; public Stream<URI> listFilesStream(URI directory) throws CatalogIOException { return listFiles(directory).stream(); } public abstract long getFileSize(URI file) throws CatalogIOException; public abstract Date getCreationDate(URI file) throws CatalogIOException; public abstract Date getModificationDate(URI file) throws CatalogIOException; // public abstract String getCreationDate(URI file); }