Skip to content

Commit

Permalink
Merge branch 'refs/heads/development' into feature/provide-pattern-ma…
Browse files Browse the repository at this point in the history
…tching

# Conflicts:
#	src/main/java/life/qbic/qpostman/list/ListCommand.java
  • Loading branch information
KochTobi committed Jul 11, 2024
2 parents ea99800 + 3557137 commit 5c8dcab
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 90 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>life.qbic</groupId>
<artifactId>postman-cli</artifactId>
<version>2.1.0</version>
<version>2.1.1</version>
<name>Postman cli</name>
<url>https://github.com/qbicsoftware/postman-cli</url>
<description>A client software written in Java for dataset downloads from QBiC's data management system openBIS </description>
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/life/qbic/App.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package life.qbic;

import java.util.Arrays;
import life.qbic.qpostman.common.DefaultExceptionHandler;
import life.qbic.qpostman.common.PostmanCommand;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
Expand All @@ -16,6 +17,7 @@ public class App {
public static void main(String[] args) {
LOG.debug("command line arguments: " + Arrays.deepToString(args));
CommandLine cmd = new CommandLine(new PostmanCommand());
cmd.setExecutionExceptionHandler(new DefaultExceptionHandler());
int exitCode = cmd.execute(args);
System.exit(exitCode);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package life.qbic.qpostman.common;

import java.nio.file.Path;
import java.util.Optional;
import life.qbic.qpostman.common.options.AuthenticationOptions.NoPasswordException;
import life.qbic.qpostman.common.options.SampleIdentifierOptions.IdentityFileEmptyException;
import life.qbic.qpostman.common.options.SampleIdentifierOptions.IdentityFileNotFoundException;
import life.qbic.qpostman.common.options.SampleIdentifierOptions.IdentityFileNotReadableException;
import life.qbic.qpostman.common.options.SampleIdentifierOptions.SampleInput.ToShortSampleIdsException;
import life.qbic.qpostman.openbis.ConnectionException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.remoting.RemoteAccessException;
import picocli.CommandLine;
import picocli.CommandLine.IExecutionExceptionHandler;
import picocli.CommandLine.ParseResult;

/**
* The exception handler to use for exceptions within commands.
*/
public class DefaultExceptionHandler implements IExecutionExceptionHandler {
private static final Logger log = LogManager.getLogger(DefaultExceptionHandler.class);
private static final String LOG_PATH = Optional.ofNullable(System.getProperty("log.path"))
.orElse("logs");

private void logError(RuntimeException e) {
if (e instanceof RemoteAccessException remoteAccessException) {
log.error(
"Failed to connect to OpenBis: " + remoteAccessException.getCause().getMessage());
log.debug(remoteAccessException.getMessage(), remoteAccessException);
} else if (e instanceof AuthenticationException authenticationException) {
log.error(
"Could not authenticate user %s. Please make sure to provide the correct password.".formatted(
authenticationException.username()));
log.debug(authenticationException.getMessage(), authenticationException);
} else if (e instanceof ConnectionException) {
log.error("Could not connect to QBiC's data source. Have you requested access to the "
+ "server? If not please write to [email protected]");
log.debug(e.getMessage(), e);
} else if (e instanceof NoPasswordException) {
log.error("No password provided. Please provide your password.");
} else if (e instanceof IdentityFileEmptyException identityFileException) {
log.error(identityFileException.getFile().getAbsolutePath() + " does not contain any identifiers.");
} else if (e instanceof IdentityFileNotFoundException identityFileNotFoundException) {
log.error("File not found: " + identityFileNotFoundException.getFile());
} else if (e instanceof IdentityFileNotReadableException identityFileNotReadableException) {
log.error("Not allowed to read file " + identityFileNotReadableException.getFile());
} else if (e instanceof ToShortSampleIdsException toShortSampleIdsException) {
log.error(
"Please provide at least 5 letters for your sample identifiers. The following sample identifiers are to short: "
+ toShortSampleIdsException.getIdentifiers());
} else {
log.error("Something went wrong. For more detailed output see " + Path.of(LOG_PATH, "postman.log").toAbsolutePath());
log.debug(e.getMessage(), e);
}
}

@Override
public int handleExecutionException(Exception e, CommandLine commandLine, ParseResult parseResult)
throws Exception {
logError((RuntimeException) e);
commandLine.usage(commandLine. getErr());
return commandLine.getCommandSpec().exitCodeOnExecutionException();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@
import static picocli.CommandLine.ArgGroup;

import java.util.StringJoiner;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import picocli.CommandLine.Option;

public class AuthenticationOptions {
private static final Logger log = LogManager.getLogger(AuthenticationOptions.class);

@Option(
@Option(
names = {"-u", "--user"},
required = true,
description = "openBIS user name")
Expand Down Expand Up @@ -55,11 +52,11 @@ char[] getPassword() {
if (nonNull(environmentVariable) && !environmentVariable.isBlank()) {
return environmentVariable.toCharArray();
}
log.error("No password provided. Please provide your password.");
System.exit(2);
return null; // not reachable due to System.exit in previous line
throw new NoPasswordException();
}
}

public static class NoPasswordException extends RuntimeException {
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package life.qbic.qpostman.common.options;

import static java.util.Objects.requireNonNull;
import static picocli.CommandLine.ArgGroup;
import static picocli.CommandLine.Option;
import static picocli.CommandLine.Parameters;
Expand All @@ -12,13 +13,9 @@
import java.util.List;
import java.util.StringJoiner;
import java.util.stream.Collectors;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class SampleIdentifierOptions {

private static final Logger log = LogManager.getLogger(SampleIdentifierOptions.class);

@ArgGroup(multiplicity = "1")
public SampleInput sampleInput;

Expand All @@ -35,28 +32,67 @@ public String toString() {

static class IdentityFileParser {

private IdentityFileParser() {

}
public static List<String> parseIdentityFile(Path path) {
File file = path.toFile();
if (!file.exists()) {
log.error("File not found: " + file);
System.exit(2);
throw new IdentityFileNotFoundException(file);
}
if (!file.canRead()) {
log.error("Not allowed to read file " + file);
System.exit(2);
throw new IdentityFileNotReadableException(file);
}
try {
return Files.readAllLines(path).stream()
List<String> readIdentifiers = Files.readAllLines(path).stream()
.filter(it -> !it.isBlank())
.filter(it -> !it.startsWith("#"))
.map(String::strip)
.collect(Collectors.toList());
if (readIdentifiers.isEmpty()) {
throw new IdentityFileEmptyException(file);
}
return readIdentifiers;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

public static class IdentityFileParsingException extends RuntimeException {
protected final File file;

public IdentityFileParsingException(File file) {
this.file = file;
}

public File getFile() {
return file;
}
}

public static class IdentityFileNotFoundException extends IdentityFileParsingException {

public IdentityFileNotFoundException(File file) {
super(file);
}
}

public static class IdentityFileNotReadableException extends IdentityFileParsingException {


public IdentityFileNotReadableException(File file) {
super(file);
}
}

public static class IdentityFileEmptyException extends IdentityFileParsingException {

public IdentityFileEmptyException(File file) {
super(file);
}
}

public static class SampleInput {

@Option(
Expand All @@ -69,17 +105,38 @@ public static class SampleInput {
public List<String> ids = new ArrayList<>();

public List<String> getIds() {
if (ids.isEmpty()) {
List<String> identities = IdentityFileParser.parseIdentityFile(filePath).stream()
.filter(it -> !it.isBlank()).toList();
var identifiers = ids.isEmpty()
? parseIdentifiers()
: ids;
// we want to prevent matching to something shorter than a project code.
List<String> toShortSampleIds = identifiers.stream()
.filter(it -> !it.matches("^\\w{5,}"))
.toList();
if (!toShortSampleIds.isEmpty()) {
throw new ToShortSampleIdsException(toShortSampleIds);
}
return identifiers;
}

if (identities.isEmpty()) {
log.error(filePath.toString() + " does not contain any identifiers.");
System.exit(2);
}
return identities;
public static class SampleIdParsingException extends RuntimeException {
}

public static class ToShortSampleIdsException extends SampleIdParsingException {
protected final List<String> identifiers;

public ToShortSampleIdsException(List<String> identifiers) {
this.identifiers = requireNonNull(identifiers, "identifiers must not be null");
}
return ids;

public List<String> getIdentifiers() {
return identifiers;
}
}

private List<String> parseIdentifiers() {
return IdentityFileParser.parseIdentityFile(filePath).stream()
.filter(it -> !it.isBlank())
.toList();
}


Expand Down
30 changes: 1 addition & 29 deletions src/main/java/life/qbic/qpostman/download/DownloadCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import life.qbic.qpostman.common.AuthenticationException;
import life.qbic.qpostman.common.FileSizeFormatter;
import life.qbic.qpostman.common.functions.FileFilter;
import life.qbic.qpostman.common.functions.FindSourceSample;
Expand All @@ -25,19 +23,15 @@
import life.qbic.qpostman.common.structures.DataSetWrapper;
import life.qbic.qpostman.common.structures.FileSize;
import life.qbic.qpostman.download.WriteFileToDisk.DownloadReport;
import life.qbic.qpostman.openbis.ConnectionException;
import life.qbic.qpostman.openbis.OpenBisSessionProvider;
import life.qbic.qpostman.openbis.ServerFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.remoting.RemoteAccessException;

@Command(name = "download",
description = "Download data from QBiC.")
public class DownloadCommand implements Runnable {
private static final Logger log = LogManager.getLogger(DownloadCommand.class);
private static final String LOG_PATH = Optional.ofNullable(System.getProperty("log.path"))
.orElse("logs");
@Mixin
AuthenticationOptions authenticationOptions;
@Mixin
Expand All @@ -51,7 +45,7 @@ public class DownloadCommand implements Runnable {

@Override
public void run() {
try {

Functions functions = functions();

Collection<DataFile> dataSetFiles = functions.searchDataSets()
Expand Down Expand Up @@ -85,28 +79,6 @@ public void run() {
if (!failedDownloads.isEmpty()) {
log.warn("Failed to download %s / %s files.".formatted(failedDownloads.size(), downloadReports.size()));
}


} catch (RemoteAccessException remoteAccessException) {
log.error(
"Failed to connect to OpenBis: " + remoteAccessException.getCause().getMessage());
log.debug(remoteAccessException.getMessage(), remoteAccessException);
System.exit(1);
} catch (AuthenticationException authenticationException) {
log.error(
"Could not authenticate user %s. Please make sure to provide the correct password.".formatted(
authenticationException.username()));
log.debug(authenticationException.getMessage(), authenticationException);
System.exit(1);
} catch (ConnectionException e) {
log.error("Could not connect to QBiC's data source. Have you requested access to the "
+ "server? If not please write to [email protected]");
log.debug(e.getMessage(), e);
System.exit(1);
} catch (RuntimeException e) {
log.error("Something went wrong. For more detailed output see " + Path.of(LOG_PATH, "postman.log").toAbsolutePath());
log.debug(e.getMessage(), e);
}
}

private SearchFiles searchFiles(Collection<DataSetWrapper> it) {
Expand Down
Loading

0 comments on commit 5c8dcab

Please sign in to comment.