Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:bigbluebutton/bigbluebutton into…
Browse files Browse the repository at this point in the history
… merge-2.2-into-2.3-july-6
  • Loading branch information
antobinary committed Jul 7, 2020
2 parents 526f79e + 4321b4c commit 420f8bf
Show file tree
Hide file tree
Showing 11 changed files with 285 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,33 @@
package org.bigbluebutton.presentation.imp;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import com.sun.org.apache.xerces.internal.impl.xs.opti.DefaultDocument;
import org.apache.commons.io.FilenameUtils;
import org.bigbluebutton.presentation.UploadedPresentation;
import org.jodconverter.core.document.DefaultDocumentFormatRegistry;
import org.jodconverter.core.document.DocumentFormat;
import org.jodconverter.core.job.AbstractConverter;
import org.jodconverter.local.LocalConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;

public class Office2PdfPageConverter {
public abstract class Office2PdfPageConverter {
private static Logger log = LoggerFactory.getLogger(Office2PdfPageConverter.class);

public boolean convert(File presentationFile, File output, int page, UploadedPresentation pres,
final LocalConverter converter){
public static boolean convert(File presentationFile, File output, int page, UploadedPresentation pres,
LocalConverter converter){

FileInputStream inputStream = null;
FileOutputStream outputStream = null;

try {
Map<String, Object> logData = new HashMap<>();
logData.put("meetingId", pres.getMeetingId());
Expand All @@ -46,7 +58,15 @@ public boolean convert(File presentationFile, File output, int page, UploadedPre
String logStr = gson.toJson(logData);
log.info(" --analytics-- data={}", logStr);

converter.convert(presentationFile).to(output).execute();
final DocumentFormat sourceFormat = DefaultDocumentFormatRegistry.getFormatByExtension(
FilenameUtils.getExtension(presentationFile.getName()));

inputStream = new FileInputStream(presentationFile);
outputStream = new FileOutputStream(output);

converter.convert(inputStream).as(sourceFormat).to(outputStream).as(DefaultDocumentFormatRegistry.PDF).execute();
outputStream.flush();

if (output.exists()) {
return true;
} else {
Expand Down Expand Up @@ -74,6 +94,22 @@ public boolean convert(File presentationFile, File output, int page, UploadedPre
String logStr = gson.toJson(logData);
log.error(" --analytics-- data={}", logStr, e);
return false;
} finally {
if(inputStream!=null) {
try {
inputStream.close();
} catch(Exception e) {

}
}

if(outputStream!=null) {
try {
outputStream.close();
} catch(Exception e) {

}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,18 @@
package org.bigbluebutton.presentation.imp;

import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.bigbluebutton.presentation.ConversionMessageConstants;
import org.bigbluebutton.presentation.SupportedFileTypes;
import org.bigbluebutton.presentation.UploadedPresentation;
import org.jodconverter.core.office.OfficeException;
import org.jodconverter.core.office.OfficeManager;
import org.jodconverter.core.office.OfficeUtils;
import org.jodconverter.local.LocalConverter;
import org.jodconverter.local.office.LocalOfficeManager;
import org.jodconverter.local.office.ExternalOfficeManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -39,20 +41,12 @@ public class OfficeToPdfConversionService {
private static Logger log = LoggerFactory.getLogger(OfficeToPdfConversionService.class);

private OfficeDocumentValidator2 officeDocumentValidator;
private final OfficeManager officeManager;
private final LocalConverter documentConverter;
private final ArrayList<ExternalOfficeManager> officeManagers;
private ExternalOfficeManager currentManager = null;
private boolean skipOfficePrecheck = false;

public OfficeToPdfConversionService() throws OfficeException {
officeManager = LocalOfficeManager
.builder()
.portNumbers(8100, 8101, 8102, 8103, 8104)
.build();
documentConverter = LocalConverter
.builder()
.officeManager(officeManager)
.filterChain(new OfficeDocumentConversionFilter())
.build();
officeManagers = new ArrayList<>();
}

/*
Expand Down Expand Up @@ -121,8 +115,39 @@ private File setupOutputPdfFile(UploadedPresentation pres) {

private boolean convertOfficeDocToPdf(UploadedPresentation pres,
File pdfOutput) {
Office2PdfPageConverter converter = new Office2PdfPageConverter();
return converter.convert(pres.getUploadedFile(), pdfOutput, 0, pres, documentConverter);
boolean success = false;
int attempts = 0;

while(!success) {
LocalConverter documentConverter = LocalConverter
.builder()
.officeManager(currentManager)
.filterChain(new OfficeDocumentConversionFilter())
.build();

success = Office2PdfPageConverter.convert(pres.getUploadedFile(), pdfOutput, 0, pres, documentConverter);

if(!success) {
// In case of failure, try with other open Office Manager

if(++attempts != officeManagers.size()) {
// Go to next Office Manager ( if the last retry with the first one )
int currentManagerIndex = officeManagers.indexOf(currentManager);

boolean isLastManager = ( currentManagerIndex == officeManagers.size()-1 );
if(isLastManager) {
currentManager = officeManagers.get(0);
} else {
currentManager = officeManagers.get(currentManagerIndex+1);
}
} else {
// We tried to use all our office managers and it's still failing
break;
}
}
}

return success;
}

private void makePdfTheUploadedFileAndSetStepAsSuccess(UploadedPresentation pres, File pdf) {
Expand All @@ -139,19 +164,41 @@ public void setSkipOfficePrecheck(boolean skipOfficePrecheck) {
}

public void start() {
try {
officeManager.start();
} catch (OfficeException e) {
log.error("Could not start Office Manager", e);
for(int managerIndex = 0; managerIndex < 4; managerIndex ++) {
Integer instanceNumber = managerIndex + 1; // starts at 1

try {
final File workingDir = new File("/var/tmp/soffice_0" +instanceNumber);
ExternalOfficeManager officeManager = ExternalOfficeManager
.builder()
.connectTimeout(2000L)
.retryInterval(500L)
.portNumber(8200 + instanceNumber)
.connectOnStart(false) // If it's true and soffice is not available, exception is thrown here ( we don't want exception here - we want the manager alive trying to reconnect )
.workingDir(workingDir)
.build();

// Workaround for jodconverter not calling makeTempDir when connectOnStart=false (issue 211)
Method method = officeManager.getClass().getSuperclass().getDeclaredMethod("makeTempDir");
method.setAccessible(true);
method.invoke(officeManager);
// End of workaround for jodconverter not calling makeTempDir

officeManager.start();
officeManagers.add(officeManager);
} catch (Exception e) {
log.error("Could not start Office Manager " + instanceNumber + ". Details: " + e.getMessage());
}

currentManager = officeManagers.get(0);
}
}

public void stop() {
try {
officeManager.stop();
} catch (OfficeException e) {
officeManagers.forEach(officeManager -> officeManager.stop() );
} catch (Exception e) {
log.error("Could not stop Office Manager", e);
}

}
}
19 changes: 19 additions & 0 deletions bbb-libreoffice/assets/bbb-libreoffice.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[Unit]
Description=BigBlueButton Libre Office container
Requires=network.target

[Service]
Type=simple
WorkingDirectory=/tmp
ExecStart=/usr/share/bbb-libreoffice/libreoffice_container.sh INSTANCE_NUMBER
ExecStop=/usr/bin/docker kill bbb-libreoffice-INSTANCE_NUMBER
Restart=always
RestartSec=60
SuccessExitStatus=
TimeoutStopSec=30
PermissionsStartOnly=true
LimitNOFILE=1024

[Install]
WantedBy=multi-user.target

33 changes: 33 additions & 0 deletions bbb-libreoffice/assets/libreoffice_container.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/bin/bash
INSTANCE_NUMBER=$1

if [ -z "$INSTANCE_NUMBER" ]; then
INSTANCE_NUMBER=0
fi;

_kill() {
CHECK_CONTAINER=`docker inspect bbb-libreoffice-${INSTANCE_NUMBER} &> /dev/null && echo 1 || echo 0`
if [ "$CHECK_CONTAINER" = "1" ]; then
echo "Killing container"
docker kill bbb-libreoffice-${INSTANCE_NUMBER};
sleep 1
fi;
}

trap _kill SIGINT


if (($INSTANCE_NUMBER >= 1 && $INSTANCE_NUMBER <= 10)); then
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

_kill

docker run --name bbb-libreoffice-${INSTANCE_NUMBER} -p 82${INSTANCE_NUMBER}:8000 -v/var/tmp/soffice${INSTANCE_NUMBER}:/var/tmp/soffice${INSTANCE_NUMBER} --rm bbb-libreoffice &

wait $!
else
echo ;
echo "Invalid or missing parameter INSTANCE_NUMBER"
echo " Usage: $0 INSTANCE_NUMBER"
exit 1
fi;
26 changes: 26 additions & 0 deletions bbb-libreoffice/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
FROM openjdk:8-jre

ENV DEBIAN_FRONTEND noninteractive

RUN apt update

RUN addgroup --system --gid 996 libreoffice
RUN adduser --disabled-password --system --disabled-login --shell /sbin/nologin --gid 996 --uid 996 libreoffice

RUN apt -y install locales-all fontconfig libxt6 libxrender1
RUN apt -y install libreoffice --no-install-recommends

RUN dpkg-reconfigure fontconfig && fc-cache -f -s -v

RUN for i in `seq -w 1 10` ; do mkdir -m 777 /var/tmp/soffice${i}; done

VOLUME ["/usr/share/fonts/"]
RUN chown libreoffice /home/libreoffice/

ADD ./bbb-libreoffice-entrypoint.sh /home/libreoffice/
RUN chown -R libreoffice /home/libreoffice/
RUN chmod 700 /home/libreoffice/bbb-libreoffice-entrypoint.sh

USER libreoffice

ENTRYPOINT ["/home/libreoffice/bbb-libreoffice-entrypoint.sh" ]
7 changes: 7 additions & 0 deletions bbb-libreoffice/docker/bbb-libreoffice-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

## Initialize environment
/usr/lib/libreoffice/program/soffice.bin -env:UserInstallation="file:///tmp/"

## Run daemon
/usr/lib/libreoffice/program/soffice.bin --accept="socket,host=0.0.0.0,port=8000,tcpNoDelay=1;urp;StarOffice.ServiceManager" --headless --invisible --nocrashreport --nodefault --nofirststartwizard --nolockcheck --nologo --norestore -env:UserInstallation="file:///tmp/"
51 changes: 51 additions & 0 deletions bbb-libreoffice/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/bin/bash
if [ "$EUID" -ne 0 ]; then
echo "Please run this script as root ( or with sudo )" ;
exit 1;
fi;

DOCKER_CHECK=`docker --version &> /dev/null && echo 1 || echo 0`

if [ "$DOCKER_CHECK" = "0" ]; then
echo "Docker not found";
apt update;
apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
apt update
apt install docker-ce -y
systemctl enable docker
systemctl start docker
systemctl status docker
else
echo "Docker already installed";
fi


IMAGE_CHECK=`docker image inspect bbb-libreoffice &> /dev/null && echo 1 || echo 0`
if [ "$IMAGE_CHECK" = "0" ]; then
echo "Docker image doesn't exists, building"
docker build -t bbb-libreoffice docker/
else
echo "Docker image already exists";
fi

FOLDER_CHECK=`[ -d /usr/share/bbb-libreoffice/ ] && echo 1 || echo 0`
if [ "$FOLDER_CHECK" = "0" ]; then
echo "Install folder doesn't exists, installing"
mkdir -m 755 /usr/share/bbb-libreoffice/
cp assets/libreoffice_container.sh /usr/share/bbb-libreoffice/
chmod 700 /usr/share/bbb-libreoffice/libreoffice_container.sh
chown -R root /usr/share/bbb-libreoffice/

for i in `seq 1 4` ; do
cat assets/bbb-libreoffice.service | sed 's/INSTANCE_NUMBER/0'${i}'/g' > /lib/systemd/system/bbb-libreoffice-0${i}.service
systemctl daemon-reload
systemctl enable bbb-libreoffice-0${i}
systemctl start bbb-libreoffice-0${i}
done

else
echo "Install folder already exists"
fi;

29 changes: 29 additions & 0 deletions bbb-libreoffice/uninstall.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash
if [ "$EUID" -ne 0 ]; then
echo "Please run this script as root ( or with sudo )" ;
exit 1;
fi;

IMAGE_CHECK=`docker image inspect bbb-libreoffice 2>&1 > /dev/null && echo 1 || echo 0`
if [ "$IMAGE_CHECK" = "1" ]; then
echo "Stopping services"
systemctl --no-pager --no-legend --value --state=running | grep bbb-libreoffice | awk -F '.service' '{print $1}' | xargs -n 1 systemctl stop

echo "Removing image"
docker image rm bbb-libreoffice
fi


FOLDER_CHECK=`[ -d /usr/share/bbb-libreoffice/ ] && echo 1 || echo 0`
if [ "$FOLDER_CHECK" = "1" ]; then
echo "Stopping services"
systemctl --no-pager --no-legend --value --state=running | grep bbb-libreoffice | awk -F '.service' '{print $1}' | xargs -n 1 systemctl stop

echo "Removing install folder"
rm -rf /usr/share/bbb-libreoffice/

echo "Removing service definitions"
rm /lib/systemd/system/bbb-libreoffice-0*
find /etc/systemd/ | grep bbb-libreoffice | xargs --no-run-if-empty -n 1 -I __ rm __
systemctl daemon-reload
fi;
Loading

0 comments on commit 420f8bf

Please sign in to comment.