— A model of High Scalable Architecture for an #[EDM,GED,DMS] www service to "PDFed" any documents: [DOC,XLS,PPT,ODT,ODT,TXT,RTF]2PDF —


high availability architecture

- Never stopdown, production load ready, hot deployment -

#VisualParadigm #UML@1999 #Java #JBoss #Jetty #Tomcat #JODConverter #JODRepport #OpenOffice #LibreOffice #iText2 #jOpenDocument #Sigar #Office2Fo #Xdocreport #DevOps.

Milestones

A J2EE comparo.

$ java -version
java version "1.7.0_65-BLFS"
OpenJDK Runtime Environment (IcedTea 2.5.) (linux-gnu build 1.7.0_65)
OpenJDK 64-Bit Server VM (build 24.65-b04, mixed mode)
 
$ /usr/local/jboss/bin/standalone.sh -b 192.168.56.103
INFO [org.jboss.as] JBoss AS 7.1.2.Final-redhat started in 12900ms
INFO [fr.data31tech...Convert] success : ods [82270b] to pdf in 1907ms

$ java -version
java version "1.8.0_112-ea"
Java(TM) SE Runtime Environment (build 1.8.0_112-ea-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b02, mixed mode)
 
/usr/local/jetty/bin/jetty.sh start
2016-12-02 12:41:28.373:INFO:oejs.Server:main: Started @6439ms
Dec 02, 2016 12:42:28 PM fr.data31tech.gedsrv.Convert doPost
INFO: successful conversion: ods [82270b] to pdf in 2345ms
$ /usr/lib/jvm/default-java/bin/java -version
openjdk version "1.8.0_111"
OpenJDK Runtime Environment (build 1.8.0_111-8u111-b14-2ubuntu0.16.04.2-b14)
OpenJDK 64-Bit Server VM (build 25.111-b14, mixed mode)
$ sudo /etc/init.d/tomcat7 restart
ok ] Restarting tomcat7 (via systemctl): tomcat7.service.
192.168.56.1 - - [05/Dec/2016:13:05:51 +0100] "POST /gedsrv/converted/document.pdf HTTP/1.1" 200 182505
Dec 05, 2016 12:53:59 PM fr.data31tech.gedsrv.converter.ConverterServlet doPost
INFO: successful conversion: ods [82270b] to pdf in 1991ms
 
