diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e00ec70b1681e8e921195d51802b1a297943e2fc --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.project +.classpath +.settings/ +target/ diff --git a/haas-imagej-client/pom.xml b/haas-imagej-client/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..91644e1d2ae020d303daaf05c3d1c7f069a22495 --- /dev/null +++ b/haas-imagej-client/pom.xml @@ -0,0 +1,105 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + + <parent> + <groupId>org.scijava</groupId> + <artifactId>pom-scijava</artifactId> + <version>17.1.1</version> + <relativePath /> + </parent> + + <groupId>cz.it4i.fiji</groupId> + <artifactId>inspect-menus</artifactId> + <version>0.0.1-SNAPSHOT</version> + <packaging>jar</packaging> + <name>Simple ImageJ Commands</name> + <description>This example provides an introduction to writing ImageJ commands.</description> + <url>https://github.com/[MY-ORG]/[MY-REPO]</url> + <inceptionYear>2013</inceptionYear> + <organization> + <name>[MY-ORGANIZATION-NAME]</name> + <url>[MY-ORGANIZATION-WEB-SITE]</url> + </organization> + <licenses> + <license> + <name>CC0 1.0 Universal License</name> + <url>http://creativecommons.org/publicdomain/zero/1.0/</url> + <distribution>repo</distribution> + </license> + </licenses> + + <developers> + <developer> + <id>[MY-GITHUB-ID]</id> + <name>[MY-FULL-NAME]</name> + <url>https://imagej.net/User:[MY-IMAGEJ-WIKI-ACCOUNT]</url> + </developer> + </developers> + <contributors> + <contributor> + <name>None</name> + </contributor> + </contributors> + + <mailingLists> + <mailingList> + <name>ImageJ Forum</name> + <archive>http://forum.imagej.net/</archive> + </mailingList> + </mailingLists> + + <scm> + <connection>scm:git:git://github.com/[MY-ORG]/[MY-REPO]</connection> + <developerConnection>scm:git:git@github.com:[MY-ORG]/[MY-REPO]</developerConnection> + <tag>HEAD</tag> + <url>https://github.com/[MY-ORG]/[MY-REPO]</url> + </scm> + <issueManagement> + <system>GitHub Issues</system> + <url>http://github.com/[MY-ORG]/[MY-REPO]/issues</url> + </issueManagement> + <ciManagement> + <system>None</system> + </ciManagement> + <properties> + <license.licenseName>cc0</license.licenseName> + <license.copyrightOwners>N/A</license.copyrightOwners> + <license.projectName>ImageJ software for multidimensional image + processing and analysis.</license.projectName> + + </properties> + + <repositories> + <repository> + <id>imagej.public</id> + <url>http://maven.imagej.net/content/groups/public</url> + </repository> + </repositories> + + <dependencies> + <dependency> + <groupId>net.imagej</groupId> + <artifactId>imagej</artifactId> + </dependency> + <dependency> + <groupId>net.preibisch</groupId> + <artifactId>multiview-reconstruction</artifactId> + <version>0.1.1-SNAPSHOT</version> + </dependency> + <!-- https://mvnrepository.com/artifact/net.imagej/imagej-legacy --> + <dependency> + <groupId>net.imagej</groupId> + <artifactId>imagej-legacy</artifactId> + </dependency> + <dependency> + <groupId>cz.it4i.fiji</groupId> + <artifactId>haas-java-client</artifactId> + <version>0.0.1-SNAPSHOT</version> + </dependency> + <!-- https://mvnrepository.com/artifact/net.imagej/imagej-launcher --> + + + </dependencies> +</project> diff --git a/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/CheckStatusOfHaaS.java b/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/CheckStatusOfHaaS.java new file mode 100644 index 0000000000000000000000000000000000000000..8592605036f381fb66b2737d58fa09ccc748e94f --- /dev/null +++ b/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/CheckStatusOfHaaS.java @@ -0,0 +1,56 @@ +package cz.it4i.fiji.haas; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collection; +import java.util.stream.Collectors; + +import org.scijava.command.Command; +import org.scijava.log.LogService; +import org.scijava.plugin.Parameter; +import org.scijava.plugin.Plugin; + +import net.imagej.ImageJ; +/** + * + * @author koz01 + * + */ +@Plugin(type = Command.class, headless = true, menuPath = "Plugins>Check status of HaaS") +public class CheckStatusOfHaaS implements Command { + + @Parameter + private LogService log; + + @Parameter(label="Work directory",persist=true) + private File workDirectory; + + @SuppressWarnings("unused") + private JobManager jobManager; + + @Override + public void run() { + try { + jobManager = new JobManager(getWorkingDirectoryPath()); + } catch (IOException e) { + log.error(e); + } + } + + + private Path getWorkingDirectoryPath() { + return Paths.get(workDirectory.toString()); + } + + public static void main(final String... args) { + // Launch ImageJ as usual. + final ImageJ ij = new ImageJ(); + ij.launch(args); + + ij.command().run(CheckStatusOfHaaS.class, true); + } + +} diff --git a/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/Job.java b/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/Job.java new file mode 100644 index 0000000000000000000000000000000000000000..ea06fb55f821a5f538d37ca437711fa34e7f1c06 --- /dev/null +++ b/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/Job.java @@ -0,0 +1,113 @@ +package cz.it4i.fiji.haas; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.nio.file.Files; +import java.nio.file.OpenOption; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumSet; +import java.util.Properties; +import java.util.function.Supplier; + +import cz.it4i.fiji.haas_java_client.HaaSClient; +import cz.it4i.fiji.haas_java_client.JobState; + +public class Job { + + private static final String JOB_ID_PROPERTY = "job.id"; + + private static final String JOB_STATE_PROPERTY = "job.state"; + + public static boolean isJobPath(Path p) { + return isValidPath(p); + } + + private static String JOB_INFO_FILE = ".jobinfo"; + + private Path jobDir; + + private Supplier<HaaSClient> haasClientSupplier; + + private JobState state; + + public Job(Path path, Collection<Path> files, Supplier<HaaSClient> haasClientSupplier) throws IOException { + this(haasClientSupplier); + HaaSClient client = this.haasClientSupplier.get(); + long id = client.start(files, "TestOutRedirect", + Collections.emptyList()); + jobDir = path.resolve("" + id); + Files.createDirectory(jobDir); + state = client.obtainJobInfo(id).getState(); + saveJobinfo(); + } + + + + public Job(Path p, Supplier<HaaSClient> haasClientSupplier) throws IOException { + this(haasClientSupplier); + jobDir = p; + loadJobInfo(); + checkStateForDownload(); + } + + private synchronized void checkStateForDownload() throws IOException { + long jobId = getJobId(); + JobState actualState = haasClientSupplier.get().obtainJobInfo(jobId).getState(); + if(EnumSet.of(JobState.Failed, JobState.Finished, JobState.Canceled).contains(actualState) && state != actualState) { + haasClientSupplier.get().download(jobId, jobDir); + state = actualState; + saveJobinfo(); + } + } + + + + private Job(Supplier<HaaSClient> haasClientSupplier) { + this.haasClientSupplier = haasClientSupplier; + } + + private synchronized void saveJobinfo() throws IOException { + try(OutputStream ow= Files.newOutputStream(jobDir.resolve(JOB_INFO_FILE), StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE)) { + Properties prop = new Properties(); + prop.setProperty(JOB_ID_PROPERTY, "" + getJobId()); + prop.setProperty(JOB_STATE_PROPERTY, "" + state); + prop.store(ow, null); + } + } + + + private synchronized void loadJobInfo() throws IOException { + try(InputStream is= Files.newInputStream(jobDir.resolve(JOB_INFO_FILE))) { + Properties prop = new Properties(); + prop.load(is); + state = JobState.valueOf(prop.getProperty(JOB_STATE_PROPERTY)); + assert getJobId() == Long.parseLong(prop.getProperty(JOB_ID_PROPERTY)); + } + } + + private long getJobId() { + return getJobId(jobDir); + } + + + + private static boolean isValidPath(Path path) { + + try { + getJobId(path); + } catch (NumberFormatException e) { + return false; + } + return Files.isRegularFile(path.resolve(JOB_INFO_FILE)); + } + + private static long getJobId(Path path) { + return Long.parseLong(path.getFileName().toString()); + } + +} diff --git a/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/JobManager.java b/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/JobManager.java new file mode 100644 index 0000000000000000000000000000000000000000..733d9322970c9fb8fabcb06019f6be9ae4cd53c4 --- /dev/null +++ b/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/JobManager.java @@ -0,0 +1,44 @@ +package cz.it4i.fiji.haas; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collection; +import java.util.LinkedList; + +import cz.it4i.fiji.haas_java_client.HaaSClient; + +public class JobManager { + + private Path workDirectory; + + private Collection<Job> jobs = new LinkedList<>(); + + private HaaSClient haasClient; + + public JobManager(Path workDirectory) throws IOException { + super(); + this.workDirectory = workDirectory; + Files.list(this.workDirectory).filter(p -> Files.isDirectory(p) && Job.isJobPath(p)) + .forEach(p -> { + try { + jobs.add(new Job(p,this::getHaasClient)); + } catch (IOException e) { + e.printStackTrace(); + } + }); + + } + + public void startJob(Path path, Collection<Path> files) throws IOException { + jobs.add(new Job(path, files,this::getHaasClient)); + } + + private HaaSClient getHaasClient() { + if(haasClient == null) { + haasClient = new HaaSClient(2l, 9600, 6l, "DD-17-31"); + } + return haasClient; + } + +} diff --git a/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/RunWithHaaS.java b/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/RunWithHaaS.java new file mode 100644 index 0000000000000000000000000000000000000000..4dfec903b38b5c95cb6262871d2557fe4b906868 --- /dev/null +++ b/haas-imagej-client/src/main/java/cz/it4i/fiji/haas/RunWithHaaS.java @@ -0,0 +1,65 @@ +package cz.it4i.fiji.haas; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collection; +import java.util.stream.Collectors; + +import org.scijava.command.Command; +import org.scijava.log.LogService; +import org.scijava.plugin.Parameter; +import org.scijava.plugin.Plugin; + +import net.imagej.ImageJ; +/** + * + * @author koz01 + * + */ +@Plugin(type = Command.class, headless = true, menuPath = "Plugins>Run with HaaS") +public class RunWithHaaS implements Command { + + @Parameter + private LogService log; + + @Parameter(label="Work directory",persist=true) + private File workDirectory; + + @Parameter(label="Data directory") + private File dataDirectory; + + private JobManager jobManager; + + @Override + public void run() { + try { + jobManager = new JobManager(getWorkingDirectoryPath()); + jobManager.startJob(getWorkingDirectoryPath(),getContent(dataDirectory)); + } catch (IOException e) { + log.error(e); + } + } + + + private Path getWorkingDirectoryPath() { + return Paths.get(workDirectory.toString()); + } + + + private Collection<Path> getContent(File dataDirectory) throws IOException { + return Files.list(Paths.get(dataDirectory.toString())).collect(Collectors.toList()); + } + + + public static void main(final String... args) { + // Launch ImageJ as usual. + final ImageJ ij = new ImageJ(); + ij.launch(args); + + ij.command().run(RunWithHaaS.class, true); + } + +}