Skip to content

Commit

Permalink
Merge pull request #4 from qbicsoftware/feature/data-options
Browse files Browse the repository at this point in the history
allows to list existing and upload new datasets
  • Loading branch information
wow-such-code authored Jun 28, 2024
2 parents 3897229 + 3a99d0d commit 68a1e95
Show file tree
Hide file tree
Showing 9 changed files with 494 additions and 61 deletions.
11 changes: 9 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
<description>A client software written in Java to query openBIS</description>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<java.version>11</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>5.3.31</spring.version>
</properties>
Expand Down Expand Up @@ -138,6 +137,14 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
56 changes: 37 additions & 19 deletions src/main/java/life/qbic/App.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package life.qbic;

import ch.ethz.sis.openbis.generic.OpenBIS;
import life.qbic.io.commandline.CommandLineOptions;
import life.qbic.model.Configuration;
import life.qbic.model.download.Authentication;
import life.qbic.model.download.AuthenticationException;
import life.qbic.model.download.ConnectionException;
import org.apache.logging.log4j.LogManager;
Expand Down Expand Up @@ -35,30 +35,36 @@ private static Boolean isNotNullOrEmpty(String envVariableCommandLineParameter)
}

/**
* Logs into OpenBIS asks for and verifies password.
* Logs into OpenBIS, asks for and verifies password.
*
* @return An instance of the Authentication class.
*/
public static Authentication loginToOpenBIS(
char[] password, String user, String as_url) {
public static OpenBIS loginToOpenBIS(
char[] password, String user, String url) {
setupLog();

// Ensure 'logs' folder is created
File logFolder = new File(Configuration.LOG_PATH.toAbsolutePath().toString());
if (!logFolder.exists()) {
boolean logFolderCreated = logFolder.mkdirs();
if (!logFolderCreated) {
LOG.error("Could not create log folder '" + logFolder.getAbsolutePath() + "'");
System.exit(1);
}
}
OpenBIS authentication = new OpenBIS(url);

return tryLogin(authentication, user, password);
}

/**
* Logs into OpenBIS, asks for and verifies password, includes Datastore Server connection.
*
* @return An instance of the Authentication class.
*/
public static OpenBIS loginToOpenBIS(
char[] password, String user, String url, String dssUrl) {
setupLog();

OpenBIS authentication = new OpenBIS(url, dssUrl);

return tryLogin(authentication, user, password);
}

Authentication authentication =
new Authentication(
user,
new String(password),
as_url);
private static OpenBIS tryLogin(OpenBIS authentication, String user, char[] password) {
try {
authentication.login();
authentication.login(user, new String(password));
} catch (ConnectionException e) {
LOG.error(e.getMessage(), e);
LOG.error("Could not connect to QBiC's data source. Have you requested access to the "
Expand All @@ -70,4 +76,16 @@ public static Authentication loginToOpenBIS(
}
return authentication;
}

private static void setupLog() {
// Ensure 'logs' folder is created
File logFolder = new File(Configuration.LOG_PATH.toAbsolutePath().toString());
if (!logFolder.exists()) {
boolean logFolderCreated = logFolder.mkdirs();
if (!logFolderCreated) {
LOG.error("Could not create log folder '" + logFolder.getAbsolutePath() + "'");
System.exit(1);
}
}
}
}
80 changes: 77 additions & 3 deletions src/main/java/life/qbic/io/commandline/AuthenticationOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
import static java.util.Objects.nonNull;
import static picocli.CommandLine.ArgGroup;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.StringJoiner;
import java.util.TreeMap;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import picocli.CommandLine;
Expand All @@ -14,17 +20,49 @@ public class AuthenticationOptions {

@Option(
names = {"-u", "--user"},
required = true,
description = "openBIS user name")
public String user;
private String user;
@ArgGroup(multiplicity = "1") // ensures the password is provided once with at least one of the possible options.
PasswordOptions passwordOptions;

@Option(
names = {"-as", "-as_url"},
description = "ApplicationServer URL",
scope = CommandLine.ScopeType.INHERIT)
public String as_url;
private String as_url;

@Option(
names = {"-dss", "-dss_url"},
description = "DatastoreServer URL",
scope = CommandLine.ScopeType.INHERIT)
private String dss_url;

@Option(
names = {"-config", "-config_file"},
description = "Config file path to provide openbis server information.",
scope = CommandLine.ScopeType.INHERIT)
public String configPath;

public String getUser() {
if(user == null & configPath!=null && !configPath.isBlank()) {
user = ReadProperties.getProperties(configPath).get("user");
}
return user;
}

public String getDSS() {
if(dss_url == null & configPath!=null && !configPath.isBlank()) {
dss_url = ReadProperties.getProperties(configPath).get("dss");
}
return dss_url;
}

public String getAS() {
if(as_url == null & configPath!=null && !configPath.isBlank()) {
as_url = ReadProperties.getProperties(configPath).get("as");
}
return as_url;
}

public char[] getPassword() {
return passwordOptions.getPassword();
Expand Down Expand Up @@ -76,4 +114,40 @@ public String toString() {
.toString();
//ATTENTION: do not expose the password here!
}

public static class ReadProperties {

public static TreeMap<String, String> getProperties(String infile) {

TreeMap<String, String> properties = new TreeMap<>();
BufferedReader bfr = null;
try {
bfr = new BufferedReader(new FileReader(new File(infile)));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}

String line;
while (true) {
try {
if ((line = bfr.readLine()) == null)
break;
} catch (IOException e) {
throw new RuntimeException(e);
}
if (!line.startsWith("#") && !line.isEmpty()) {
String[] property = line.trim().split("=");
properties.put(property[0].trim(), property[1].trim());
}
}

try {
bfr.close();
} catch (IOException e) {
throw new RuntimeException(e);
}

return(properties);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@

// main command with format specifiers for the usage help message
@Command(name = "openbis-scripts",
subcommands = { SampleHierarchyCommand.class },
subcommands = { SampleHierarchyCommand.class, FindDatasetsCommand.class, UploadDatasetCommand.class },
description = "A client software for querying openBIS.",
mixinStandardHelpOptions = true)
mixinStandardHelpOptions = true, versionProvider = ManifestVersionProvider.class)
public class CommandLineOptions {
private static final Logger LOG = LogManager.getLogger(CommandLineOptions.class);

@Option(names = {"-V", "--version"},
versionHelp = true,
description = "print version information",
scope = CommandLine.ScopeType.INHERIT)
boolean versionRequested;
boolean versionRequested = false;

@Option(
names = {"-h", "--help"},
Expand Down
68 changes: 68 additions & 0 deletions src/main/java/life/qbic/io/commandline/DownloadDatasetCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package life.qbic.io.commandline;

import ch.ethz.sis.openbis.generic.OpenBIS;
import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSet;
import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.Person;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import life.qbic.App;
import life.qbic.model.download.OpenbisConnector;
import picocli.CommandLine.Command;
import picocli.CommandLine.Mixin;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;

@Command(name = "list-data",
description = "lists datasets and their details for a given experiment code")
public class DownloadDatasetCommand implements Runnable {

@Parameters(arity = "1", paramLabel = "experiment", description = "The code of the experiment data is attached to")
private String experimentCode;
@Option(arity = "1", paramLabel = "<space>", description = "Optional openBIS spaces to filter results", names = {"-s", "--space"})
private String space;
@Mixin
AuthenticationOptions auth = new AuthenticationOptions();

@Override
public void run() {
List<String> spaces = new ArrayList<>();
if (space != null) {
System.out.println("Querying experiment in space: " + space + "...");
spaces.add(space);
} else {
System.out.println("Querying experiment in all available spaces...");
}
OpenBIS authentication = App.loginToOpenBIS(auth.getPassword(), auth.getUser(), auth.getAS());
OpenbisConnector openbis = new OpenbisConnector(authentication);
List<DataSet> datasets = openbis.listDatasetsOfExperiment(spaces, experimentCode).stream()
.sorted(Comparator.comparing(
(DataSet d) -> d.getExperiment().getProject().getSpace().getCode())).collect(
Collectors.toList());
int datasetIndex = 0;
for (DataSet dataSet : datasets) {
datasetIndex++;
System.out.println("["+datasetIndex+"]");
System.out.println(dataSet.getExperiment().getIdentifier());
System.out.println(dataSet.getCode());
System.out.println(dataSet.getType().getCode());
System.out.println(dataSet.getRegistrationDate());
System.out.println(new SimpleDateFormat("MM-dd-yyyy").format(dataSet.getRegistrationDate()));
Person person = dataSet.getRegistrator();
System.out.println(person.getFirstName() + " " + person.getLastName());
System.out.println();
}
}

private String getTimeStamp() {
final String PATTERN_FORMAT = "YYYY-MM-dd_HHmmss";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PATTERN_FORMAT);
return LocalDateTime.ofInstant(Instant.now(), ZoneOffset.UTC).format(formatter);
}
}
70 changes: 70 additions & 0 deletions src/main/java/life/qbic/io/commandline/FindDatasetsCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package life.qbic.io.commandline;

import ch.ethz.sis.openbis.generic.OpenBIS;
import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSet;
import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.Person;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import life.qbic.App;
import life.qbic.model.download.OpenbisConnector;
import picocli.CommandLine.Command;
import picocli.CommandLine.Mixin;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;

@Command(name = "list-data",
description = "lists datasets and their details for a given experiment code")
public class FindDatasetsCommand implements Runnable {

@Parameters(arity = "1", paramLabel = "experiment", description = "The code of the experiment data is attached to")
private String experimentCode;
@Option(arity = "1", paramLabel = "<space>", description = "Optional openBIS spaces to filter samples", names = {"-s", "--space"})
private String space;
@Mixin
AuthenticationOptions auth = new AuthenticationOptions();

@Override
public void run() {
List<String> spaces = new ArrayList<>();
if (space != null) {
System.out.println("Querying experiment in space: " + space + "...");
spaces.add(space);
} else {
System.out.println("Querying experiment in all available spaces...");
}
OpenBIS authentication = App.loginToOpenBIS(auth.getPassword(), auth.getUser(), auth.getAS());
OpenbisConnector openbis = new OpenbisConnector(authentication);
List<DataSet> datasets = openbis.listDatasetsOfExperiment(spaces, experimentCode).stream()
.sorted(Comparator.comparing(
(DataSet d) -> d.getExperiment().getProject().getSpace().getCode())).collect(
Collectors.toList());
int datasetIndex = 0;
System.out.println();
System.out.printf("Found %s datasets for experiment %s:%n", datasets.size(), experimentCode);
for (DataSet dataSet : datasets) {
datasetIndex++;
System.out.println("["+datasetIndex+"]");
System.out.printf("ID: %s (%s)%n", dataSet.getCode(), dataSet.getExperiment().getIdentifier());
System.out.println("Type: "+dataSet.getType().getCode());
Person person = dataSet.getRegistrator();
String simpleTime = new SimpleDateFormat("MM-dd-yy HH:mm:ss").format(dataSet.getRegistrationDate());
String name = person.getFirstName() +" "+ person.getLastName();
String uploadedBy = "Uploaded by "+name+" ("+simpleTime+")";
System.out.println(uploadedBy);
System.out.println();
}
}

private String getTimeStamp() {
final String PATTERN_FORMAT = "YYYY-MM-dd_HHmmss";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PATTERN_FORMAT);
return LocalDateTime.ofInstant(Instant.now(), ZoneOffset.UTC).format(formatter);
}
}
Loading

0 comments on commit 68a1e95

Please sign in to comment.