Maximo

Maximo

Come for answers, stay for best practices. All we're missing is you.

 View Only
Expand all | Collapse all

Server-side printing for reports on Maximo Application Suite

  • 1.  Server-side printing for reports on Maximo Application Suite

    Posted Mon August 28, 2023 11:45 PM

    Does server-side printing for reports work on Maximo Application Suite?

    I'm wondering if the IBM URL for version 7.6 will be compatible with the new version MAS.

    Please advise.

    Server-side printing for reports

    Ibm remove preview
    Server-side printing for reports
    You print reports from a machine where the Java™ virtual machine (JVM) application server is running. By using server-side printing, you have more options for customizing how and when the report is printed.
    View this on Ibm >

     



    ------------------------------
    [Srikanth][Narala]
    [Maximo Specialist]
    [Melbourne]
    [Australia]
    ------------------------------


  • 2.  RE: Server-side printing for reports on Maximo Application Suite

    Posted Tue August 29, 2023 08:20 AM

    I would recommend opening a support case to get an answer. I initially wanted to say no because the docs mentioned a dependency on Adobe Reader (which you wouldn't be able to install in OpenShift) but I'm not sure if that's really required anymore looking at some of the code changes made this year.

    For what it's worth, I've never looked at what it takes to configure a printer in OpenShift. That might be its own challenge since it's not the kind of activity normally done through a container. 



    ------------------------------
    Steven Shull
    ------------------------------



  • 3.  RE: Server-side printing for reports on Maximo Application Suite

    Posted Mon September 04, 2023 01:08 PM

    Steven, if I may ask. Leaving aside Adobe for now. How is server side printing done on the Liberty server (Linux) setup of Maximo? If it is done using CUPS then the same is likely possible through OpenShift. I suspect it may require some IBM development efforts to get it going with MAS. There's a container image available for CUPS via Red Hat. I do not know enough about Adobe Reader running on containers.



    ------------------------------
    Arif Ali
    ------------------------------



  • 4.  RE: Server-side printing for reports on Maximo Application Suite

    Posted Tue February 13, 2024 01:08 AM

    Apologies for the delay in responding to you. I have raised the issue with IBM, and their response indicates that MAS doesn't support Server Side Printing.



    ------------------------------
    [Srikanth][Narala]
    [Maximo Specialist]
    [Melbourne]
    [Australia]
    ------------------------------



  • 5.  RE: Server-side printing for reports on Maximo Application Suite

    Posted Wed August 30, 2023 01:38 PM

    When I looked at the IBM Documentation site to compare what you provided in your link, I can see no direct documented capability the same as 7.6.x.

    https://www.ibm.com/docs/en/maximo-manage/continuous-delivery?topic=users-printing-documents



    ------------------------------
    Bradley K. Downing , MBA
    Senior Brand Technical Specialist
    IBM
    Bakersfield CA
    ------------------------------



  • 6.  RE: Server-side printing for reports on Maximo Application Suite

    Posted Fri September 01, 2023 03:07 AM

    I'm pretty sure that server side printing is not doable at all with OpenShift. The architecture of this platform simply excludes using hardware such as printers.



    ------------------------------
    Witold Wierzchowski
    ------------------------------



  • 7.  RE: Server-side printing for reports on Maximo Application Suite
    Best Answer

    Posted Tue September 05, 2023 01:24 PM

    Srikanth,

    Here is an automation script that does what you are asking with MAS and CUPS.  I tested this with MAS 8.10 and CUPS 2.4.2.  

    It dynamically downloads the necessary cups4j client and dependencies from the maven repo and then generates the report and prints the results.  As mentioned there is a really easy to use CUPS image you can deploy found here https://hub.docker.com/r/olbat/cupsd

    That is what I used to test with my local printer.

    I have embedded the code below, but I think the email version mangles it, so you will want to view it in a web browser.

    If you have any questions please reach out.

    ByteArrayType = Java.type("byte[]");
    IntType = Java.type("int");
    StringType = Java.type("java.lang.String");
    Thread = Java.type("java.lang.Thread");
    
    File = Java.type("java.io.File");
    FileInputStream = Java.type("java.io.FileInputStream");
    FileOutputStream = Java.type("java.io.FileOutputStream");
    InputStream = Java.type("java.io.InputStream");
    
    URLClassLoader = Java.type("java.net.URLClassLoader");
    
    HostnameVerifier = Java.type("javax.net.ssl.HostnameVerifier");
    HttpsURLConnection = Java.type("javax.net.ssl.HttpsURLConnection");
    SSLContext = Java.type("javax.net.ssl.SSLContext");
    TrustManagerArrayType = Java.type("javax.net.ssl.TrustManager[]");
    X509ExtendedTrustManager = Java.type("javax.net.ssl.X509ExtendedTrustManager");
    URL = Java.type("java.net.URL");
    URLArrayType = Java.type("java.net.URL[]");
    
    SecureRandom = Java.type("java.security.SecureRandom");
    
    ReportParameterData = Java.type("com.ibm.tivoli.maximo.report.birt.runtime.ReportParameterData");
    ReportAdminServiceRemote = Java.type("com.ibm.tivoli.maximo.report.birt.admin.ReportAdminServiceRemote");
    
    MXServer = Java.type("psdi.server.MXServer");
    
    // Temporary path where the downloaded Jar files will be stored.
    JAR_PATH = "/var/tmp" + File.separator;
    
    // The server IP or host name for the CUPS server
    CUPS_ADDRESS = "x.x.x.x";
    
    // The port for the CUPS server, the default is 631
    CUPS_PORT = 631;
    
    // The name of the printer registered with the CUPS server.
    CUPS_PRINT_NAME = "YOUR_PRINTER_NAME";
    
    // X509ExtendedTrustManager that trusts all certificates.
    TrustAllManager = Java.extend(X509ExtendedTrustManager, {
        "getAcceptedIssuers": function () {
            return null;
        },
        "checkClientTrusted": function (certs, authType) {},
        "checkServerTrusted": function (certs, authType) {},
        "checkClientTrusted": function (xcs, string, socket) {},
        "checkServerTrusted": function (xcs, string, socket) {},
        "checkClientTrusted": function (xcs, string, ssle) {},
        "checkServerTrusted": function (xcs, string, ssle) {},
    });
    
    // HostnameVerifier that verifies all hosts.
    TrustAllHostnameVerifier = Java.extend(HostnameVerifier, {
        "verify": function (hostname, session) {
            return true;
        },
    });
    
    // Call the main function.
    main();
    
    /**
     * The main function provides an entry point for the script.
     */
    function main() {
        // download the necessary Jar files if they don't exist
        downloadJars();
    
        // The Jar file urls for the cups4j client, commons-lang 2.6 and simple-xml dependency.  All other dependencies are already present in the Maximo class path
        var urls = [
            new URL("file://" + JAR_PATH + "cups4j-0.7.9.jar"),
            new URL("file://" + JAR_PATH + "commons-lang-2.6.jar"),
            new URL("file://" + JAR_PATH + "simple-xml-2.7.1.jar"),
        ];
    
        // Create a new class loader with urls and set the parent as the current thread context loader that launched the script
        var urlClassLoader = URLClassLoader.newInstance(Java.to(urls, URLArrayType), Thread.currentThread().getContextClassLoader());
    
        // Load the client, printer and job.
        CupsClient = urlClassLoader.loadClass("org.cups4j.CupsClient");
        CupsPrinter = urlClassLoader.loadClass("org.cups4j.CupsPrinter");
        PrintJob = urlClassLoader.loadClass("org.cups4j.PrintJob");
        PrintJobBuilder = urlClassLoader.loadClass("org.cups4j.PrintJob$Builder");
    
        // Create a new instance of the client and printer
        var cupsClient = CupsClient.getConstructor(StringType.class, IntType.class).newInstance(CUPS_ADDRESS, CUPS_PORT);
        var cupsPrinter = cupsClient.getPrinter(CUPS_PRINT_NAME);
    
        // Get the report as a PDF
        var reportData = generateReport(MXServer.getMXServer().getSystemUserInfo(), "WOTRACK", "woprint.rptdesign", "workorder.wonum='1118'");
    
        // Create a new print job
        var printJob = PrintJobBuilder.getConstructor(ByteArrayType.class).newInstance(reportData).build();
        
        // Send the print job to the printer.
        var printRequestResult = cupsPrinter.print(printJob);
    
        // If the request was a direct web request then return a result.
        if (typeof request !== "undefined") {
            responseBody = JSON.stringify({ "status":printRequestResult.isSuccessfulResult()? "success":"error", "details": printRequestResult.getResultDescription() }, null, 4);
        }
    }
    
    /**
     * Runs the report and returns the results as byte array for the resulting PDF.
     * @param {psdi.security.UserInfo} userInfo The user that
     * @param {String} app the name of the Maximo application that the report is registered to.
     * @param {String} report the name of the report, this should end in ".rptdesign"
     * @param {String} whereClause the where clause that the report will use.
     * @returns byte[] of the PDF result.
     */
    function generateReport(userInfo, app, report, whereClause) {
        // get the report administrative service.
        var reportService = MXServer.getMXServer().lookup("BIRTREPORT");
    
        // add the where clause to the report parameters.
        // additional parameters could be added here.
        var parameterData = new ReportParameterData();
        parameterData.addParameter("where", whereClause);
    
        // run the report immediately and return the results as a PDF
        return reportService.runReportInImmediateMode(userInfo, report, app, parameterData, "report.pdf", ReportAdminServiceRemote.OUTPUT_FORMAT_PDF);
    }
    
    /**
     * Downloads the CUPS client JAR files and dependencies. SSL validation is disabled to ensure that the files are successfully downloaded without needing
     * to register the GlobalSign CA used by the repo01.maven.org server.
     */
    function downloadJars() {
        var trustAllCerts = Java.to([new TrustAllManager()], TrustManagerArrayType);
        var sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new SecureRandom());
    
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HttpsURLConnection.setDefaultHostnameVerifier(new TrustAllHostnameVerifier());
    
        downloadJarIfMissing("https://repo1.maven.org/maven2/org/cups4j/cups4j/0.7.9/cups4j-0.7.9.jar", "cups4j-0.7.9.jar");
        downloadJarIfMissing("https://repo1.maven.org/maven2/org/simpleframework/simple-xml/2.7.1/simple-xml-2.7.1.jar", "simple-xml-2.7.1.jar");
        downloadJarIfMissing("https://repo1.maven.org/maven2/commons-lang/commons-lang/2.6/commons-lang-2.6.jar", "commons-lang-2.6.jar");
    }
    
    /**
     * Downloads the specified Jar file URL to a temporary location.
     * @param {String} uri the URI to download.
     * @param {String} fileName the name of the file to save as.
     */
    function downloadJarIfMissing(uri, fileName) {
        // create the downloaded Jar in the var/tmp directory.
        var file = new File(JAR_PATH + fileName);
    
        // if the file doesn't exist then download it.
        if (!file.exists()) {
            url = new URL(uri);
    
            var connection = url.openConnection();
    
            var outputStream = new FileOutputStream(file);
            var inputStream = connection.getInputStream();
            var bytesRead = -1;
            buffer = new ByteArrayType(2048);
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
    
            outputStream.close();
            inputStream.close();
        }
    }
    
    var scriptConfig = {
        "autoscript": "PRINT",
        "description": "Print",
        "version": "",
        "active": true,
        "logLevel": "ERROR",
    };
    


    ------------------------------
    Jason VenHuizen
    https://sharptree.io
    https://opqo.io
    ------------------------------



  • 8.  RE: Server-side printing for reports on Maximo Application Suite

    Posted Tue September 05, 2023 01:33 PM

    This sounds great. I thought we'd need CUPS here somewhere, and you have confirmed it. BTW, are you running CUPS's docker image as a separate container in OCP?



    ------------------------------
    Arif Ali
    ------------------------------



  • 9.  RE: Server-side printing for reports on Maximo Application Suite

    Posted Tue September 05, 2023 01:38 PM

    I am running it on my desktop just to test it out, but I would expect that you would run it in a pod on OCP.  Although, I think technically the OCP license provided with Maximo does not allow for any non-Maximo workloads, so you may be in a bit of a licensing grey area.

    I should also mention, I wrote that last night just to see if it could be done so I haven't deployed in a product environment.



    ------------------------------
    Jason VenHuizen
    https://sharptree.io
    https://opqo.io
    ------------------------------



  • 10.  RE: Server-side printing for reports on Maximo Application Suite

    Posted Tue February 13, 2024 01:03 AM

    Thank you so much for clarification. Sorry for the delay in response. 



    ------------------------------
    [Srikanth][Narala]
    [Maximo Specialist]
    [Melbourne]
    [Australia]
    ------------------------------



  • 11.  RE: Server-side printing for reports on Maximo Application Suite

    Posted Tue September 12, 2023 08:23 PM

    Howdy..... read up on this after time away at he beach and fishing! Ha!

    I have a silly question.... What is business value for server side printing?  I have not been able to decipher that.  Most print jobs are performed locally to begin with.  Now that mobility drives a huge portion of the paper out of the process the remainder of reprots are most likely emailed.  That still works, and there is no "print server."  So I am kinda stumped on the use case at this point.  Maybe after writing over 1500 reports during the past two decades and then not doing a darned thing with reporting for about eight years now I am just rusty?  Please someone educate me.



    ------------------------------
    Bradley K. Downing , MBA
    Senior Brand Technical Specialist
    IBM
    Bakersfield CA
    ------------------------------



  • 12.  RE: Server-side printing for reports on Maximo Application Suite

    Posted Tue February 13, 2024 01:00 AM
    Edited by maximo njsreddy Tue February 13, 2024 01:00 AM

    Currently we are using this server side print class in autoscript to print barcode labels. This is to print barcode labels. Thank you.



    ------------------------------
    [Srikanth][Narala]
    [Maximo Specialist]
    [Melbourne]
    [Australia]
    ------------------------------



  • 13.  RE: Server-side printing for reports on Maximo Application Suite

    Posted Wed July 31, 2024 11:45 AM

    Srikanth,

    I had missed this earlier, but if you are printing labels you may want to check this out.  https://github.com/sharptree/zebra-label

    Jason



    ------------------------------
    Jason VenHuizen
    https://sharptree.io
    https://opqo.io
    ------------------------------