Search in sources :

Example 1 with IPipelineEngine

use of org.apache.hop.pipeline.engine.IPipelineEngine in project hop by apache.

the class PipelineLoggingExtensionPoint method logPipelineMetadata.

private void logPipelineMetadata(final ILogChannel log, final Session session, final NeoConnection connection, final IPipelineEngine<PipelineMeta> pipeline) throws HopException {
    log.logDetailed("Logging pipeline metadata to Neo4j connection : " + connection.getName());
    final PipelineMeta pipelineMeta = pipeline.getPipelineMeta();
    synchronized (session) {
        session.writeTransaction((TransactionWork<Void>) transaction -> {
            try {
                Map<String, Object> transPars = new HashMap<>();
                transPars.put("pipelineName", pipelineMeta.getName());
                transPars.put("description", pipelineMeta.getDescription());
                transPars.put("filename", pipelineMeta.getFilename());
                StringBuilder transCypher = new StringBuilder();
                transCypher.append("MERGE (pipeline:Pipeline { name : $pipelineName } ) ");
                transCypher.append("SET pipeline.filename = $filename, pipeline.description = $description ");
                transaction.run(transCypher.toString(), transPars);
                log.logDetailed("Pipeline cypher : " + transCypher);
                for (TransformMeta transformMeta : pipelineMeta.getTransforms()) {
                    Map<String, Object> transformPars = new HashMap<>();
                    transformPars.put("pipelineName", pipelineMeta.getName());
                    transformPars.put("transformName", transformMeta.getName());
                    transformPars.put("description", transformMeta.getDescription());
                    transformPars.put("pluginId", transformMeta.getPluginId());
                    transformPars.put("copies", transformMeta.getCopies(pipeline));
                    transformPars.put("locationX", transformMeta.getLocation().x);
                    transformPars.put("locationY", transformMeta.getLocation().y);
                    StringBuilder transformCypher = new StringBuilder();
                    transformCypher.append("MATCH (pipeline:Pipeline { name : $pipelineName } ) ");
                    transformCypher.append("MERGE (transform:Transform { pipelineName : $pipelineName, name : $transformName } ) ");
                    transformCypher.append("SET ");
                    transformCypher.append("  transform.description = $description ");
                    transformCypher.append(", transform.pluginId = $pluginId ");
                    transformCypher.append(", transform.copies = $copies ");
                    transformCypher.append(", transform.locationX = $locationX ");
                    transformCypher.append(", transform.locationY = $locationY ");
                    transformCypher.append("MERGE (transform)-[rel:TRANSFORM_OF_PIPELINE]->(pipeline) ");
                    log.logDetailed("Transform '" + transformMeta.getName() + "' cypher : " + transformCypher);
                    transaction.run(transformCypher.toString(), transformPars);
                }
                for (int i = 0; i < pipelineMeta.nrPipelineHops(); i++) {
                    PipelineHopMeta hopMeta = pipelineMeta.getPipelineHop(i);
                    Map<String, Object> hopPars = new HashMap<>();
                    hopPars.put("fromTransform", hopMeta.getFromTransform().getName());
                    hopPars.put("toTransform", hopMeta.getToTransform().getName());
                    hopPars.put("pipelineName", pipelineMeta.getName());
                    StringBuilder hopCypher = new StringBuilder();
                    hopCypher.append("MATCH (from:Transform { pipelineName : $pipelineName, name : $fromTransform }) ");
                    hopCypher.append("MATCH (to:Transform { pipelineName : $pipelineName, name : $toTransform }) ");
                    hopCypher.append("MERGE (from)-[rel:PRECEDES]->(to) ");
                    transaction.run(hopCypher.toString(), hopPars);
                }
                transaction.commit();
            } catch (Exception e) {
                transaction.rollback();
                log.logError("Error logging pipeline metadata", e);
            }
            return null;
        });
    }
}
Also used : PipelineHopMeta(org.apache.hop.pipeline.PipelineHopMeta) Session(org.neo4j.driver.Session) org.apache.hop.pipeline.transform(org.apache.hop.pipeline.transform) Driver(org.neo4j.driver.Driver) java.util(java.util) ILogChannel(org.apache.hop.core.logging.ILogChannel) HopLogStore(org.apache.hop.core.logging.HopLogStore) ExtensionPoint(org.apache.hop.core.extension.ExtensionPoint) IVariables(org.apache.hop.core.variables.IVariables) Defaults(org.apache.hop.neo4j.logging.Defaults) HopException(org.apache.hop.core.exception.HopException) SimpleDateFormat(java.text.SimpleDateFormat) LoggingObjectType(org.apache.hop.core.logging.LoggingObjectType) TransactionWork(org.neo4j.driver.TransactionWork) IPipelineEngine(org.apache.hop.pipeline.engine.IPipelineEngine) Transaction(org.neo4j.driver.Transaction) LoggingHierarchy(org.apache.hop.core.logging.LoggingHierarchy) IExtensionPoint(org.apache.hop.core.extension.IExtensionPoint) NeoConnection(org.apache.hop.neo4j.shared.NeoConnection) Pipeline(org.apache.hop.pipeline.Pipeline) Result(org.apache.hop.core.Result) LoggingCore(org.apache.hop.neo4j.logging.util.LoggingCore) PipelineMeta(org.apache.hop.pipeline.PipelineMeta) PipelineHopMeta(org.apache.hop.pipeline.PipelineHopMeta) HopException(org.apache.hop.core.exception.HopException) PipelineMeta(org.apache.hop.pipeline.PipelineMeta)

Example 2 with IPipelineEngine

use of org.apache.hop.pipeline.engine.IPipelineEngine in project hop by apache.

the class LocalPipelineEngine method prepareExecution.

@Override
public void prepareExecution() throws HopException {
    if (!(pipelineRunConfiguration.getEngineRunConfiguration() instanceof LocalPipelineRunConfiguration)) {
        throw new HopException("A local pipeline execution expects a local pipeline configuration, not an instance of class " + pipelineRunConfiguration.getEngineRunConfiguration().getClass().getName());
    }
    LocalPipelineRunConfiguration config = (LocalPipelineRunConfiguration) pipelineRunConfiguration.getEngineRunConfiguration();
    int sizeRowsSet = Const.toInt(resolve(config.getRowSetSize()), Const.ROWS_IN_ROWSET);
    setRowSetSize(sizeRowsSet);
    setSafeModeEnabled(config.isSafeModeEnabled());
    setSortingTransformsTopologically(config.isSortingTransformsTopologically());
    setGatheringMetrics(config.isGatheringMetrics());
    setFeedbackShown(config.isFeedbackShown());
    setFeedbackSize(Const.toInt(resolve(config.getFeedbackSize()), Const.ROWS_UPDATE));
    // See if we need to enable transactions...
    // 
    IExtensionData parentExtensionData = getParentPipeline();
    if (parentExtensionData == null) {
        parentExtensionData = getParentWorkflow();
    }
    String connectionGroup = null;
    if (parentExtensionData != null) {
        connectionGroup = (String) parentExtensionData.getExtensionDataMap().get(Const.CONNECTION_GROUP);
    }
    // 
    if (config.isTransactional() && connectionGroup == null) {
        // Store a value in the parent...
        // 
        connectionGroup = getPipelineMeta().getName() + " - " + UUID.randomUUID();
        // We also need to commit/rollback at the end of this pipeline...
        // We only do this when we created a new group.  Never in a child
        // 
        addExecutionFinishedListener((IExecutionFinishedListener<IPipelineEngine>) pipeline -> {
            String group = (String) pipeline.getExtensionDataMap().get(Const.CONNECTION_GROUP);
            List<Database> databases = DatabaseConnectionMap.getInstance().getDatabases(group);
            Result result = pipeline.getResult();
            for (Database database : databases) {
                try {
                    if (result.getResult() && !result.isStopped() && result.getNrErrors() == 0) {
                        try {
                            database.commit(true);
                            pipeline.getLogChannel().logBasic("All transactions of database connection '" + database.getDatabaseMeta().getName() + "' were committed at the end of the pipeline!");
                        } catch (HopDatabaseException e) {
                            throw new HopException("Error committing database connection " + database.getDatabaseMeta().getName(), e);
                        }
                    } else {
                        try {
                            database.rollback(true);
                            pipeline.getLogChannel().logBasic("All transactions of database connection '" + database.getDatabaseMeta().getName() + "' were rolled back at the end of the pipeline!");
                        } catch (HopDatabaseException e) {
                            throw new HopException("Error rolling back database connection " + database.getDatabaseMeta().getName(), e);
                        }
                    }
                } finally {
                    try {
                        database.closeConnectionOnly();
                        pipeline.getLogChannel().logDebug("Database connection '" + database.getDatabaseMeta().getName() + "' closed successfully!");
                    } catch (HopDatabaseException hde) {
                        pipeline.getLogChannel().logError("Error disconnecting from database - closeConnectionOnly failed:" + Const.CR + hde.getMessage());
                        pipeline.getLogChannel().logError(Const.getStackTracker(hde));
                    }
                }
                DatabaseConnectionMap.getInstance().removeConnection(group, null, database);
            }
        });
    }
    // 
    if (connectionGroup != null && getExtensionDataMap() != null) {
        // Set the connection group for this pipeline
        // 
        getExtensionDataMap().put(Const.CONNECTION_GROUP, connectionGroup);
    }
    super.prepareExecution();
}
Also used : IPipelineEngineRunConfiguration(org.apache.hop.pipeline.config.IPipelineEngineRunConfiguration) Database(org.apache.hop.core.database.Database) HopDatabaseException(org.apache.hop.core.exception.HopDatabaseException) ILoggingObject(org.apache.hop.core.logging.ILoggingObject) IVariables(org.apache.hop.core.variables.IVariables) HopException(org.apache.hop.core.exception.HopException) IHopMetadataProvider(org.apache.hop.metadata.api.IHopMetadataProvider) UUID(java.util.UUID) Const(org.apache.hop.core.Const) IPipelineEngine(org.apache.hop.pipeline.engine.IPipelineEngine) ArrayList(java.util.ArrayList) PipelineEnginePlugin(org.apache.hop.pipeline.engine.PipelineEnginePlugin) INamedParameters(org.apache.hop.core.parameters.INamedParameters) List(java.util.List) Pipeline(org.apache.hop.pipeline.Pipeline) DatabaseConnectionMap(org.apache.hop.core.database.map.DatabaseConnectionMap) Result(org.apache.hop.core.Result) IExtensionData(org.apache.hop.core.IExtensionData) PipelineRunConfiguration(org.apache.hop.pipeline.config.PipelineRunConfiguration) PipelineMeta(org.apache.hop.pipeline.PipelineMeta) PipelineEngineCapabilities(org.apache.hop.pipeline.engine.PipelineEngineCapabilities) IExecutionFinishedListener(org.apache.hop.pipeline.IExecutionFinishedListener) IExtensionData(org.apache.hop.core.IExtensionData) HopException(org.apache.hop.core.exception.HopException) Database(org.apache.hop.core.database.Database) ArrayList(java.util.ArrayList) List(java.util.List) HopDatabaseException(org.apache.hop.core.exception.HopDatabaseException) IPipelineEngine(org.apache.hop.pipeline.engine.IPipelineEngine) Result(org.apache.hop.core.Result)

