package org.gcube.storagehub; import java.io.InputStream; import java.io.StringWriter; import java.net.URL; import java.util.List; import org.gcube.common.authorization.utils.manager.SecretManager; import org.gcube.common.authorization.utils.manager.SecretManagerProvider; import org.gcube.common.scope.impl.ScopeBean; import org.gcube.common.scope.impl.ScopeBean.Type; import org.gcube.common.storagehub.client.dsl.ContainerType; import org.gcube.common.storagehub.client.dsl.FileContainer; import org.gcube.common.storagehub.client.dsl.FolderContainer; import org.gcube.common.storagehub.client.dsl.ItemContainer; import org.gcube.common.storagehub.client.dsl.ListResolver; import org.gcube.common.storagehub.client.dsl.ListResolverTyped; import org.gcube.common.storagehub.client.dsl.StorageHubClient; import org.gcube.common.storagehub.model.Metadata; import org.gcube.common.storagehub.model.exceptions.StorageHubException; import org.gcube.common.storagehub.model.items.Item; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class StorageHubManagement { private static final Logger logger = LoggerFactory.getLogger(StorageHubManagement.class); protected MetadataMatcher metadataMatcher; protected final StorageHubClient storageHubClient; protected FileContainer persitedFile; protected String mimeType; public StorageHubManagement() { storageHubClient = new StorageHubClient(); } public void setMetadataMatcher(MetadataMatcher checkMetadata) { this.metadataMatcher = checkMetadata; } public String getMimeType() { return mimeType; } public FileContainer getPersistedFile() { return persitedFile; } protected void recursiveList(FolderContainer folder, int level) throws StorageHubException { ListResolverTyped listResolverTyped = folder.list(); List> containers = listResolverTyped.includeHidden().getContainers(); for(ItemContainer itemContainer : containers) { ContainerType containerType = itemContainer.getType(); logItem(itemContainer, level); switch(containerType) { case FOLDER: FolderContainer folderContainer = (FolderContainer) itemContainer; recursiveList(folderContainer, level + 1); break; case FILE: break; case GENERIC_ITEM: break; default: break; } } } protected FolderContainer getWorkspaceRoot() { return storageHubClient.getWSRoot(); } protected FolderContainer getOrCreateFolder(FolderContainer parent, String name, String description, boolean hidden) throws Exception { FolderContainer destinationFolder = null; ListResolverTyped listResolverTyped = parent.list(); List> containers = listResolverTyped.includeHidden().getContainers(); for(ItemContainer itemContainer : containers) { if(itemContainer instanceof FolderContainer) { if(itemContainer.get().getName().compareTo(name) == 0) { destinationFolder = (FolderContainer) itemContainer; } } } if(destinationFolder == null) { if(hidden) { destinationFolder = parent.newHiddenFolder(name, description); } else { destinationFolder = parent.newFolder(name, description); } } return destinationFolder; } protected FolderContainer getContextFolder() throws Exception { FolderContainer destinationFolder = getWorkspaceRoot(); String currentContext = SecretManagerProvider.instance.get().getContext(); ScopeBean scopeBean = new ScopeBean(currentContext); switch(scopeBean.type()) { case INFRASTRUCTURE: case VO: String folderName = currentContext.replaceFirst("/", "").replace("/", "_"); destinationFolder = getOrCreateFolder(destinationFolder, folderName, "", false); break; case VRE: destinationFolder = storageHubClient.openVREFolder(); break; default: break; } return destinationFolder; } public FolderContainer getApplicationFolder() throws Exception { FolderContainer destinationFolder = getContextFolder(); SecretManager secretManager = SecretManagerProvider.instance.get(); String currentContext = secretManager.getContext(); ScopeBean scopeBean = new ScopeBean(currentContext); if(scopeBean.is(Type.VRE)) { String username = secretManager.getUser().getUsername(); destinationFolder = getOrCreateFolder(destinationFolder, username, "Folder Created for user/application", true); } return destinationFolder; } public FolderContainer getDestinationFolder(String mimeType) throws Exception { FolderContainer destinationFolder = getApplicationFolder(); String[] splittedMimeType = mimeType.split("/"); for(String name : splittedMimeType) { destinationFolder = getOrCreateFolder(destinationFolder, name, "Folder Created using mimetype", false); } return destinationFolder; } protected boolean isPersistedFile(FileContainer fileContainer, String filename) { // Checking if the file is already a persisted file of the workspace if(fileContainer.get().getName().startsWith(filename)) { if(metadataMatcher != null) { Metadata metadata = fileContainer.get().getMetadata(); return metadataMatcher.check(metadata); } else { return true; } } return false; } protected void logItem(ItemContainer itemContainer) { logItem(itemContainer, 0); } protected void logItem(ItemContainer itemContainer, int level) { StringWriter indent = new StringWriter(level + 1); for(int i = 0; i < level+1; i++) { indent.append('-'); } indent.append(" "); Item item = itemContainer.get(); logger.debug("{}{} {} (ID:{}){}", indent.toString(), itemContainer.getType(), item.getName(), itemContainer.getId(), item.isHidden() ? " (hidden)" : ""); } protected void tree(FolderContainer folderContainer) throws Exception { logItem(folderContainer,0); recursiveList(folderContainer, 1); } public URL persistFile(InputStream inputStream, String fileName, String mimeType) throws Exception { this.mimeType = mimeType; FolderContainer destinationFolder = getDestinationFolder(mimeType); persitedFile = destinationFolder.uploadFile(inputStream, fileName, "This file has been created to ensure persistence"); if(metadataMatcher != null) { persitedFile.setMetadata(metadataMatcher.getMetadata()); } URL finalURL = persitedFile.getPublicLink(); logger.debug("File persistence has been ensured. The file is available at {}", finalURL); return finalURL; } public FileContainer getPersistedFile(String filename, String mimeType) throws Exception { FolderContainer destinationFolder = getDestinationFolder(mimeType); ListResolver listResolver = destinationFolder.findByName(filename); List> itemContainers = listResolver.withMetadata().getContainers(); for(ItemContainer itemContainer : itemContainers) { if(itemContainer.getType()==ContainerType.FILE) { if(isPersistedFile((FileContainer) itemContainer, filename)) { logger.debug("The file with mimetype {} and name {} was found in the expected folder (i.e. id:{}, path:{}) and the check on metadata succeded. The file is the one expected.", mimeType, filename, destinationFolder.getId(), destinationFolder.get().getPath()); this.persitedFile = (FileContainer) itemContainer; return this.persitedFile; }else { logger.warn("The file with mimetype {} and name {} was found in the expected folder (i.e. id:{}, path:{}) but the check on metadata failed. The file is not the one expected.", mimeType, filename, destinationFolder.getId(), destinationFolder.get().getPath()); } } } logger.warn("Unable to find file with mimetype {} and name {} in the expected folder (i.e. id:{}, path:{})", mimeType, filename, destinationFolder.getId(), destinationFolder.get().getPath()); return null; } public void removePersistedFile(String filename, String mimeType) throws Exception { persitedFile = getPersistedFile(filename, mimeType); if(persitedFile !=null) { logger.info("Persited file with mimetype {} and name {} was found. Goign to remove it.", mimeType, filename); persitedFile.delete(); } } }