diff --git a/.github/workflows/deploy-maven-repository-workflow.yml b/.github/workflows/deploy-maven-repository-workflow.yml
index 7bb0fb306..e34012dcb 100644
--- a/.github/workflows/deploy-maven-repository-workflow.yml
+++ b/.github/workflows/deploy-maven-repository-workflow.yml
@@ -33,7 +33,7 @@ jobs:
gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} # Value of the GPG private key to import
gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase
- name: Deploy to Maven Central repository
- run: mvn clean deploy -DskipTests -P deploy-maven ${{ inputs.maven_opts }} --no-transfer-progress
+ run: mvn clean deploy -DskipTests -Pdeploy-maven ${{ inputs.maven_opts }} --no-transfer-progress
env:
MAVEN_NEXUS_USER: ${{ secrets.MAVEN_USER_TOKEN }}
MAVEN_NEXUS_PASSWORD: ${{ secrets.MAVEN_PASSWORD_TOKEN }}
@@ -44,6 +44,6 @@ jobs:
distribution: 'temurin'
java-version: '8'
- name: Deploy to GitHub Packages repository
- run: mvn clean deploy -DskipTests -P deploy-github ${{ inputs.maven_opts }} --no-transfer-progress
+ run: mvn clean deploy -DskipTests -Pdeploy-github ${{ inputs.maven_opts }} --no-transfer-progress
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/pull-request-approved.yml b/.github/workflows/pull-request-approved.yml
index 0c489fd73..7e34cf39c 100644
--- a/.github/workflows/pull-request-approved.yml
+++ b/.github/workflows/pull-request-approved.yml
@@ -35,7 +35,7 @@ jobs:
test:
name: "Run all tests before merging"
needs: calculate-xetabase-branch
- uses: opencb/java-common-libs/.github/workflows/test-xetabase-workflow.yml@develop
+ uses: ./.github/workflows/test-xetabase-workflow.yml
with:
branch: ${{ needs.calculate-xetabase-branch.outputs.xetabase_branch }}
task: ${{ github.event.pull_request.head.ref }}
diff --git a/.github/workflows/test-analysis.yml b/.github/workflows/test-analysis.yml
index 487cbb350..3af763725 100644
--- a/.github/workflows/test-analysis.yml
+++ b/.github/workflows/test-analysis.yml
@@ -39,4 +39,4 @@ jobs:
check_name: "Surefire tests report"
report_paths: './**/surefire-reports/TEST-*.xml'
commit: '${{ github.sha }}'
- fail_on_test_failures: true
+ fail_on_test_failures: true
\ No newline at end of file
diff --git a/.github/workflows/test-xetabase-workflow.yml b/.github/workflows/test-xetabase-workflow.yml
index 0b060f583..3720d93cf 100644
--- a/.github/workflows/test-xetabase-workflow.yml
+++ b/.github/workflows/test-xetabase-workflow.yml
@@ -77,17 +77,6 @@ jobs:
with:
mongodb-version: 6.0
mongodb-replica-set: rs-test
- - name: K8s Tunnel MongoDB
- run: |
- wget https://dl.k8s.io/release/v1.28.2/bin/linux/amd64/kubectl
- chmod +x ./kubectl
- echo "${{ secrets.AZURE_KUBE_CONFIG }}" > admin.conf
- ./kubectl -n cellbase-db port-forward services/cellbase-rs0-svc 27018:27017 --kubeconfig ./admin.conf &
- - name: DockerHub login
- uses: docker/login-action@v3
- with:
- username: ${{ env.DOCKER_HUB_USER }}
- password: ${{ env.DOCKER_HUB_PASSWORD }}
- name: Install sshpass
run: sudo apt-get install sshpass
- name: Add SSH Host to known_hosts
@@ -97,11 +86,11 @@ jobs:
env:
SSH_HOST: ${{ env.SSH_HOST }}
SSH_PORT: ${{ env.SSH_PORT }}
- - name: Run all OpenCB Junit tests, ie. java-common-libs, biodata, cellbase, opencga and opencga-enterprise
+ - name: Run all OpenCB Junit tests, ie. java-common-libs, biodata, opencga and opencga-enterprise
run: |
cd opencga-enterprise
ln -s ../opencga opencga-home
- ./build.sh -t -l runShortTests -b -s -T ${{ inputs.task }} -c localhost:27018 -H hdp3.1
+ ./build.sh -t -l runShortTests -b -s -T ${{ inputs.task }}
- name: Upload reports results to Github
uses: actions/upload-artifact@v4
with:
diff --git a/commons-datastore/commons-datastore-core/pom.xml b/commons-datastore/commons-datastore-core/pom.xml
index d3e72035e..e297caa08 100644
--- a/commons-datastore/commons-datastore-core/pom.xml
+++ b/commons-datastore/commons-datastore-core/pom.xml
@@ -13,6 +13,10 @@
commons-datastore-core
jar
+ OpenCB commons-datastore-core project
+ OpenCB commons project contains several Java libs for Bioinformatics
+ http://www.opencb.org
+
com.fasterxml.jackson.core
diff --git a/commons-datastore/commons-datastore-core/src/main/java/org/opencb/commons/datastore/core/ObjectMap.java b/commons-datastore/commons-datastore-core/src/main/java/org/opencb/commons/datastore/core/ObjectMap.java
index 743b610f0..dd1beec33 100644
--- a/commons-datastore/commons-datastore-core/src/main/java/org/opencb/commons/datastore/core/ObjectMap.java
+++ b/commons-datastore/commons-datastore-core/src/main/java/org/opencb/commons/datastore/core/ObjectMap.java
@@ -38,7 +38,6 @@ public class ObjectMap implements Map, Serializable {
private static final Pattern KEY_SPLIT_PATTERN = Pattern.compile("(^[^\\[\\].]+(?:\\[[^\\]]+\\])?)(?:\\.(.*))*");
private static final Pattern LIST_FILTER_PATTERN = Pattern.compile("([^\\[\\]]+)\\[([^=]*?)(?:[=]?)([^=]+)\\]$");
- public static final Pattern COMMA_SEPARATED_LIST_SPLIT_PATTERN = Pattern.compile("((?:(?!,\\S).)+)+");
public ObjectMap() {
objectMap = new LinkedHashMap<>();
diff --git a/commons-datastore/commons-datastore-core/src/test/java/org/opencb/commons/datastore/core/ObjectMapTest.java b/commons-datastore/commons-datastore-core/src/test/java/org/opencb/commons/datastore/core/ObjectMapTest.java
index 15f4e4e40..d0098015b 100644
--- a/commons-datastore/commons-datastore-core/src/test/java/org/opencb/commons/datastore/core/ObjectMapTest.java
+++ b/commons-datastore/commons-datastore-core/src/test/java/org/opencb/commons/datastore/core/ObjectMapTest.java
@@ -263,35 +263,4 @@ public void testGetWithFilterFromList() {
assertEquals("CGHI", objectMap.get("nestedList[nested.value=G].nested.list[id=Cghi].name"));
}
- @Test
- public void testPatternListSplit() {
- List originalValues = Arrays.asList("disorder1", "disorder2, blabla", "disorder3");
- objectMap.put("key", StringUtils.join(originalValues, ","));
- objectMap.put("key1", "");
- objectMap.put("key2", "my value");
- objectMap.put("key3", Arrays.asList("1", "2"));
- objectMap.put("key4", Arrays.asList(1, 2));
-
- List values = objectMap.getAsStringList("key", ObjectMap.COMMA_SEPARATED_LIST_SPLIT_PATTERN);
- assertEquals(originalValues.size(), values.size());
- assertTrue(originalValues.containsAll(values));
-
- values = objectMap.getAsStringList("key1", ObjectMap.COMMA_SEPARATED_LIST_SPLIT_PATTERN);
- assertEquals(1, values.size());
- assertEquals("", values.get(0));
-
- values = objectMap.getAsStringList("key2", ObjectMap.COMMA_SEPARATED_LIST_SPLIT_PATTERN);
- assertEquals(1, values.size());
- assertEquals("my value", values.get(0));
-
- values = objectMap.getAsStringList("key3", ObjectMap.COMMA_SEPARATED_LIST_SPLIT_PATTERN);
- assertEquals(2, values.size());
- assertEquals("1", values.get(0));
- assertEquals("2", values.get(1));
-
- values = objectMap.getAsStringList("key4", ObjectMap.COMMA_SEPARATED_LIST_SPLIT_PATTERN);
- assertEquals(2, values.size());
- assertEquals("1", values.get(0));
- assertEquals("2", values.get(1));
- }
}
diff --git a/commons-datastore/commons-datastore-mongodb/pom.xml b/commons-datastore/commons-datastore-mongodb/pom.xml
index 75ff94b2b..04e5b2189 100644
--- a/commons-datastore/commons-datastore-mongodb/pom.xml
+++ b/commons-datastore/commons-datastore-mongodb/pom.xml
@@ -13,6 +13,10 @@
commons-datastore-mongodb
jar
+ OpenCB commons-datastore-mongodb project
+ OpenCB commons project contains several Java libs for Bioinformatics
+ http://www.opencb.org
+
org.opencb.commons
diff --git a/commons-datastore/commons-datastore-mongodb/src/main/java/org/opencb/commons/datastore/mongodb/MongoDBQueryUtils.java b/commons-datastore/commons-datastore-mongodb/src/main/java/org/opencb/commons/datastore/mongodb/MongoDBQueryUtils.java
index e80265d53..a57e79cf6 100644
--- a/commons-datastore/commons-datastore-mongodb/src/main/java/org/opencb/commons/datastore/mongodb/MongoDBQueryUtils.java
+++ b/commons-datastore/commons-datastore-mongodb/src/main/java/org/opencb/commons/datastore/mongodb/MongoDBQueryUtils.java
@@ -36,9 +36,9 @@
import static com.mongodb.client.model.Aggregates.*;
import static com.mongodb.client.model.Projections.*;
+import static org.opencb.commons.datastore.mongodb.MongoDBQueryUtils.Accumulator.*;
import static org.opencb.commons.datastore.mongodb.MongoDBQueryUtils.Accumulator.bucket;
import static org.opencb.commons.datastore.mongodb.MongoDBQueryUtils.Accumulator.count;
-import static org.opencb.commons.datastore.mongodb.MongoDBQueryUtils.Accumulator.*;
/**
* Created by imedina on 17/01/16.
@@ -178,6 +178,53 @@ public static Bson createFilter(String mongoDbField, String queryParam, Query qu
return filter;
}
+ /**
+ * Splits a string by the given separator, handling quoted values properly.
+ * Quoted values can contain the separator character without being split.
+ * Removes surrounding quotes and trims whitespace from each value.
+ *
+ * @param input the input string to split
+ * @param separator the separator to split by ("," or ";")
+ * @return list of trimmed, unquoted values
+ */
+ public static List smartSplit(String input, String separator) {
+ List result = new ArrayList<>();
+ if (input == null || input.isEmpty()) {
+ return result;
+ }
+
+ boolean inQuotes = false;
+ StringBuilder currentValue = new StringBuilder();
+
+ for (int i = 0; i < input.length(); i++) {
+ char c = input.charAt(i);
+
+ if (c == '"') {
+ inQuotes = !inQuotes;
+ } else if (!inQuotes && input.substring(i).startsWith(separator)) {
+ // Found separator outside quotes
+ String value = currentValue.toString().trim();
+ if (value.startsWith("\"") && value.endsWith("\"") && value.length() > 1) {
+ value = value.substring(1, value.length() - 1);
+ }
+ result.add(value.trim());
+ currentValue = new StringBuilder();
+ i += separator.length() - 1; // Skip the separator
+ } else {
+ currentValue.append(c);
+ }
+ }
+
+ // Add the last value
+ String value = currentValue.toString().trim();
+ if (value.startsWith("\"") && value.endsWith("\"") && value.length() > 1) {
+ value = value.substring(1, value.length() - 1);
+ }
+ result.add(value.trim());
+
+ return result;
+ }
+
private static String getLogicalSeparator(LogicalOperator operator) {
return (operator != null && operator.equals(LogicalOperator.AND)) ? AND : OR;
}
@@ -258,8 +305,13 @@ protected static String getOp2(String op, String value) {
public static Bson createAutoFilter(String mongoDbField, String queryParam, Query query, QueryParam.Type type, LogicalOperator operator)
throws NumberFormatException {
-
- List queryParamList = query.getAsStringList(queryParam, getLogicalSeparator(operator));
+ List queryParamList;
+ String value = query.getString(queryParam);
+ if (StringUtils.isNotEmpty(value) && value.contains("\"")) {
+ queryParamList = smartSplit(value, getLogicalSeparator(operator));
+ } else {
+ queryParamList = query.getAsStringList(queryParam, getLogicalSeparator(operator));
+ }
return createAutoFilter(mongoDbField, queryParam, type, operator, queryParamList);
}
diff --git a/commons-datastore/commons-datastore-mongodb/src/test/java/org/opencb/commons/datastore/mongodb/SmartSplitTest.java b/commons-datastore/commons-datastore-mongodb/src/test/java/org/opencb/commons/datastore/mongodb/SmartSplitTest.java
new file mode 100644
index 000000000..59a5b2c2b
--- /dev/null
+++ b/commons-datastore/commons-datastore-mongodb/src/test/java/org/opencb/commons/datastore/mongodb/SmartSplitTest.java
@@ -0,0 +1,63 @@
+package org.opencb.commons.datastore.mongodb;
+
+import org.junit.Test;
+import java.util.List;
+import static org.junit.Assert.assertEquals;
+
+public class SmartSplitTest {
+
+ @Test
+ public void testSmartSplitWithQuotedCommaValues() {
+ String input = "\"a \",\" b\",\" c \"";
+ List result = MongoDBQueryUtils.smartSplit(input, ",");
+
+ assertEquals(3, result.size());
+ assertEquals("a", result.get(0));
+ assertEquals("b", result.get(1));
+ assertEquals("c", result.get(2));
+ }
+
+ @Test
+ public void testSmartSplitWithQuotedSemicolonValues() {
+ String input = "\"a \";\" b\";\" c \"";
+ List result = MongoDBQueryUtils.smartSplit(input, ";");
+
+ assertEquals(3, result.size());
+ assertEquals("a", result.get(0));
+ assertEquals("b", result.get(1));
+ assertEquals("c", result.get(2));
+ }
+
+ @Test
+ public void testSmartSplitWithNonQuotedValues() {
+ String input = "a,b,c";
+ List result = MongoDBQueryUtils.smartSplit(input, ",");
+
+ assertEquals(3, result.size());
+ assertEquals("a", result.get(0));
+ assertEquals("b", result.get(1));
+ assertEquals("c", result.get(2));
+ }
+
+ @Test
+ public void testSmartSplitWithNonQuotedValuesAndSpaces() {
+ String input = "a, b,c ";
+ List result = MongoDBQueryUtils.smartSplit(input, ",");
+
+ assertEquals(3, result.size());
+ assertEquals("a", result.get(0));
+ assertEquals("b", result.get(1));
+ assertEquals("c", result.get(2));
+ }
+
+ @Test
+ public void testSmartSplitWithMixedValues() {
+ String input = "\"a, with comma\",b,\"c\"";
+ List result = MongoDBQueryUtils.smartSplit(input, ",");
+
+ assertEquals(3, result.size());
+ assertEquals("a, with comma", result.get(0));
+ assertEquals("b", result.get(1));
+ assertEquals("c", result.get(2));
+ }
+}
diff --git a/commons-datastore/commons-datastore-solr/pom.xml b/commons-datastore/commons-datastore-solr/pom.xml
index 272f93a49..d12b5a736 100644
--- a/commons-datastore/commons-datastore-solr/pom.xml
+++ b/commons-datastore/commons-datastore-solr/pom.xml
@@ -29,6 +29,11 @@
commons-datastore-solr
jar
+ OpenCB commons-datastore-solr project
+ OpenCB commons project contains several Java libs for Bioinformatics
+ http://www.opencb.org
+
+
org.opencb.commons
diff --git a/commons-datastore/pom.xml b/commons-datastore/pom.xml
index 4f66880f6..895662cfc 100644
--- a/commons-datastore/pom.xml
+++ b/commons-datastore/pom.xml
@@ -13,6 +13,11 @@
commons-datastore
pom
+ OpenCB commons-datastore project
+ OpenCB commons project contains several Java libs for Bioinformatics
+ http://www.opencb.org
+
+
commons-datastore-core
commons-datastore-mongodb
diff --git a/commons-lib/pom.xml b/commons-lib/pom.xml
index 168118b23..d28d48754 100644
--- a/commons-lib/pom.xml
+++ b/commons-lib/pom.xml
@@ -13,6 +13,10 @@
commons-lib
jar
+ OpenCB commons-lib project
+ OpenCB commons project contains several Java libs for Bioinformatics
+ http://www.opencb.org
+
org.opencb.commons
diff --git a/commons-lib/src/main/java/org/opencb/commons/exec/Command.java b/commons-lib/src/main/java/org/opencb/commons/exec/Command.java
index efcbf7f2f..dd9e7182e 100755
--- a/commons-lib/src/main/java/org/opencb/commons/exec/Command.java
+++ b/commons-lib/src/main/java/org/opencb/commons/exec/Command.java
@@ -20,6 +20,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -27,6 +28,10 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
import java.util.stream.Collectors;
public class Command extends RunnableProcess {
@@ -47,6 +52,10 @@ public class Command extends RunnableProcess {
private OutputStream outputOutputStream = null;
private OutputStream errorOutputStream = null;
+ private static final ExecutorService EXECUTOR_SERVICE = Executors.newCachedThreadPool(
+ new NamedThreadFactory("command")
+ .setDaemon(true));
+
private final String[] cmdArray;
private boolean printOutput = true;
@@ -73,8 +82,16 @@ public Command(String[] cmdArray, Map environment) {
this.environment = environment;
}
+ public Future async() {
+ return run(true);
+ }
+
@Override
public void run() {
+ run(false);
+ }
+
+ public Future run(boolean background) {
try {
startTime();
logger.debug(Commandline.describeCommand(cmdArray));
@@ -92,32 +109,19 @@ public void run() {
}
setStatus(Status.RUNNING);
- InputStream is = proc.getInputStream();
- // Thread out = readOutputStream(is);
- Thread readOutputStreamThread = readOutputStream(is);
- InputStream es = proc.getErrorStream();
- // Thread err = readErrorStream(es);
- Thread readErrorStreamThread = readErrorStream(es);
-
- proc.waitFor();
- readOutputStreamThread.join();
- readErrorStreamThread.join();
- endTime();
-
- setExitValue(proc.exitValue());
- if (proc.exitValue() != 0) {
- status = Status.ERROR;
- // output = IOUtils.toString(proc.getInputStream());
- // error = IOUtils.toString(proc.getErrorStream());
- output = outputBuffer.toString();
- error = errorBuffer.toString();
- }
- if (status != Status.KILLED && status != Status.TIMEOUT && status != Status.ERROR) {
- status = Status.DONE;
- // output = IOUtils.toString(proc.getInputStream());
- // error = IOUtils.toString(proc.getErrorStream());
- output = outputBuffer.toString();
- error = errorBuffer.toString();
+ InputStream stdout = proc.getInputStream();
+ Future> readOutputStreamThread = readOutputStream(stdout);
+ InputStream stderr = proc.getErrorStream();
+ Future> readErrorStreamThread = readErrorStream(stderr);
+
+ if (background) {
+ // Wait in the background
+ return EXECUTOR_SERVICE.submit(() -> {
+ waitFor(readOutputStreamThread, readErrorStreamThread);
+ return getStatus();
+ });
+ } else {
+ waitFor(readOutputStreamThread, readErrorStreamThread);
}
} catch (RuntimeException | IOException | InterruptedException e) {
@@ -129,67 +133,97 @@ public void run() {
exitValue = -1;
logger.error("Exception occurred while executing Command " + exception, e);
}
+ return null;
+ }
+
+ private void waitFor(Future> readOutputStreamThread, Future> readErrorStreamThread) throws InterruptedException {
+ proc.waitFor();
+ try {
+ readOutputStreamThread.get();
+ readErrorStreamThread.get();
+ } catch (ExecutionException e) {
+ throw new RuntimeException(e);
+ }
+ endTime();
+
+ setExitValue(proc.exitValue());
+ if (proc.exitValue() != 0) {
+ status = Status.ERROR;
+ // output = IOUtils.toString(proc.getInputStream());
+ // error = IOUtils.toString(proc.getErrorStream());
+ output = outputBuffer.toString();
+ error = errorBuffer.toString();
+ }
+ if (status != Status.KILLED && status != Status.TIMEOUT && status != Status.ERROR) {
+ status = Status.DONE;
+ // output = IOUtils.toString(proc.getInputStream());
+ // error = IOUtils.toString(proc.getErrorStream());
+ output = outputBuffer.toString();
+ error = errorBuffer.toString();
+ }
}
@Override
public void destroy() {
- if (proc != null) {
+ if (proc != null && proc.isAlive()) {
proc.destroy();
setStatus(Status.KILLED);
}
}
- private Thread readOutputStream(InputStream ins) throws IOException {
+ private Future> readOutputStream(InputStream ins) throws IOException {
return readStream("stdout", outputOutputStream, outputBuffer, ins);
}
- private Thread readErrorStream(InputStream ins) throws IOException {
+ private Future> readErrorStream(InputStream ins) throws IOException {
return readStream("stderr", errorOutputStream, errorBuffer, ins);
}
- private Thread readStream(String outputName, OutputStream outputStream, StringBuffer stringBuffer, InputStream in) {
- Thread thread = new Thread(() -> {
+ private Future> readStream(String outputName, OutputStream outputStream, StringBuffer stringBuffer, InputStream in) {
+ return EXECUTOR_SERVICE.submit(() -> {
try {
- int bytesRead = 0;
- int bufferLength;
- byte[] buffer;
+ int bytesRead = 0;
+ int bufferLength;
+ byte[] buffer;
- while (bytesRead != -1) {
- // int x=in.available();
- // if (x<=0)
- // continue ;
+ while (bytesRead != -1) {
+ // int x=in.available();
+ // if (x<=0)
+ // continue ;
- bufferLength = in.available();
- bufferLength = Math.max(bufferLength, 1);
+ bufferLength = in.available();
+ bufferLength = Math.max(bufferLength, 1);
- buffer = new byte[bufferLength];
- bytesRead = in.read(buffer, 0, bufferLength);
+ buffer = new byte[bufferLength];
+ bytesRead = in.read(buffer, 0, bufferLength);
- if (bytesRead == 0) {
- Thread.sleep(500);
+ if (bytesRead == 0) {
+ Thread.sleep(500);
+ if (logger.isTraceEnabled()) {
logger.trace(outputName + " - Sleep");
- } else if (bytesRead > 0) {
+ }
+ } else if (bytesRead > 0) {
+ if (logger.isTraceEnabled()) {
logger.trace(outputName + " - last bytesRead = {})", bytesRead);
- if (printOutput) {
- System.err.print(new String(buffer));
- }
-
- if (outputStream == null) {
- stringBuffer.append(new String(buffer));
- } else {
- outputStream.write(buffer);
- outputStream.flush();
- }
+ }
+ if (printOutput) {
+ System.err.print(new String(buffer));
+ }
+
+ if (outputStream == null) {
+ stringBuffer.append(new String(buffer));
+ } else {
+ outputStream.write(buffer);
+ outputStream.flush();
}
}
- logger.debug("Read {} - Exit while", outputName);
- } catch (Exception ex) {
- logger.error("Error reading " + outputName, ex);
- exception = ex.toString();
}
- }, outputName + "_reader");
- thread.start();
- return thread;
+ logger.debug("Read {} - Exit while", outputName);
+ } catch (Exception ex) {
+ logger.error("Error reading " + outputName, ex);
+ exception = ex.toString();
+ }
+ });
}
/**
@@ -275,4 +309,17 @@ public Command setPrintOutput(boolean printOutput) {
this.printOutput = printOutput;
return this;
}
+
+ public Process getProc() {
+ return proc;
+ }
+
+ public DataOutputStream getStdin() {
+ if (status == Status.RUNNING) {
+ return new DataOutputStream(proc.getOutputStream());
+ } else {
+ throw new IllegalStateException("Process is not running. Process status: " + status);
+ }
+ }
+
}
diff --git a/commons-lib/src/main/java/org/opencb/commons/exec/NamedThreadFactory.java b/commons-lib/src/main/java/org/opencb/commons/exec/NamedThreadFactory.java
new file mode 100644
index 000000000..fee4cb302
--- /dev/null
+++ b/commons-lib/src/main/java/org/opencb/commons/exec/NamedThreadFactory.java
@@ -0,0 +1,60 @@
+package org.opencb.commons.exec;
+
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class NamedThreadFactory implements ThreadFactory {
+
+ private static final AtomicInteger POOL_NUMBER = new AtomicInteger(1);
+ private final ThreadGroup group;
+ private final AtomicInteger threadNumber = new AtomicInteger(1);
+ private final String prefix;
+ private Integer priority;
+ private boolean daemon;
+
+ public NamedThreadFactory(String namePrefix) {
+ SecurityManager s = System.getSecurityManager();
+ group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
+ prefix = namePrefix + "-"
+ + POOL_NUMBER.getAndIncrement()
+ + "-thread-";
+ priority = Thread.NORM_PRIORITY;
+ daemon = false;
+ }
+
+ public NamedThreadFactory setPriority(Integer priority) {
+ this.priority = priority;
+ return this;
+ }
+
+ /**
+ * Marks this thread as either a {@linkplain #isDaemon daemon} thread
+ * or a user thread. The Java Virtual Machine exits when the only
+ * threads running are all daemon threads.
+ *
+ * @param daemon true to mark this thread as a daemon thread;
+ * @return this thread factory
+ */
+ public NamedThreadFactory setDaemon(boolean daemon) {
+ this.daemon = daemon;
+ return this;
+ }
+
+ public boolean isDaemon() {
+ return daemon;
+ }
+
+ @Override
+ public Thread newThread(Runnable r) {
+ Thread t = new Thread(group, r, prefix + threadNumber.getAndIncrement());
+
+ t.setDaemon(daemon);
+
+ if (priority != null) {
+ if (t.getPriority() != priority) {
+ t.setPriority(priority);
+ }
+ }
+ return t;
+ }
+}
diff --git a/commons-lib/src/main/java/org/opencb/commons/exec/RunnableProcess.java b/commons-lib/src/main/java/org/opencb/commons/exec/RunnableProcess.java
index 6897fad4a..0e19f6f30 100755
--- a/commons-lib/src/main/java/org/opencb/commons/exec/RunnableProcess.java
+++ b/commons-lib/src/main/java/org/opencb/commons/exec/RunnableProcess.java
@@ -28,7 +28,7 @@ public abstract class RunnableProcess implements Runnable {
protected String exception;
protected int exitValue;
- protected Status status;
+ protected Status status = Status.WAITING;
public enum Status {WAITING, RUNNING, DONE, ERROR, TIMEOUT, KILLED}
diff --git a/commons-lib/src/main/java/org/opencb/commons/exec/SingleProcess.java b/commons-lib/src/main/java/org/opencb/commons/exec/SingleProcess.java
index f5dc7073e..7a641f622 100755
--- a/commons-lib/src/main/java/org/opencb/commons/exec/SingleProcess.java
+++ b/commons-lib/src/main/java/org/opencb/commons/exec/SingleProcess.java
@@ -22,7 +22,7 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-
+@Deprecated
public class SingleProcess {
private Logger logger;
diff --git a/commons-lib/src/test/java/org/opencb/commons/exec/CommandTest.java b/commons-lib/src/test/java/org/opencb/commons/exec/CommandTest.java
new file mode 100644
index 000000000..d1b8fd718
--- /dev/null
+++ b/commons-lib/src/test/java/org/opencb/commons/exec/CommandTest.java
@@ -0,0 +1,35 @@
+package org.opencb.commons.exec;
+
+import org.junit.Test;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.Assert.assertEquals;
+
+public class CommandTest {
+
+
+ @Test
+ public void testCommand() throws Exception {
+ // Test the Command class
+// String commandLine = "bash -c 'echo Hello World ; echo Error Message >&2 ; cat -'";
+// String commandLine = "cat";
+ String commandLine = "bash -c 'cat <(echo -n \"Hello - \") - <(echo -n \" - END\")'";
+ Command command = new Command(commandLine);
+ command.setPrintOutput(false);
+
+ // Execute the command
+ Future future = command.async();
+ DataOutputStream stdin = command.getStdin();
+ stdin.write("World from STDIN".getBytes());
+ stdin.close();
+ future.get(1000, TimeUnit.MILLISECONDS);
+ assertEquals(RunnableProcess.Status.DONE, command.getStatus());
+ assertEquals("Hello - World from STDIN - END", command.getOutput());
+ assertEquals("", command.getError());
+ }
+
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index eb71ba272..0d49cb801 100644
--- a/pom.xml
+++ b/pom.xml
@@ -51,14 +51,6 @@
-
- ossrh
- https://oss.sonatype.org/content/repositories/snapshots
-
- true
- daily
-
-
github
https://maven.pkg.github.com/opencb
@@ -305,34 +297,62 @@
+
deploy-maven
+
ossrh
- https://oss.sonatype.org/service/local/staging/deploy/maven2/
+ OSSRH Staging API Releases
+ https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2/
+
+
ossrh
- https://oss.sonatype.org/content/repositories/snapshots
+ Central Portal Snapshots
+ https://central.sonatype.com/repository/maven-snapshots/
+
+
+ org.sonatype.central
+ central-publishing-maven-plugin
+ 0.8.0
+
+ true
+
+
+ ossrh
+
+ true
+
+ published
+
+ true
+
+
+
org.apache.maven.plugins
maven-source-plugin
- 3.2.0
+ 3.2.1
attach-sources
+
jar-no-fork
+
+
org.apache.maven.plugins
maven-javadoc-plugin
@@ -341,14 +361,20 @@
attach-javadocs
+
jar
+
none
+
+ false
+
+
org.apache.maven.plugins
maven-gpg-plugin
@@ -356,12 +382,13 @@
sign-artifacts
- deploy
+
+ verify
sign
-
+
--pinentry-mode
loopback
@@ -370,17 +397,6 @@
-
- org.sonatype.plugins
- nexus-staging-maven-plugin
- 1.6.8
- true
-
- ossrh
- https://oss.sonatype.org/
- true
-
-