Example 3 with IPipelineEngine

use of org.apache.hop.pipeline.engine.IPipelineEngine in project hop by apache.

the class GetStatusServlet method doGet.

@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    if (isJettyMode() && !request.getContextPath().startsWith(CONTEXT_PATH)) {
        return;
    }
    if (log.isDebug()) {
        logDebug(BaseMessages.getString(PKG, "GetStatusServlet.StatusRequested"));
    }
    response.setStatus(HttpServletResponse.SC_OK);
    String root = request.getRequestURI() == null ? StatusServletUtils.HOP_ROOT : request.getRequestURI().substring(0, request.getRequestURI().indexOf(CONTEXT_PATH));
    String prefix = isJettyMode() ? StatusServletUtils.STATIC_PATH : root + StatusServletUtils.RESOURCES_PATH;
    boolean useXml = "Y".equalsIgnoreCase(request.getParameter("xml"));
    boolean useJson = "Y".equalsIgnoreCase(request.getParameter("json"));
    boolean useLightTheme = "Y".equalsIgnoreCase(request.getParameter("useLightTheme"));
    if (useXml) {
        response.setContentType("text/xml");
        response.setCharacterEncoding(Const.XML_ENCODING);
    }
    if (useJson) {
        response.setContentType("application/json");
        response.setCharacterEncoding(Const.XML_ENCODING);
    } else {
        response.setContentType("text/html;charset=UTF-8");
    }
    PrintWriter out = response.getWriter();
    List<HopServerObjectEntry> pipelineEntries = getPipelineMap().getPipelineObjects();
    List<HopServerObjectEntry> actions = getWorkflowMap().getWorkflowObjects();
    if (useXml || useJson) {
        HopServerStatus serverStatus = new HopServerStatus();
        serverStatus.setStatusDescription("Online");
        getSystemInfo(serverStatus);
        for (HopServerObjectEntry entry : pipelineEntries) {
            IPipelineEngine<PipelineMeta> pipeline = getPipelineMap().getPipeline(entry);
            String statusDescription = pipeline.getStatusDescription();
            HopServerPipelineStatus pipelineStatus = new HopServerPipelineStatus(entry.getName(), entry.getId(), statusDescription);
            pipelineStatus.setLogDate(new Date());
            pipelineStatus.setExecutionStartDate(pipeline.getExecutionStartDate());
            pipelineStatus.setExecutionEndDate(pipeline.getExecutionEndDate());
            pipelineStatus.setPaused(pipeline.isPaused());
            serverStatus.getPipelineStatusList().add(pipelineStatus);
        }
        for (HopServerObjectEntry entry : actions) {
            IWorkflowEngine<WorkflowMeta> workflow = getWorkflowMap().getWorkflow(entry);
            String status = workflow.getStatusDescription();
            HopServerWorkflowStatus workflowStatus = new HopServerWorkflowStatus(entry.getName(), entry.getId(), status);
            workflowStatus.setLogDate(new Date());
            workflowStatus.setExecutionStartDate(workflow.getExecutionStartDate());
            workflowStatus.setExecutionEndDate(workflow.getExecutionEndDate());
            serverStatus.getWorkflowStatusList().add(workflowStatus);
        }
        if (useXml) {
            // XML
            try {
                out.print(XmlHandler.getXmlHeader(Const.XML_ENCODING));
                out.println(serverStatus.getXml());
            } catch (HopException e) {
                throw new ServletException("Unable to get the server status in XML format", e);
            }
        } else {
            // JSON
            // 
            ObjectMapper mapper = new ObjectMapper();
            String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(serverStatus);
            out.println(jsonString);
        }
    } else {
        out.println("<HTML>");
        out.println("<HEAD><TITLE>" + BaseMessages.getString(PKG, "GetStatusServlet.HopHopServerStatus") + "</TITLE>");
        out.println("<META http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
        int tableBorder = 1;
        if (!useLightTheme) {
            if (isJettyMode()) {
                out.println("<link rel=\"stylesheet\" type=\"text/css\" href=\"/static/css/hop-server.css\" />");
            } else {
                out.println("<style>");
                out.println(".hop-table td, tr.cellTableRow, td.gwt-MenuItem, .toolbar-button:not(.toolbar-button-disabled) {");
                out.println("  cursor: pointer;");
                out.println("}");
                out.println(".toolbar-button-disabled {");
                out.println("  opacity: 0.4;");
                out.println("}");
                out.println("div#messageDialogBody:first-letter {");
                out.println("  text-transform: capitalize;");
                out.println("}");
                out.println("</style>");
            }
            tableBorder = 0;
        }
        out.println("</HEAD>");
        out.println("<BODY class=\"hop-page-background dragdrop-dropTarget dragdrop-boundary\" style=\"overflow: auto;\">");
        // Empty div for containing currently selected item
        out.println("<div id=\"selectedTableItem\">");
        // initialize to none
        out.println("<value></value>");
        out.println("</div>");
        out.println("<div class=\"row\" id=\"pucHeader\">");
        String htmlClass = useLightTheme ? "h1" : "div";
        out.println("<" + htmlClass + " class=\"workspaceHeading\" style=\"padding: 0px 0px 0px 10px;\">" + BaseMessages.getString(PKG, "GetStatusServlet.TopStatus") + "</" + htmlClass + ">");
        out.println("</div>");
        try {
            // Tooltips
            String run = BaseMessages.getString(PKG, "HopServerStatusServlet.Run");
            String stop = BaseMessages.getString(PKG, "HopServerStatusServlet.StopPipeline");
            String cleanup = BaseMessages.getString(PKG, "HopServerStatusServlet.CleanupPipeline");
            String view = BaseMessages.getString(PKG, "HopServerStatusServlet.ViewPipelineDetails");
            String remove = BaseMessages.getString(PKG, "HopServerStatusServlet.RemovePipeline");
            out.println("<div class=\"row\" style=\"padding: 0px 0px 0px 30px\">");
            htmlClass = useLightTheme ? "h2" : "div";
            out.println("<div class=\"row\" style=\"padding: 25px 30px 75px 0px;\">");
            out.println("<" + htmlClass + " class=\"workspaceHeading\" style=\"padding: 0px 0px 0px 0px;\">Pipelines</" + htmlClass + ">");
            out.println("<table id=\"pipeline-table\" cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td align=\"left\" width=\"100%\" style=\"vertical-align:middle;\">");
            out.println("<table cellspacing=\"0\" cellpadding=\"0\" class=\"toolbar\" style=\"width: 100%; height: 26px; margin-bottom: 2px; border: 0;\">");
            out.println("<tbody><tr>");
            out.println("<td align=\"left\" style=\"vertical-align: middle; width: 100%\" id=\"pipeline-align\"></td>");
            out.println("<td " + setupIconEnterLeaveJavascript("pause") + " align=\"left\" style=\"vertical-align: middle;\"><div style=\"padding: 2px;\" onClick=\"resumeFunction( this )\" class=\"toolbar-button toolbar-button-disabled\" id=\"pause\"><img " + "style=\"width: 22px; height: 22px\" src=\"" + prefix + "/images/run.svg\" title=\"" + run + "\"/></div></td>");
            out.println("<td " + setupIconEnterLeaveJavascript("stop") + " align=\"left\" style=\"vertical-align: middle;\"><div style=\"padding: 2px;\" onClick=\"stopFunction( this )\" class=\"toolbar-button toolbar-button-disabled\" id=\"stop\"><img " + "style=\"width: 22px; height: 22px\"src=\"" + prefix + "/images/stop.svg\" title=\"" + stop + "\"/></div></td>");
            out.println("<td " + setupIconEnterLeaveJavascript("cleanup") + " align=\"left\" style=\"vertical-align: middle;\"><div style=\"padding: 2px; margin-left: 10px !important;\" onClick=\"cleanupFunction( this )\" class=\"toolbar-button " + "toolbar-button-disabled\" id=\"cleanup\"><img style=\"width: 22px; height: 22px\"src=\"" + prefix + "/images/cleanup.svg\" title=\"" + cleanup + "\"/></div></td>");
            out.println("<td " + setupIconEnterLeaveJavascript("view") + " align=\"left\" style=\"vertical-align: middle;\"><div style=\"padding: 2px; margin-left: 0 !important;\" onClick=\"viewFunction( this )\" class=\"toolbar-button " + "toolbar-button-disabled\" id=\"view\"><img style=\"width: 22px; height: 22px\" src=\"" + prefix + "/images/view.svg\" title=\"" + view + "\"/></div></td>");
            out.println("<td " + setupIconEnterLeaveJavascript("close") + " align=\"left\" style=\"vertical-align: middle;\"><div style=\"padding: 2px; margin-right: 10px;\" onClick=\"removeFunction( this )\" class=\"toolbar-button toolbar-button-disabled\" " + "id=\"close\"><img style=\"width: 22px; height: 22px\" src=\"" + prefix + "/images/close.svg\" title=\"" + remove + "\"/></div></td>");
            out.println("</tr></tbody></table>");
            out.println("<div id=\"runActions\" class=\"custom-dropdown-popup\" style=\"visibility: hidden; overflow: visible; position: fixed;\" onLoad=\"repositionActions( this, document.getElementById( " + "'pause' ) )\" onMouseLeave=\"this.style='visibility: hidden; overflow: visible; position: fixed;'\"><div class=\"popupContent\"><div style=\"padding: 0;\" class=\"gwt-MenuBar " + "gwt-MenuBar-vertical\"><table><tbody><tr><td class=\"gwt-MenuItem\" onClick=\"runPipelineSelector( this )\" onMouseEnter=\"this.className='gwt-MenuItem gwt-MenuItem-selected'\" " + "onMouseLeave=\"this.className='gwt-MenuItem'\">Prepare the execution</td></tr><tr><td class=\"gwt-MenuItem\" onClick=\"runPipelineSelector( this )\" onMouseEnter=\"this" + ".className='gwt-MenuItem gwt-MenuItem-selected'\" onMouseLeave=\"this.className='gwt-MenuItem'\">Run</td></tr></tbody></table></div></div></div>");
            out.println("<div id=\"stopActions\" class=\"custom-dropdown-popup\" style=\"visibility: hidden; overflow: visible; position: fixed;\" onLoad=\"repositionActions( this, document.getElementById( " + "'stop' ) )\" onMouseLeave=\"this.style='visibility: hidden; overflow: visible; position: fixed;'\"><div class=\"popupContent\"><div style=\"padding: 0;\" class=\"gwt-MenuBar " + "gwt-MenuBar-vertical\"><table><tbody><tr><td class=\"gwt-MenuItem\" onClick=\"stopPipelineSelector( this )\" onMouseEnter=\"this.className='gwt-MenuItem gwt-MenuItem-selected'\" " + "onMouseLeave=\"this.className='gwt-MenuItem'\">Stop pipeline</td></tr><tr><td class=\"gwt-MenuItem\" onClick=\"stopPipelineSelector( this )\" onMouseEnter=\"this" + ".className='gwt-MenuItem gwt-MenuItem-selected'\" onMouseLeave=\"this.className='gwt-MenuItem'\">Stop input processing</td></tr></tbody></table></div></div></div>");
            out.println(messageDialog());
            out.println("<table class=\"hop-table\" border=\"" + tableBorder + "\">");
            out.print("<tr> <th class=\"cellTableHeader\">" + BaseMessages.getString(PKG, "GetStatusServlet.PipelineName") + "</th> <th class=\"cellTableHeader\">" + BaseMessages.getString(PKG, "GetStatusServlet.ServerId") + "</th> <th class=\"cellTableHeader\">" + BaseMessages.getString(PKG, "GetStatusServlet.Status") + "</th> <th class=\"cellTableHeader\">" + BaseMessages.getString(PKG, "GetStatusServlet.StartDate") + "</th> <th class=\"cellTableHeader\">" + BaseMessages.getString(PKG, "GetStatusServlet.LastLogTime") + "</th> </tr>");
            Comparator<HopServerObjectEntry> pipelineComparator = (o1, o2) -> {
                IPipelineEngine<PipelineMeta> t1 = getPipelineMap().getPipeline(o1);
                IPipelineEngine<PipelineMeta> t2 = getPipelineMap().getPipeline(o2);
                Date d1 = t1.getExecutionStartDate();
                Date d2 = t2.getExecutionStartDate();
                // if both pipelines have last log date, desc sort by log date
                if (d1 != null && d2 != null) {
                    int logDateCompare = d2.compareTo(d1);
                    if (logDateCompare != 0) {
                        return logDateCompare;
                    }
                }
                return o1.compareTo(o2);
            };
            Collections.sort(pipelineEntries, pipelineComparator);
            boolean evenRow = true;
            for (int i = 0; i < pipelineEntries.size(); i++) {
                String name = pipelineEntries.get(i).getName();
                String id = pipelineEntries.get(i).getId();
                IPipelineEngine<PipelineMeta> pipeline = getPipelineMap().getPipeline(pipelineEntries.get(i));
                String statusDescription = pipeline.getStatusDescription();
                String trClass = // alternating row color
                evenRow ? "cellTableEvenRow" : "cellTableOddRow";
                String tdClass = evenRow ? "cellTableEvenRowCell" : "cellTableOddRowCell";
                // flip
                evenRow = !evenRow;
                String firstColumn = i == 0 ? "cellTableFirstColumn" : "";
                String lastColumn = i == pipelineEntries.size() - 1 ? "cellTableLastColumn" : "";
                out.print("<tr onMouseEnter=\"mouseEnterFunction( this, '" + trClass + "' )\" " + "onMouseLeave=\"mouseLeaveFunction( this, '" + trClass + "' )\" " + "onClick=\"clickFunction( this, '" + trClass + "' )\" " + "id=\"cellTableRow_" + i + "\" class=\"" + trClass + "\">");
                out.print("<td onMouseEnter=\"mouseEnterFunction( this, '" + tdClass + "' )\" " + "onMouseLeave=\"mouseLeaveFunction( this, '" + tdClass + "' )\" " + "onClick=\"clickFunction( this, '" + tdClass + "' )\" " + "id=\"cellTableFirstCell_" + i + "\" class=\"cellTableCell cellTableFirstColumn " + tdClass + "\">" + name + "</td>");
                out.print("<td onMouseEnter=\"mouseEnterFunction( this, '" + tdClass + "' )\" " + "onMouseLeave=\"mouseLeaveFunction( this, '" + tdClass + "' )\" " + "onClick=\"clickFunction( this, '" + tdClass + "' )\" " + "id=\"cellTableCell_" + i + "\" class=\"cellTableCell " + tdClass + "\">" + id + "</td>");
                out.print("<td onMouseEnter=\"mouseEnterFunction( this, '" + tdClass + "' )\" " + "onMouseLeave=\"mouseLeaveFunction( this, '" + tdClass + "' )\" " + "onClick=\"clickFunction( this, '" + tdClass + "' )\" " + "id=\"cellTableCellStatus_" + i + "\" class=\"cellTableCell " + tdClass + "\">" + statusDescription + "</td>");
                String dateStr = XmlHandler.date2string(pipeline.getExecutionStartDate());
                out.print("<td onMouseEnter=\"mouseEnterFunction( this, '" + tdClass + "' )\" " + "onMouseLeave=\"mouseLeaveFunction( this, '" + tdClass + "' )\" " + "onClick=\"clickFunction( this, '" + tdClass + "' )\" " + "id=\"cellTableCell_" + i + "\" class=\"cellTableCell " + tdClass + "\">" + (pipeline.getExecutionStartDate() == null ? "-" : dateStr.substring(0, dateStr.indexOf(' '))) + "</td>");
                out.print("<td onMouseEnter=\"mouseEnterFunction( this, '" + tdClass + "' )\" " + "onMouseLeave=\"mouseLeaveFunction( this, '" + tdClass + "' )\" " + "onClick=\"clickFunction( this, '" + tdClass + "' )\" " + "id=\"cellTableLastCell_" + i + "\" class=\"cellTableCell cellTableLastColumn " + tdClass + "\">" + dateStr.substring(dateStr.indexOf(' ')) + "</td>");
                out.print("</tr>");
            }
            out.print("</table></table>");
            // end div
            out.print("</div>");
            // Tooltips
            String runJ = BaseMessages.getString(PKG, "HopServerStatusServlet.Run");
            String stopJ = BaseMessages.getString(PKG, "HopServerStatusServlet.StopWorkflow");
            String viewJ = BaseMessages.getString(PKG, "HopServerStatusServlet.ViewWorkflowDetails");
            String removeJ = BaseMessages.getString(PKG, "HopServerStatusServlet.RemoveWorkflow");
            out.println("<div class=\"row\" style=\"padding: 0px 30px 75px 0px;\">");
            out.println("<" + htmlClass + " class=\"workspaceHeading\" style=\"padding: 0px 0px 0px 0px;\">Workflows</" + htmlClass + ">");
            out.println("<table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td align=\"left\" width=\"100%\" style=\"vertical-align:middle;\">");
            out.println("<table cellspacing=\"0\" cellpadding=\"0\" class=\"toolbar\" style=\"width: 100%; height: 26px; margin-bottom: 2px; border: 0;\">");
            out.println("<tbody><tr>");
            out.println("<td align=\"left\" style=\"vertical-align: middle; width: 100%\"></td>");
            out.println("<td " + setupIconEnterLeaveJavascript("j-pause") + " align=\"left\" style=\"vertical-align: middle;\"><div style=\"padding: 2px;\" onClick=\"resumeFunction( this )\" class=\"toolbar-button toolbar-button-disabled\" id=\"j-pause\"><img " + "style=\"width: 22px; height: 22px\" src=\"" + prefix + "/images/run.svg\" title=\"" + runJ + "\"/></div></td>");
            out.println("<td " + setupIconEnterLeaveJavascript("j-stop") + " align=\"left\" style=\"vertical-align: middle;\"><div style=\"padding: 2px;\" onClick=\"stopFunction( this )\" class=\"toolbar-button toolbar-button-disabled\" id=\"j-stop\"><img " + "style=\"width: 22px; height: 22px\"src=\"" + prefix + "/images/stop.svg\" title=\"" + stopJ + "\"/></div></td>");
            out.println("<td " + setupIconEnterLeaveJavascript("j-view") + " align=\"left\" style=\"vertical-align: middle;\"><div style=\"padding: 2px;\" onClick=\"viewFunction( this )\" class=\"toolbar-button toolbar-button-disabled\" id=\"j-view\"><img " + "style=\"width: 22px; height: 22px\" src=\"" + prefix + "/images/view.svg\" title=\"" + viewJ + "\"/></div></td>");
            out.println("<td " + setupIconEnterLeaveJavascript("j-close") + " align=\"left\" style=\"vertical-align: middle;\"><div style=\"padding: 2px; margin-right: 10px;\" onClick=\"removeFunction( this )\" class=\"toolbar-button toolbar-button-disabled\" " + "id=\"j-close\"><img style=\"width: 22px; height: 22px\" src=\"" + prefix + "/images/close.svg\" title=\"" + removeJ + "\"/></div></td>");
            out.println("</tr></tbody></table>");
            out.println("<table class=\"hop-table\" border=\"" + tableBorder + "\">");
            out.print("<tr> <th class=\"cellTableHeader\">" + BaseMessages.getString(PKG, "GetStatusServlet.WorkflowName") + "</th> <th class=\"cellTableHeader\">" + BaseMessages.getString(PKG, "GetStatusServlet.ServerId") + "</th> <th class=\"cellTableHeader\">" + BaseMessages.getString(PKG, "GetStatusServlet.Status") + "</th> <th class=\"cellTableHeader\">" + BaseMessages.getString(PKG, "GetStatusServlet.StartDate") + "</th> <th class=\"cellTableHeader\">" + BaseMessages.getString(PKG, "GetStatusServlet.LastLogTime") + "</th> </tr>");
            Comparator<HopServerObjectEntry> jobComparator = (o1, o2) -> {
                IWorkflowEngine<WorkflowMeta> t1 = getWorkflowMap().getWorkflow(o1);
                IWorkflowEngine<WorkflowMeta> t2 = getWorkflowMap().getWorkflow(o2);
                Date d1 = t1.getExecutionStartDate();
                Date d2 = t2.getExecutionStartDate();
                // if both workflows have last log date, desc sort by log date
                if (d1 != null && d2 != null) {
                    int logDateCompare = d2.compareTo(d1);
                    if (logDateCompare != 0) {
                        return logDateCompare;
                    }
                }
                return o1.compareTo(o2);
            };
            Collections.sort(actions, jobComparator);
            evenRow = true;
            for (int i = 0; i < actions.size(); i++) {
                String name = actions.get(i).getName();
                String id = actions.get(i).getId();
                IWorkflowEngine<WorkflowMeta> workflow = getWorkflowMap().getWorkflow(actions.get(i));
                String status = workflow.getStatusDescription();
                String trClass = // alternating row color
                evenRow ? "cellTableEvenRow" : "cellTableOddRow";
                String tdClass = evenRow ? "cellTableEvenRowCell" : "cellTableOddRowCell";
                // flip
                evenRow = !evenRow;
                out.print("<tr onMouseEnter=\"mouseEnterFunction( this, '" + trClass + "' )\" " + "onMouseLeave=\"mouseLeaveFunction( this, '" + trClass + "' )\" " + "onClick=\"clickFunction( this, '" + trClass + "' )\" " + "id=\"j-cellTableRow_" + i + "\" class=\"cellTableCell " + trClass + "\">");
                out.print("<td onMouseEnter=\"mouseEnterFunction( this, '" + tdClass + "' )\" " + "onMouseLeave=\"mouseLeaveFunction( this, '" + tdClass + "' )\" " + "onClick=\"clickFunction( this, '" + tdClass + "' )\" " + "id=\"j-cellTableFirstCell_" + i + "\" class=\"cellTableCell cellTableFirstColumn " + tdClass + "\">" + name + "</a></td>");
                out.print("<td onMouseEnter=\"mouseEnterFunction( this, '" + tdClass + "' )\" " + "onMouseLeave=\"mouseLeaveFunction( this, '" + tdClass + "' )\" " + "onClick=\"clickFunction( this, '" + tdClass + "' )\" " + "id=\"j-cellTableCell_" + i + "\" class=\"cellTableCell " + tdClass + "\">" + id + "</td>");
                out.print("<td onMouseEnter=\"mouseEnterFunction( this, '" + tdClass + "' )\" " + "onMouseLeave=\"mouseLeaveFunction( this, '" + tdClass + "' )\" " + "onClick=\"clickFunction( this, '" + tdClass + "' )\" " + "id=\"j-cellTableCell_" + i + "\" class=\"cellTableCell " + tdClass + "\">" + status + "</td>");
                String dateStr = XmlHandler.date2string(workflow.getExecutionStartDate());
                out.print("<td onMouseEnter=\"mouseEnterFunction( this, '" + tdClass + "' )\" " + "onMouseLeave=\"mouseLeaveFunction( this, '" + tdClass + "' )\" " + "onClick=\"clickFunction( this, '" + tdClass + "' )\" " + "id=\"j-cellTableCell_" + i + "\" class=\"cellTableCell " + tdClass + "\">" + (workflow.getExecutionStartDate() == null ? "-" : dateStr.substring(0, dateStr.indexOf(' '))) + "</td>");
                out.print("<td onMouseEnter=\"mouseEnterFunction( this, '" + tdClass + "' )\" " + "onMouseLeave=\"mouseLeaveFunction( this, '" + tdClass + "' )\" " + "onClick=\"clickFunction( this, '" + tdClass + "' )\" " + "id=\"j-cellTableLastCell_" + i + "\" class=\"cellTableCell cellTableLastColumn " + tdClass + "\">" + (dateStr != null ? dateStr.substring(dateStr.indexOf(' ')) : "") + "</td>");
                out.print("</tr>");
            }
            out.print("</table></table>");
            // end div
            out.print("</div>");
        } catch (Exception ex) {
            out.println("<pre>");
            ex.printStackTrace(out);
            out.println("</pre>");
        }
        out.println("<div class=\"row\" style=\"padding: 0px 0px 30px 0px;\">");
        htmlClass = useLightTheme ? "h3" : "div";
        out.println("<div><" + htmlClass + " class=\"workspaceHeading\">" + BaseMessages.getString(PKG, "GetStatusServlet.ConfigurationDetails.Title") + "</" + htmlClass + "></div>");
        out.println("<table border=\"" + tableBorder + "\">");
        // The max number of log lines in the back-end
        // 
        HopServerConfig serverConfig = getPipelineMap().getHopServerConfig();
        if (serverConfig != null) {
            String maxLines = "";
            if (serverConfig.getMaxLogLines() == 0) {
                maxLines = BaseMessages.getString(PKG, "GetStatusServlet.NoLimit");
            } else {
                maxLines = serverConfig.getMaxLogLines() + BaseMessages.getString(PKG, "GetStatusServlet.Lines");
            }
            out.print("<tr style=\"font-size: 12;\"> <td style=\"padding: 2px 10px 2px 10px\" class=\"cellTableCell cellTableEvenRowCell cellTableFirstColumn\">" + BaseMessages.getString(PKG, "GetStatusServlet.Parameter.MaxLogLines") + "</td> <td style=\"padding: 2px 10px 2px 10px\" class=\"cellTableCell cellTableEvenRowCell cellTableLastColumn\">" + maxLines + "</td> </tr>");
            // The max age of log lines
            // 
            String maxAge = "";
            if (serverConfig.getMaxLogTimeoutMinutes() == 0) {
                maxAge = BaseMessages.getString(PKG, "GetStatusServlet.NoLimit");
            } else {
                maxAge = serverConfig.getMaxLogTimeoutMinutes() + BaseMessages.getString(PKG, "GetStatusServlet.Minutes");
            }
            out.print("<tr style=\"font-size: 12;\"> <td style=\"padding: 2px 10px 2px 10px\" class=\"cellTableCell cellTableEvenRowCell cellTableFirstColumn\">" + BaseMessages.getString(PKG, "GetStatusServlet.Parameter.MaxLogLinesAge") + "</td> <td style=\"padding: 2px 10px 2px 10px\" class=\"cellTableCell cellTableEvenRowCell cellTableLastColumn\">" + maxAge + "</td> </tr>");
            // The max age of stale objects
            // 
            String maxObjAge = "";
            if (serverConfig.getObjectTimeoutMinutes() == 0) {
                maxObjAge = BaseMessages.getString(PKG, "GetStatusServlet.NoLimit");
            } else {
                maxObjAge = serverConfig.getObjectTimeoutMinutes() + BaseMessages.getString(PKG, "GetStatusServlet.Minutes");
            }
            out.print("<tr style=\"font-size: 12;\"> <td style=\"padding: 2px 10px 2px 10px\" class=\"cellTableCell cellTableEvenRowCell cellTableFirstColumn\">" + BaseMessages.getString(PKG, "GetStatusServlet.Parameter.MaxObjectsAge") + "</td> <td style=\"padding: 2px 10px 2px 10px\" class=\"cellTableCell cellTableEvenRowCell cellTableLastColumn\">" + maxObjAge + "</td> </tr>");
            out.print("</table>");
            String filename = serverConfig.getFilename();
            if (filename == null) {
                filename = BaseMessages.getString(PKG, "GetStatusServlet.ConfigurationDetails.UsingDefaults");
            }
            // end div
            out.println("</div>");
            out.print("<div class=\"row\">");
            out.println("<i>" + BaseMessages.getString(PKG, "GetStatusServlet.ConfigurationDetails.Advice", filename) + "</i>");
            out.print("</div>");
            out.print("</div>");
            out.print("</div>");
        }
        out.println("<script type=\"text/javascript\">");
        out.println("if (!String.prototype.endsWith) {");
        out.println("  String.prototype.endsWith = function(suffix) {");
        out.println("    return this.indexOf(suffix, this.length - suffix.length) !== -1;");
        out.println("  };");
        out.println("}");
        out.println("if (!String.prototype.startsWith) {");
        out.println("  String.prototype.startsWith = function(searchString, position) {");
        out.println("    position = position || 0;");
        out.println("    return this.indexOf(searchString, position) === position;");
        out.println("  };");
        out.println("}");
        // currently selected table item
        out.println("var selectedPipelineRowIndex = -1;");
        // currently selected table item
        out.println("var selectedWorkflowRowIndex = -1;");
        // element of remove button clicked
        out.println("var removeElement = null;");
        out.println("var selectedPipelineName = \"\";");
        out.println("var selectedWorkflowName = \"\";");
        // Click function for stop button
        out.println("function repositionActions( element, elementFrom ) {");
        out.println("element.style.left = ( 10 + elementFrom.getBoundingClientRect().left ) + 'px';");
        out.println("}");
        // Click function for resume button
        out.println("function resumeFunction( element ) {");
        out.println("if( !element.classList.contains('toolbar-button-disabled') ) {");
        out.println("if( element.id.startsWith( 'j-' ) && selectedWorkflowRowIndex != -1 ) {");
        out.println(setupAjaxCall(setupJobURI(convertContextPath(StartWorkflowServlet.CONTEXT_PATH)), BaseMessages.getString(PKG, "GetStatusServlet.StartWorkflow.Title"), "'" + BaseMessages.getString(PKG, "GetStatusServlet.TheWorkflow.Label") + " ' + selectedWorkflowName + ' " + BaseMessages.getString(PKG, "GetStatusServlet.StartWorkflow.Success.Body") + "'", "'" + BaseMessages.getString(PKG, "GetStatusServlet.TheWorkflow.Label") + " ' + selectedWorkflowName + ' " + BaseMessages.getString(PKG, "GetStatusServlet.StartWorkflow.Failure.Body") + "'"));
        out.println("} else if ( !element.id.startsWith( 'j-' ) && selectedPipelineRowIndex != -1 && document.getElementById( 'cellTableCellStatus_' + selectedPipelineRowIndex ).innerHTML == 'Running') {");
        out.println(setupAjaxCall(setupPipelineURI(convertContextPath(PausePipelineServlet.CONTEXT_PATH)), BaseMessages.getString(PKG, "GetStatusServlet.PausePipeline.Title"), "'" + BaseMessages.getString(PKG, "GetStatusServlet.ThePipeline.Label") + " ' + selectedPipelineName + ' " + BaseMessages.getString(PKG, "GetStatusServlet.PausePipeline.Success.Body") + "'", "'" + BaseMessages.getString(PKG, "GetStatusServlet.ThePipeline.Label") + " ' + selectedPipelineName + ' " + BaseMessages.getString(PKG, "GetStatusServlet.PausePipeline.Failure.Body") + "'"));
        out.println("} else if( !element.id.startsWith( 'j-' ) && selectedPipelineRowIndex != -1 && document.getElementById( 'cellTableCellStatus_' + selectedPipelineRowIndex ).innerHTML == 'Paused') {");
        out.println(setupAjaxCall(setupPipelineURI(convertContextPath(PausePipelineServlet.CONTEXT_PATH)), BaseMessages.getString(PKG, "GetStatusServlet.ResumePipeline.Title"), "'" + BaseMessages.getString(PKG, "GetStatusServlet.ThePipeline.Label") + " ' + selectedPipelineName + ' " + BaseMessages.getString(PKG, "GetStatusServlet.ResumePipeline.Success.Body") + "'", "'" + BaseMessages.getString(PKG, "GetStatusServlet.ThePipeline.Label") + " ' + selectedPipelineName + ' " + BaseMessages.getString(PKG, "GetStatusServlet.ResumePipeline.Failure.Body") + "'"));
        out.println("} else if( !element.id.startsWith( 'j-' ) && selectedPipelineRowIndex != -1 ){");
        out.println("repositionActions( document.getElementById( 'runActions' ), element );");
        out.println("document.getElementById( 'runActions' ).style.visibility = 'visible';");
        out.println("}");
        out.println("}");
        out.println("}");
        // Click function for stop button
        out.println("function stopFunction( element ) {");
        out.println("if( !element.classList.contains('toolbar-button-disabled') ) {");
        out.println("if( element.id.startsWith( 'j-' ) && selectedWorkflowRowIndex != -1 ) {");
        out.println(setupAjaxCall(setupJobURI(convertContextPath(StopWorkflowServlet.CONTEXT_PATH)), BaseMessages.getString(PKG, "GetStatusServlet.StopWorkflow.Title"), "'" + BaseMessages.getString(PKG, "GetStatusServlet.StopWorkflow.Success.Body1") + " " + BaseMessages.getString(PKG, "GetStatusServlet.TheWorkflow.Label") + " ' + selectedWorkflowName + ' " + BaseMessages.getString(PKG, "GetStatusServlet.StopWorkflow.Success.Body2") + "'", "'" + BaseMessages.getString(PKG, "GetStatusServlet.TheWorkflow.Label") + " ' + selectedWorkflowName + ' " + BaseMessages.getString(PKG, "GetStatusServlet.StopWorkflow.Failure.Body") + "'"));
        out.println("} else if ( !element.id.startsWith( 'j-' ) && selectedPipelineRowIndex != -1 ) {");
        out.println("repositionActions( document.getElementById( 'stopActions' ), element );");
        out.println("document.getElementById( 'stopActions' ).style.visibility = 'visible';");
        out.println("}");
        out.println("}");
        out.println("}");
        out.println("function runPipelineSelector( element ) {");
        out.println("if( element.innerHTML == 'Prepare the execution' ){");
        out.println(setupAjaxCall(setupPipelineURI(convertContextPath(PrepareExecutionPipelineServlet.CONTEXT_PATH)), BaseMessages.getString(PKG, "GetStatusServlet.PreparePipeline.Title"), "'" + BaseMessages.getString(PKG, "GetStatusServlet.ThePipeline.Label") + " ' + selectedPipelineName + ' " + BaseMessages.getString(PKG, "GetStatusServlet.PreparePipeline.Success.Body") + "'", "'" + BaseMessages.getString(PKG, "GetStatusServlet.ThePipeline.Label") + " ' + selectedPipelineName + ' " + BaseMessages.getString(PKG, "GetStatusServlet.PreparePipeline.Failure.Body") + "'"));
        out.println("} else {");
        out.println(setupAjaxCall(setupPipelineURI(convertContextPath(StartPipelineServlet.CONTEXT_PATH)), BaseMessages.getString(PKG, "GetStatusServlet.StartPipeline.Title"), "'" + BaseMessages.getString(PKG, "GetStatusServlet.ThePipeline.Label") + " ' + selectedPipelineName + ' " + BaseMessages.getString(PKG, "GetStatusServlet.StartPipeline.Success.Body") + "'", "'" + BaseMessages.getString(PKG, "GetStatusServlet.ThePipeline.Label") + " ' + selectedPipelineName + ' " + BaseMessages.getString(PKG, "GetStatusServlet.StartPipeline.Failure.Body") + "'"));
        out.println("}");
        out.println("}");
        // Click function for stop button
        out.println("function stopPipelineSelector( element ) {");
        out.println("if( element.innerHTML == 'Stop pipeline' ) {");
        out.println(setupAjaxCall(setupPipelineURI(convertContextPath(StopPipelineServlet.CONTEXT_PATH)), BaseMessages.getString(PKG, "GetStatusServlet.StopPipeline.Title"), "'" + BaseMessages.getString(PKG, "GetStatusServlet.PipelineStop.Success.Body1") + " " + BaseMessages.getString(PKG, "GetStatusServlet.ThePipeline.Label") + " ' + selectedPipelineName + ' " + BaseMessages.getString(PKG, "GetStatusServlet.PipelineStop.Success.Body2") + "'", "'" + BaseMessages.getString(PKG, "GetStatusServlet.ThePipeline.Label") + " ' + selectedPipelineName + ' " + BaseMessages.getString(PKG, "GetStatusServlet.StopPipeline.Failure.Body") + "'"));
        out.println("} else if( element.innerHTML == 'Stop input processing' ) {");
        out.println(setupAjaxCall(setupPipelineURI(convertContextPath(StopPipelineServlet.CONTEXT_PATH)) + " + '&inputOnly=Y'", BaseMessages.getString(PKG, "GetStatusServlet.StopInputPipeline.Title"), "'" + BaseMessages.getString(PKG, "GetStatusServlet.StopInputPipeline.Success.Body1") + " " + BaseMessages.getString(PKG, "GetStatusServlet.ThePipeline.Label") + " ' + selectedPipelineName + ' " + BaseMessages.getString(PKG, "GetStatusServlet.StopInputPipeline.Success.Body2") + "'", "'" + BaseMessages.getString(PKG, "GetStatusServlet.ThePipeline.Label") + " ' + selectedPipelineName + ' " + BaseMessages.getString(PKG, "GetStatusServlet.StopInputPipeline.Failure.Body") + "'"));
        out.println("}");
        out.println("document.getElementById( 'stopActions' ).style.visibility = 'hidden';");
        out.println("}");
        // Click function for view button
        out.println("function viewFunction( element ) {");
        out.println("if( !element.classList.contains('toolbar-button-disabled') ) {");
        out.println("if( element.id.startsWith( 'j-' ) && selectedWorkflowRowIndex != -1 ) {");
        out.println("window.location.replace( '" + convertContextPath(GetWorkflowStatusServlet.CONTEXT_PATH) + "'" + " + '?name=' + document.getElementById( 'j-cellTableFirstCell_' + selectedWorkflowRowIndex ).innerHTML" + " + '&id=' + document.getElementById( 'j-cellTableCell_' + selectedWorkflowRowIndex ).innerHTML );");
        out.println("} else if ( selectedPipelineRowIndex != -1 ) {");
        out.println("window.location.replace( '" + convertContextPath(GetPipelineStatusServlet.CONTEXT_PATH) + "'" + " + '?name=' + document.getElementById( 'cellTableFirstCell_' + selectedPipelineRowIndex ).innerHTML" + " + '&id=' + document.getElementById( 'cellTableCell_' + selectedPipelineRowIndex ).innerHTML );");
        out.println("}");
        out.println("}");
        out.println("}");
        // Click function for remove button
        out.println("function removeFunction( element ) {");
        out.println("if( !element.classList.contains('toolbar-button-disabled') ) {");
        out.println("removeElement = element;");
        out.println("if( element.id.startsWith( 'j-' ) && selectedWorkflowRowIndex != -1 ) {");
        out.println("openMessageDialog( '" + BaseMessages.getString(PKG, "GetStatusServlet.RemoveWorkflow.Title") + "'," + "'" + BaseMessages.getString(PKG, "GetStatusServlet.RemoveWorkflow.Confirm.Body") + " " + BaseMessages.getString(PKG, "GetStatusServlet.TheWorkflow.Label") + " ' + selectedWorkflowName + '?" + "'" + ", false );");
        out.println("} else if ( selectedPipelineRowIndex != -1 ) {");
        out.println("openMessageDialog( '" + BaseMessages.getString(PKG, "GetStatusServlet.RemovePipeline.Title") + "'," + "'" + BaseMessages.getString(PKG, "GetStatusServlet.RemovePipeline.Confirm.Body") + " " + BaseMessages.getString(PKG, "GetStatusServlet.ThePipeline.Label") + " ' + selectedPipelineName + '?" + "'" + ", false );");
        out.println("}");
        out.println("}");
        out.println("}");
        // OnClick function for table element
        out.println("function clickFunction( element, tableClass ) {");
        out.println("var prefix = element.id.startsWith( 'j-' ) ? 'j-' : '';");
        out.println("var rowNum = getRowNum( element.id );");
        out.println("if( tableClass.endsWith( 'Row' ) ) {");
        out.println("element.className='cellTableRow ' + tableClass + ' cellTableSelectedRow';");
        out.println("} else {");
        out.println("document.getElementById( prefix + 'cellTableFirstCell_' + rowNum ).className='cellTableCell cellTableFirstColumn ' + tableClass + ' cellTableSelectedRowCell';");
        out.println("element.className='cellTableCell ' + tableClass + ' cellTableSelectedRowCell';");
        out.println("}");
        out.println("if( element.id.startsWith( 'j-' ) ) {");
        out.println("document.getElementById( \"j-pause\" ).classList.remove( \"toolbar-button-disabled\" )");
        out.println("document.getElementById( \"j-stop\" ).classList.remove( \"toolbar-button-disabled\" )");
        out.println("document.getElementById( \"j-view\" ).classList.remove( \"toolbar-button-disabled\" )");
        out.println("document.getElementById( \"j-close\" ).classList.remove( \"toolbar-button-disabled\" )");
        out.println("if( selectedWorkflowRowIndex != -1 && rowNum != selectedWorkflowRowIndex ) {");
        out.println("document.getElementById( prefix + 'cellTableRow_' + selectedWorkflowRowIndex ).className='cellTableRow ' + tableClass;");
        out.println("document.getElementById( prefix + 'cellTableFirstCell_' + selectedWorkflowRowIndex ).className='cellTableCell cellTableFirstColumn ' + tableClass;");
        out.println("document.getElementById( prefix + 'cellTableCell_' + selectedWorkflowRowIndex ).className='cellTableCell ' + tableClass;");
        out.println("document.getElementById( prefix + 'cellTableLastCell_' + selectedWorkflowRowIndex ).className='cellTableCell cellTableLastColumn ' + tableClass;");
        out.println("}");
        out.println("selectedWorkflowRowIndex = rowNum;");
        out.println("} else {");
        out.println("document.getElementById( \"pause\" ).classList.remove( \"toolbar-button-disabled\" )");
        out.println("document.getElementById( \"stop\" ).classList.remove( \"toolbar-button-disabled\" )");
        out.println("document.getElementById( \"cleanup\" ).classList.remove( \"toolbar-button-disabled\" )");
        out.println("document.getElementById( \"view\" ).classList.remove( \"toolbar-button-disabled\" )");
        out.println("document.getElementById( \"close\" ).classList.remove( \"toolbar-button-disabled\" )");
        out.println("if( selectedPipelineRowIndex != -1 && rowNum != selectedPipelineRowIndex ) {");
        out.println("document.getElementById( prefix + 'cellTableRow_' + selectedPipelineRowIndex ).className='cellTableRow ' + tableClass;");
        out.println("document.getElementById( prefix + 'cellTableFirstCell_' + selectedPipelineRowIndex ).className='cellTableCell cellTableFirstColumn ' + tableClass;");
        out.println("document.getElementById( prefix + 'cellTableCell_' + selectedPipelineRowIndex ).className='cellTableCell ' + tableClass;");
        out.println("document.getElementById( prefix + 'cellTableLastCell_' + selectedPipelineRowIndex ).className='cellTableCell cellTableLastColumn ' + tableClass;");
        out.println("}");
        out.println("selectedPipelineRowIndex = rowNum;");
        out.println("if( document.getElementById( 'cellTableCellStatus_' + selectedPipelineRowIndex ).innerHTML == 'Running' ) {");
        out.println("document.getElementById( 'pause' ).innerHTML = '<img style=\"width: 22px; height: 22px\" src=\"" + prefix + "/images/pause.svg\"/ title=\"Pause pipeline\">';");
        out.println("} else if( document.getElementById( 'cellTableCellStatus_' + selectedPipelineRowIndex ).innerHTML == 'Paused' ) {");
        out.println("document.getElementById( 'pause' ).innerHTML = '<img style=\"width: 22px; height: 22px\" src=\"" + prefix + "/images/pause.svg\" title=\"Resume pipeline\"/>';");
        out.println("}");
        out.println("}");
        out.println("setSelectedNames();");
        out.println("}");
        // Function to set the pipeline or workflow name of the selected pipeline or workflow
        out.println("function setSelectedNames() {");
        out.println("  selectedWorkflowName = selectedPipelineName = \"\";");
        out.println("  var selectedElementNames = document.getElementsByClassName( \"cellTableFirstColumn cellTableSelectedRowCell\" );");
        out.println("  if( selectedElementNames ) {");
        out.println("    for(var i = 0; i < selectedElementNames.length; i++) {");
        out.println("      if(selectedElementNames[i].id.startsWith(\"j-\")) {");
        out.println("        selectedWorkflowName = selectedElementNames[i].innerHTML;");
        out.println("      } else {");
        out.println("        selectedPipelineName = selectedElementNames[i].innerHTML;");
        out.println("      }");
        out.println("    }");
        out.println("  }");
        out.println("}");
        // OnMouseEnter function
        out.println("function mouseEnterFunction( element, tableClass ) {");
        out.println("var prefix = '';");
        out.println("var rowNum = getRowNum( element.id );");
        out.println("var selectedIndex = selectedPipelineRowIndex;");
        out.println("if( element.id.startsWith( 'j-' ) ) {");
        out.println("prefix = 'j-';");
        out.println("selectedIndex = selectedWorkflowRowIndex;");
        out.println("}");
        out.println("if( rowNum != selectedIndex ) {");
        out.println("if( tableClass.endsWith( 'Row' ) ) {");
        out.println("element.className='cellTableRow ' + tableClass + ' cellTableHoveredRow';");
        out.println("} else {");
        out.println("document.getElementById( prefix + 'cellTableFirstCell_' + element.id.charAt( element.id.length - 1 ) ).className='cellTableCell cellTableFirstColumn ' + tableClass + ' " + "cellTableHoveredRowCell';");
        out.println("document.getElementById( prefix + 'cellTableCell_' + element.id.charAt( element.id.length - 1 ) ).className='cellTableCell ' + tableClass + ' cellTableHoveredRowCell';");
        out.println("document.getElementById( prefix + 'cellTableLastCell_' + element.id.charAt( element.id.length - 1 ) ).className='cellTableCell cellTableLastColumn ' + tableClass + ' " + "cellTableHoveredRowCell';");
        out.println("}");
        out.println("}");
        out.println("}");
        // OnMouseLeave function
        out.println("function mouseLeaveFunction( element, tableClass ) {");
        out.println("var prefix = '';");
        out.println("var rowNum = getRowNum( element.id );");
        out.println("var selectedIndex = selectedPipelineRowIndex;");
        out.println("if( element.id.startsWith( 'j-' ) ) {");
        out.println("prefix = 'j-';");
        out.println("selectedIndex = selectedWorkflowRowIndex;");
        out.println("}");
        out.println("if( rowNum != selectedIndex ) {");
        out.println("if( tableClass.endsWith( 'Row' ) ) {");
        out.println("element.className='cellTableRow ' + tableClass;");
        out.println("} else {");
        out.println("document.getElementById( prefix + 'cellTableFirstCell_' + element.id.charAt( element.id.length - 1 ) ).className='cellTableCell cellTableFirstColumn ' + tableClass;");
        out.println("document.getElementById( prefix + 'cellTableCell_' + element.id.charAt( element.id.length - 1 ) ).className='cellTableCell ' + tableClass;");
        out.println("document.getElementById( prefix + 'cellTableLastCell_' + element.id.charAt( element.id.length - 1 ) ).className='cellTableCell cellTableLastColumn ' + tableClass;");
        out.println("}");
        out.println("}");
        out.println("}");
        // Onclick function for closing message dialog-->make it hidden
        out.println("function closeMessageDialog( refresh ) {");
        out.println("  document.getElementById( \"messageDialogBackdrop\" ).style.visibility = 'hidden';");
        out.println("  document.getElementById( \"messageDialog\" ).style.visibility = 'hidden';");
        out.println("  if( refresh ) {");
        out.println("    window.location.reload();");
        out.println("  }");
        out.println("}");
        // Function to open the message dialog--> make it visible
        out.println("function openMessageDialog( title, body, single ) {");
        out.println("  document.getElementById( \"messageDialogBackdrop\" ).style.visibility = 'visible';");
        out.println("  document.getElementById( \"messageDialog\" ).style.visibility = 'visible';");
        out.println("  document.getElementById( \"messageDialogTitle\" ).innerHTML = title;");
        out.println("  document.getElementById( \"messageDialogBody\" ).innerHTML = body;");
        out.println("  if( single ) {");
        out.println("    document.getElementById( \"singleButton\" ).style.display = 'block';");
        out.println("    document.getElementById( \"doubleButton\" ).style.display = 'none';");
        out.println("  } else {");
        out.println("    document.getElementById( \"singleButton\" ).style.display = 'none';");
        out.println("    document.getElementById( \"doubleButton\" ).style.display = 'block';");
        out.println("  }");
        out.println("}");
        // Function to remove selected pipeline/workflow after user confirms
        out.println("function removeSelection() {");
        out.println("  if( removeElement !== null ) {");
        out.println("    if( removeElement.id.startsWith( 'j-' ) && selectedWorkflowRowIndex != -1 ) {");
        out.println(setupAjaxCall(setupJobURI(convertContextPath(RemoveWorkflowServlet.CONTEXT_PATH)), BaseMessages.getString(PKG, "GetStatusServlet.RemoveWorkflow.Title"), "'" + BaseMessages.getString(PKG, "GetStatusServlet.TheWorkflow.Label") + " ' + selectedWorkflowName + ' " + BaseMessages.getString(PKG, "GetStatusServlet.RemoveWorkflow.Success.Body") + "'", "'" + BaseMessages.getString(PKG, "GetStatusServlet.TheWorkflow.Label") + " ' + selectedWorkflowName + ' " + BaseMessages.getString(PKG, "GetStatusServlet.RemoveWorkflow.Failure.Body") + "'"));
        out.println("} else if ( selectedPipelineRowIndex != -1 ) {");
        out.println(setupAjaxCall(setupPipelineURI(convertContextPath(RemovePipelineServlet.CONTEXT_PATH)), BaseMessages.getString(PKG, "GetStatusServlet.RemovePipeline.Title"), "'" + BaseMessages.getString(PKG, "GetStatusServlet.ThePipeline.Label") + " ' + selectedPipelineName + ' " + BaseMessages.getString(PKG, "GetStatusServlet.RemovePipeline.Success.Body") + "'", "'" + BaseMessages.getString(PKG, "GetStatusServlet.ThePipeline.Label") + " ' + selectedPipelineName + ' " + BaseMessages.getString(PKG, "GetStatusServlet.RemovePipeline.Failure.Body") + "'"));
        out.println("    }");
        out.println("  }");
        out.println("}");
        out.println("function getRowNum( id ) {");
        out.println("  return id.substring( id.indexOf('_') + 1, id.length);");
        out.println("}");
        out.println("</script>");
        out.println("</BODY>");
        out.println("</HTML>");
    }
}
Also used : PrintWriter(java.io.PrintWriter) HopServerServlet(org.apache.hop.core.annotations.HopServerServlet) RuntimeMXBean(java.lang.management.RuntimeMXBean) BaseMessages(org.apache.hop.i18n.BaseMessages) ServletException(javax.servlet.ServletException) XmlHandler(org.apache.hop.core.xml.XmlHandler) Date(java.util.Date) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) HopException(org.apache.hop.core.exception.HopException) WorkflowMeta(org.apache.hop.workflow.WorkflowMeta) HttpServletResponse(javax.servlet.http.HttpServletResponse) IOException(java.io.IOException) ThreadMXBean(java.lang.management.ThreadMXBean) Const(org.apache.hop.core.Const) IPipelineEngine(org.apache.hop.pipeline.engine.IPipelineEngine) HttpServletRequest(javax.servlet.http.HttpServletRequest) List(java.util.List) IWorkflowEngine(org.apache.hop.workflow.engine.IWorkflowEngine) OperatingSystemMXBean(java.lang.management.OperatingSystemMXBean) Comparator(java.util.Comparator) PipelineMeta(org.apache.hop.pipeline.PipelineMeta) Collections(java.util.Collections) HopException(org.apache.hop.core.exception.HopException) Date(java.util.Date) ServletException(javax.servlet.ServletException) HopException(org.apache.hop.core.exception.HopException) IOException(java.io.IOException) PipelineMeta(org.apache.hop.pipeline.PipelineMeta) WorkflowMeta(org.apache.hop.workflow.WorkflowMeta) ServletException(javax.servlet.ServletException) IWorkflowEngine(org.apache.hop.workflow.engine.IWorkflowEngine) IPipelineEngine(org.apache.hop.pipeline.engine.IPipelineEngine) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) PrintWriter(java.io.PrintWriter)