$ ll /var/lib/tomcat7/conf/*.xml
total 220
drwxr-xr-x   4 root root      4096 Dec  5 12:40 ./
drwxr-xr-x 135 root root     12288 Dec  5 13:19 ../
-rw-r--r--   1 root tomcat7   1394 Jan 25  2014 context.xml
-rw-r--r--   1 root tomcat7   6678 Jun 27 21:48 server.xml
-rw-r-----   1 root tomcat7   1764 Dec  5 12:40 tomcat-users.xml
-rw-r--r--   1 root tomcat7 168099 Nov 25  2015 web.xml
 
sudo cat /etc/passwd
tomcat7:x:106:113::/usr/share/tomcat7:/bin/false

A test webapp : graphisme 0.2.


An oldschool basic java implementation : HttpServlet.

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
  WebappContext webappContext = WebappContext.get(getServletContext());
  OfficeDocumentConverter converter = webappContext.getDocumentConverter();
  DocumentFormatRegistry registry = converter.getFormatRegistry();
 
  String inputMimeType = request.getContentType();
  if (inputMimeType == null)
  {
    throw new IllegalArgumentException("Content-Type not set in request");
  }
  DocumentFormat inputFormat = registry.getFormatByMediaType(inputMimeType);
  if (inputFormat == null)
  {
    throw new IllegalArgumentException("Unsupported input mime-type: " + inputMimeType);
  }
  String outputMimeType = request.getHeader("Accept");
  if (outputMimeType == null)
  {
    throw new IllegalArgumentException("Accept header not set in request");
  }
  DocumentFormat outputFormat = registry.getFormatByMediaType(outputMimeType);
  if (outputFormat == null)
  {
    throw new IllegalArgumentException("Unsupported output mime-type: " + outputMimeType);
  }
 
  response.setContentType(outputFormat.getMediaType());
  // response.setContentLength(???); - should cache result in a buffer first
  try
  {
    long startTime = System.currentTimeMillis();
    converter.convert(request.getInputStream(), inputFormat, response.getOutputStream(), outputFormat);
    long conversionTime = System.currentTimeMillis() - startTime;
    logger.info(String.format("Successful conversion: [%s] -> [%s] in [%d]ms", inputFormat, outputFormat, conversionTime));
    }
  catch (Exception exception)
  {
    throw new ServletException("Conversion failed", exception);
  }
}

A newschool implementation : CXF on JBoss.

09:30:27,514 INFO  [org.jboss.wsf.stack.cxf.metadata.MetadataBuilder] (MSC service thread 1-1) Add Service
 id=fr.data31tech.gedsrv.converter.services.ConverterWS
 address=http://192.168.56.103:8080/gedsrv/ConverterWS
 implementor=fr.data31tech.gedsrv.converter.services.ConverterWS
 invoker=org.jboss.wsf.stack.cxf.JBossWSInvoker
 serviceName={http://services.converter.gedsrv.data31tech.fr/}ConverterWSService
 portName={http://services.converter.gedsrv.data31tech.fr/}ConverterWSPort
 wsdlLocation=null
 mtomEnabled=false

The excellent JODConverter (a kind of OpenOffice Memory LeaK workaround).

$ netstat | grep "200."
[sudo] password for hduser:
tcp        0      0 127.0.0.1:2002          0.0.0.0:*               LISTEN      8270/soffice.bin
tcp        0      0 127.0.0.1:2003          0.0.0.0:*               LISTEN      8293/soffice.bin
$ kill -9 8270 8293

WARNING [org.artofsolving.jodconverter.office.PooledOfficeManager] (MessageDispatcher) connection lost unexpectedly; attempting restart
WARNING [org.artofsolving.jodconverter.office.PooledOfficeManager] (MessageDispatcher) connection lost unexpectedly; attempting restart
INFO [org.artofsolving.jodconverter.office.ManagedOfficeProcess] (OfficeProcessThread-0) process exited with code 137
INFO [org.artofsolving.jodconverter.office.ManagedOfficeProcess] (OfficeProcessThread-1) process exited with code 137
INFO [org.artofsolving.jodconverter.office.OfficeProcess] (OfficeProcessThread-0) starting process acceptString 'socket,host=127.0.0.1,port=2002'
INFO [org.artofsolving.jodconverter.office.OfficeProcess] (OfficeProcessThread-1) starting process acceptString 'socket,host=127.0.0.1,port=2003'
INFO [org.artofsolving.jodconverter.office.OfficeProcess] (OfficeProcessThread-0) started process; pid = 9586
INFO [org.artofsolving.jodconverter.office.OfficeProcess] (OfficeProcessThread-1) started process; pid = 9588

$ netstat | grep "200."
tcp        0      0 127.0.0.1:2002          0.0.0.0:*               LISTEN      9586/soffice.bin
tcp        0      0 127.0.0.1:2003          0.0.0.0:*               LISTEN      9588/soffice.bin
$

Sigar, a low level java lib to manage the OS.

Chalengers : Office2Fo-1.0b2, Xdocreport, jOpenDocument, iText2...

$ java -cp .:./jOpenDocument-1.3.jar:./iText-2.1.5.jar Convert ./myComplexFile.ods ./myComplexFile.ods.pdf
Convert ./myComplexFile.ods
SaxContentUnmarshaller.log() Thu Dec 01 09:24:34 CET 2016
content.xml : ignoring :office:document-content current:null
...
Failed on x:1 y:0 Cell:Cell: style:null TestP:[TextP:[  ]]
java.lang.IllegalArgumentException: Font size too small: 0.0
at com.lowagie.text.pdf.PdfContentByte.setFontAndSize(Unknown Source)
at com.lowagie.text.pdf.PdfGraphics2D.drawString(Unknown Source)
at com.lowagie.text.pdf.PdfGraphics2D.drawString(Unknown Source)
at org.jopendocument.renderer.ODTCellTextLine.draw(Unknown Source)
at org.jopendocument.renderer.ODTCellText.draw(Unknown Source)
at org.jopendocument.renderer.ODTCellTextRenderer.draw(Unknown Source)
at org.jopendocument.renderer.ODTRenderer.drawCells(Unknown Source)
at org.jopendocument.renderer.ODTRenderer.drawODTText(Unknown Source)
at org.jopendocument.renderer.ODTRenderer.paintComponent(Unknown Source)
at Convert.main(Convert.java:56)

TODOs

Cloud4? : http://www.conv2pdf.com/, http://www.conv2pdf.com/, http://www.zamzar.com/, http://porting.openoffice.org/.

The excellent JODRepport.