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 - -