Example 4 with IPipelineEngine

use of org.apache.hop.pipeline.engine.IPipelineEngine in project hop by apache.

the class PipelineResource method addPipeline.

@PUT
@Path("/add")
@Produces({ MediaType.APPLICATION_JSON })
public PipelineStatus addPipeline(String xml) {
    PipelineConfiguration pipelineConfiguration;
    try {
        pipelineConfiguration = PipelineConfiguration.fromXml(xml.toString());
        IHopMetadataProvider metadataProvider = new MultiMetadataProvider(HopServerSingleton.getHopServer().getVariables(), HopServerSingleton.getHopServer().getConfig().getMetadataProvider(), pipelineConfiguration.getMetadataProvider());
        PipelineMeta pipelineMeta = pipelineConfiguration.getPipelineMeta();
        ILogChannel log = HopServerSingleton.getInstance().getLog();
        if (log.isDetailed()) {
            log.logDetailed("Logging level set to " + log.getLogLevel().getDescription());
        }
        PipelineExecutionConfiguration executionConfiguration = pipelineConfiguration.getPipelineExecutionConfiguration();
        String serverObjectId = UUID.randomUUID().toString();
        SimpleLoggingObject servletLoggingObject = new SimpleLoggingObject(getClass().getName(), LoggingObjectType.HOP_SERVER, null);
        servletLoggingObject.setContainerObjectId(serverObjectId);
        servletLoggingObject.setLogLevel(executionConfiguration.getLogLevel());
        // Create the pipeline and store in the list...
        // 
        String runConfigurationName = executionConfiguration.getRunConfiguration();
        // TODO: configure
        IVariables variables = Variables.getADefaultVariableSpace();
        final IPipelineEngine pipeline = PipelineEngineFactory.createPipelineEngine(variables, runConfigurationName, metadataProvider, pipelineMeta);
        pipeline.setParent(servletLoggingObject);
        HopServerSingleton.getInstance().getPipelineMap().addPipeline(pipelineMeta.getName(), serverObjectId, pipeline, pipelineConfiguration);
        pipeline.setContainerId(serverObjectId);
        return getPipelineStatus(serverObjectId);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}
Also used : ILogChannel(org.apache.hop.core.logging.ILogChannel) IVariables(org.apache.hop.core.variables.IVariables) IHopMetadataProvider(org.apache.hop.metadata.api.IHopMetadataProvider) PipelineConfiguration(org.apache.hop.pipeline.PipelineConfiguration) PipelineExecutionConfiguration(org.apache.hop.pipeline.PipelineExecutionConfiguration) SimpleLoggingObject(org.apache.hop.core.logging.SimpleLoggingObject) IPipelineEngine(org.apache.hop.pipeline.engine.IPipelineEngine) HopException(org.apache.hop.core.exception.HopException) MultiMetadataProvider(org.apache.hop.metadata.serializer.multi.MultiMetadataProvider) PipelineMeta(org.apache.hop.pipeline.PipelineMeta)

Example 5 with IPipelineEngine

use of org.apache.hop.pipeline.engine.IPipelineEngine in project hop by apache.

the class ScriptValuesAddedFunctions method setVariable.

public static void setVariable(Context actualContext, Scriptable actualObject, Object[] arguments, Function functionContext) {
    if (arguments.length != 3) {
        throw Context.reportRuntimeError("The function call setVariable requires 3 arguments.");
    }
    Object transformObject = Context.jsToJava(actualObject.get("_transform_", actualObject), ITransform.class);
    if (transformObject instanceof ITransform) {
        ITransform transform = (ITransform) transformObject;
        IPipelineEngine pipeline = transform.getPipeline();
        final String variableName = Context.toString(arguments[0]);
        final String variableValue = Context.toString(arguments[1]);
        final VariableScope variableScope = getVariableScope(Context.toString(arguments[2]));
        // Set variable in transform's scope so that it can be retrieved in the same transform using
        // getVariable
        transform.setVariable(variableName, variableValue);
        switch(variableScope) {
            case PARENT:
                setParentScopeVariable(pipeline, variableName, variableValue);
                break;
            case GRAND_PARENT:
                setGrandParentScopeVariable(pipeline, variableName, variableValue);
                break;
            case ROOT:
                setRootScopeVariable(pipeline, variableName, variableValue);
                break;
            case SYSTEM:
                setSystemScopeVariable(pipeline, variableName, variableValue);
                break;
        }
    }
}
Also used : ITransform(org.apache.hop.pipeline.transform.ITransform) FileObject(org.apache.commons.vfs2.FileObject) IPipelineEngine(org.apache.hop.pipeline.engine.IPipelineEngine)

Aggregations

IPipelineEngine (org.apache.hop.pipeline.engine.IPipelineEngine)6 HopException (org.apache.hop.core.exception.HopException)5 IVariables (org.apache.hop.core.variables.IVariables)4 PipelineMeta (org.apache.hop.pipeline.PipelineMeta)4 List (java.util.List)2 Const (org.apache.hop.core.Const)2 Result (org.apache.hop.core.Result)2 ILogChannel (org.apache.hop.core.logging.ILogChannel)2 IHopMetadataProvider (org.apache.hop.metadata.api.IHopMetadataProvider)2 Pipeline (org.apache.hop.pipeline.Pipeline)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 IOException (java.io.IOException)1 PrintWriter (java.io.PrintWriter)1 OperatingSystemMXBean (java.lang.management.OperatingSystemMXBean)1 RuntimeMXBean (java.lang.management.RuntimeMXBean)1 ThreadMXBean (java.lang.management.ThreadMXBean)1 SimpleDateFormat (java.text.SimpleDateFormat)1 java.util (java.util)1 ArrayList (java.util.ArrayList)1 Collections (java.util.Collections)1