diff --git a/libreoffice/griffin b/libreoffice/griffin
index 603a84d..b96af17 100755
--- a/libreoffice/griffin
+++ b/libreoffice/griffin
@@ -1,3 +1,5 @@
#!/usr/bin/env bash
-java -Dfile.encoding=UTF-8 -jar /vitam/bin/worker/griffins/libreoffice-griffin/libreoffice-jar-with-dependencies.jar $1
\ No newline at end of file
+LIBREOFFICE_HOME=$(dirname $(dirname $(readlink -f $(which $(compgen -c | grep libreoffice | head -1)))))
+
+java -Doffice.home="$LIBREOFFICE_HOME" -Dfile.encoding=UTF-8 -jar /vitam/bin/worker/griffins/libreoffice-griffin/libreoffice-jar-with-dependencies.jar $1
\ No newline at end of file
diff --git a/libreoffice/libreoffice b/libreoffice/libreoffice
deleted file mode 100644
index 8b7af42..0000000
--- a/libreoffice/libreoffice
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env bash
-
-$(compgen -c | grep libreoffice | head -1) --accept="socket,host=127.0.0.1,port=2002,tcpNoDelay=1;urp;StarOffice.ServiceManager" --headless --invisible --nodefault --nofirststartwizard --nolockcheck --nologo --norestore
\ No newline at end of file
diff --git a/libreoffice/pom.xml b/libreoffice/pom.xml
index c658dee..dc4deae 100755
--- a/libreoffice/pom.xml
+++ b/libreoffice/pom.xml
@@ -99,28 +99,6 @@
/vitam/bin/worker/griffins/${unix.name}
-
- ${basedir}/libreoffice
- file
-
- perm
- ${unix.user}
- ${unix.group}
- 750
- /vitam/bin/worker/griffins/${unix.name}
-
-
-
- ${basedir}/soffice.service
- file
-
- perm
- ${unix.user}
- ${unix.group}
- 0755
- /lib/systemd/system
-
-
@@ -190,33 +168,12 @@
-
-
- /usr/lib/systemd/system/
- 644
- root
- root
- false
-
-
-
-
-
-
-
-
-
-
diff --git a/libreoffice/soffice.service b/libreoffice/soffice.service
deleted file mode 100644
index 5e4bc74..0000000
--- a/libreoffice/soffice.service
+++ /dev/null
@@ -1,13 +0,0 @@
-[Unit]
-Description=Control headless soffice instance
-After=network.target
-
-[Service]
-User=vitam
-Group=vitam
-Type=simple
-ExecStart=/vitam/bin/worker/griffins/libreoffice-griffin/libreoffice
-Restart=always
-
-[Install]
-WantedBy=multi-user.target
\ No newline at end of file
diff --git a/libreoffice/src/deb/control/postinst b/libreoffice/src/deb/control/postinst
deleted file mode 100755
index 609330f..0000000
--- a/libreoffice/src/deb/control/postinst
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-if [ -x /bin/systemctl ]; then
- systemctl daemon-reload
- systemctl enable soffice.service
- systemctl start soffice.service
-fi
\ No newline at end of file
diff --git a/libreoffice/src/deb/control/prerm b/libreoffice/src/deb/control/prerm
deleted file mode 100644
index 5c9664f..0000000
--- a/libreoffice/src/deb/control/prerm
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh
-
-if [ -x /bin/systemctl ]; then
- systemctl stop soffice.service
- systemctl disable soffice.service
-fi
\ No newline at end of file
diff --git a/libreoffice/src/main/java/fr/gouv/vitam/griffins/libreoffice/AutoClosableOfficeManager.java b/libreoffice/src/main/java/fr/gouv/vitam/griffins/libreoffice/AutoClosableOfficeManager.java
new file mode 100644
index 0000000..307463e
--- /dev/null
+++ b/libreoffice/src/main/java/fr/gouv/vitam/griffins/libreoffice/AutoClosableOfficeManager.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2015-2019)
+ *
+ * contact.vitam@culture.gouv.fr
+ *
+ * This software is a computer program whose purpose is to implement a digital archiving back-office system managing
+ * high volumetry securely and efficiently.
+ *
+ * This software is governed by the CeCILL 2.1 license under French law and abiding by the rules of distribution of free
+ * software. You can use, modify and/ or redistribute the software under the terms of the CeCILL 2.1 license as
+ * circulated by CEA, CNRS and INRIA at the following URL "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy, modify and redistribute granted by the license,
+ * users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the
+ * successive licensors have only limited liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated with loading, using, modifying and/or
+ * developing or reproducing the software by the user in light of its specific status of free software, that may mean
+ * that it is complicated to manipulate, and that also therefore means that it is reserved for developers and
+ * experienced professionals having in-depth computer knowledge. Users are therefore encouraged to load and test the
+ * software's suitability as regards their requirements in conditions enabling the security of their systems and/or data
+ * to be ensured and, more generally, to use and operate it in the same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had knowledge of the CeCILL 2.1 license and that you
+ * accept its terms.
+ */
+package fr.gouv.vitam.griffins.libreoffice;
+
+import org.jodconverter.office.LocalOfficeManager;
+import org.jodconverter.office.OfficeException;
+import org.jodconverter.office.OfficeManager;
+import org.jodconverter.task.OfficeTask;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.nio.file.FileAlreadyExistsException;
+import java.nio.file.Files;
+import java.nio.file.OpenOption;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class AutoClosableOfficeManager implements AutoCloseable, OfficeManager {
+
+ private final OfficeManager manager;
+
+ public AutoClosableOfficeManager(int libreOffice) throws IOException {
+ this.manager = LocalOfficeManager.builder()
+ .portNumbers(libreOffice)
+ .workingDir(Files.createTempDirectory("griffin-libreoffice-").toFile())
+ .install()
+ .build();
+ }
+
+ @Override
+ public void close() throws Exception {
+ this.stop();
+ }
+
+ @Override
+ public void execute(OfficeTask task) throws OfficeException {
+ manager.execute(task);
+ }
+
+ @Override
+ public boolean isRunning() {
+ return manager.isRunning();
+ }
+
+ @Override
+ public void start() throws OfficeException {
+ manager.start();
+ }
+
+ @Override
+ public void stop() throws OfficeException {
+ manager.stop();
+ }
+}
diff --git a/libreoffice/src/main/java/fr/gouv/vitam/griffins/libreoffice/BatchProcessor.java b/libreoffice/src/main/java/fr/gouv/vitam/griffins/libreoffice/BatchProcessor.java
index 52f9686..53343fd 100755
--- a/libreoffice/src/main/java/fr/gouv/vitam/griffins/libreoffice/BatchProcessor.java
+++ b/libreoffice/src/main/java/fr/gouv/vitam/griffins/libreoffice/BatchProcessor.java
@@ -35,8 +35,6 @@
import fr.gouv.vitam.griffins.libreoffice.pojo.Result;
import fr.gouv.vitam.griffins.libreoffice.status.GriffinStatus;
import org.jodconverter.LocalConverter;
-import org.jodconverter.office.ExternalOfficeManagerBuilder;
-import org.jodconverter.office.OfficeException;
import org.jodconverter.office.OfficeManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -65,7 +63,6 @@ public class BatchProcessor {
public static final String parametersFileName = "parameters.json";
public static final String resultFileName = "result.json";
public static final String inputFilesDirName = "input-files";
-
private static final String FILTER_DATA = "FilterData";
private static final String FILTER_NAME = "FilterName";
private static final String FILTER_OPTIONS = "FilterOptions";
@@ -83,9 +80,9 @@ public BatchStatus execute() {
long startTime = System.currentTimeMillis();
String batchProcessingId = batchDirectory.getFileName().toString();
- OfficeManager officeManager = new ExternalOfficeManagerBuilder().build();
+ try (PortReserver portReserver = new PortReserver();
+ AutoClosableOfficeManager officeManager = new AutoClosableOfficeManager(portReserver.getLibreOfficePort())) {
- try {
File file = batchDirectory.resolve(parametersFileName).toFile();
parameters = mapper.readValue(file, Parameters.class);
@@ -112,8 +109,6 @@ public BatchStatus execute() {
} catch (Exception e) {
logger.error("{}", e);
return BatchStatus.error(batchProcessingId, startTime, e);
- } finally {
- stopOfficeManager(officeManager);
}
}
@@ -215,12 +210,4 @@ private boolean isInteger(String value) {
return false;
}
}
-
- private void stopOfficeManager(OfficeManager manager) {
- try {
- manager.stop();
- } catch (OfficeException ex) {
- logger.error("{}", ex);
- }
- }
}
diff --git a/libreoffice/src/main/java/fr/gouv/vitam/griffins/libreoffice/PortReserver.java b/libreoffice/src/main/java/fr/gouv/vitam/griffins/libreoffice/PortReserver.java
new file mode 100644
index 0000000..fdd3c76
--- /dev/null
+++ b/libreoffice/src/main/java/fr/gouv/vitam/griffins/libreoffice/PortReserver.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2015-2019)
+ *
+ * contact.vitam@culture.gouv.fr
+ *
+ * This software is a computer program whose purpose is to implement a digital archiving back-office system managing
+ * high volumetry securely and efficiently.
+ *
+ * This software is governed by the CeCILL 2.1 license under French law and abiding by the rules of distribution of free
+ * software. You can use, modify and/ or redistribute the software under the terms of the CeCILL 2.1 license as
+ * circulated by CEA, CNRS and INRIA at the following URL "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy, modify and redistribute granted by the license,
+ * users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the
+ * successive licensors have only limited liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated with loading, using, modifying and/or
+ * developing or reproducing the software by the user in light of its specific status of free software, that may mean
+ * that it is complicated to manipulate, and that also therefore means that it is reserved for developers and
+ * experienced professionals having in-depth computer knowledge. Users are therefore encouraged to load and test the
+ * software's suitability as regards their requirements in conditions enabling the security of their systems and/or data
+ * to be ensured and, more generally, to use and operate it in the same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had knowledge of the CeCILL 2.1 license and that you
+ * accept its terms.
+ */
+package fr.gouv.vitam.griffins.libreoffice;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.nio.file.FileAlreadyExistsException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class PortReserver implements AutoCloseable {
+ private static final Logger LOGGER = LoggerFactory.getLogger(PortReserver.class);
+ private static final Path LOCK_DIRECTORY = Paths.get(System.getProperty("java.io.tmpdir"), "griffin-libre-office-locks");
+ private static final int MAX_ATTEMPT_NUMBER = 4;
+
+ private final int libreOfficePort;
+
+ public PortReserver() throws IOException {
+ createLockDirectory();
+ this.libreOfficePort = findAvailablePort(MAX_ATTEMPT_NUMBER);
+ }
+
+ private void createLockDirectory() throws IOException {
+ if (Files.notExists(LOCK_DIRECTORY)) {
+ try {
+ Files.createDirectory(LOCK_DIRECTORY);
+ } catch (FileAlreadyExistsException e) {
+ LOGGER.info("ignore error {}", e);
+ }
+ }
+ }
+
+ private int findAvailablePort(int numberOfAttempt) throws IOException {
+ try (ServerSocket socket = new ServerSocket(0, 1, InetAddress.getLocalHost())) {
+ int localPort = socket.getLocalPort();
+ Files.createFile(LOCK_DIRECTORY.resolve(String.format("%d.lock", localPort)));
+ return localPort;
+ } catch (FileAlreadyExistsException e) {
+ LOGGER.warn("{}", e);
+
+ if (numberOfAttempt > MAX_ATTEMPT_NUMBER) {
+ throw new RuntimeException("Reach max retries for find available port and yet there is still:", e);
+ }
+
+ return findAvailablePort(numberOfAttempt + 1);
+ }
+ }
+
+ @Override
+ public void close() throws Exception {
+ Files.delete(LOCK_DIRECTORY.resolve(String.format("%d.lock", this.libreOfficePort)));
+ }
+
+ public int getLibreOfficePort() {
+ return libreOfficePort;
+ }
+}
diff --git a/libreoffice/src/test/java/fr/gouv/vitam/griffins/libreoffice/MainTest.java b/libreoffice/src/test/java/fr/gouv/vitam/griffins/libreoffice/MainTest.java
index daa3d98..784c09b 100755
--- a/libreoffice/src/test/java/fr/gouv/vitam/griffins/libreoffice/MainTest.java
+++ b/libreoffice/src/test/java/fr/gouv/vitam/griffins/libreoffice/MainTest.java
@@ -35,10 +35,6 @@
import fr.gouv.vitam.griffins.libreoffice.pojo.Result;
import fr.gouv.vitam.griffins.libreoffice.pojo.Values;
import fr.gouv.vitam.griffins.libreoffice.status.GriffinStatus;
-import org.jodconverter.office.LocalOfficeManager;
-import org.jodconverter.office.OfficeException;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@@ -78,19 +74,6 @@ public class MainTest {
@Rule
public TemporaryFolder tmpGriffinFolder = new TemporaryFolder();
- private static LocalOfficeManager officeManager;
-
- @BeforeClass
- public static void setup() throws OfficeException {
- officeManager = LocalOfficeManager.install();
- officeManager.start();
- }
-
- @AfterClass
- public static void clean() throws OfficeException {
- officeManager.stop();
- }
-
@Test
public void should_GENERATE_DOC_file_from_odt() {
// Given
@@ -174,13 +157,14 @@ public void should_GENERATE_for_multiple_instance() {
assertThat(actual).hasSize(4);
assertThat(actual).extracting(Output::getAction).allMatch(a -> a.equals(GENERATE));
assertThat(actual).extracting(Output::getStatus).allMatch(s -> s.equals(OK));
- assertThat(actual).extracting(Output::getOutputName).containsExactlyElementsOf(names.stream().map(s -> String.format("%s.pdf", s)).collect(Collectors.toList()));
+ assertThat(actual).extracting(Output::getOutputName)
+ .containsExactlyElementsOf(names.stream().map(s -> String.format("%s.pdf", s)).collect(Collectors.toList()));
}
@Test
public void should_GENERATE_for_big_number_of_file() {
String sourceName = "test.odt";
- List names = IntStream.range(0, 400)
+ List names = IntStream.range(0, 30)
.mapToObj(i -> String.format("%d_%s", i, sourceName))
.collect(Collectors.toList());
@@ -207,7 +191,7 @@ public void should_GENERATE_for_big_number_of_file() {
// Then
assertThat(actual).extracting(Output::getAction).allMatch(a -> a.equals(GENERATE));
assertThat(actual).extracting(Output::getStatus).allMatch(s -> s.equals(OK));
- assertThat(actual).hasSize(400);
+ assertThat(actual).hasSize(names.size());
}
@Test
@@ -336,7 +320,8 @@ private Parameters generateBatch(Action action, Input input, String sourceName)
parameters.setActions(Collections.singletonList(action));
parameters.setInputs(Collections.singletonList(input));
- FileAttribute> setFileAttribute = PosixFilePermissions.asFileAttribute(Files.getPosixFilePermissions(batchFolder, NOFOLLOW_LINKS));
+ FileAttribute> setFileAttribute =
+ PosixFilePermissions.asFileAttribute(Files.getPosixFilePermissions(batchFolder, NOFOLLOW_LINKS));
File parametersFile = Files.createFile(Paths.get(batchFolder.toString(), parametersFileName), setFileAttribute).toFile();
objectMapper.writer().writeValue(parametersFile, parameters);