mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 21:20:45 +00:00
Merge pull request #35 from Kingsrook/feature/CE-548-script-writer-dev-setup-intelli-j-ide-local-ide-unit-testing
Feature/ce 548 script writer dev setup intelli j ide local ide unit testing
This commit is contained in:
@ -231,7 +231,19 @@ public class ExecuteCodeAction
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static void addApiUtilityToContext(Map<String, Serializable> context, ScriptRevision scriptRevision)
|
public static void addApiUtilityToContext(Map<String, Serializable> context, ScriptRevision scriptRevision)
|
||||||
{
|
{
|
||||||
if(!StringUtils.hasContent(scriptRevision.getApiName()) || !StringUtils.hasContent(scriptRevision.getApiVersion()))
|
addApiUtilityToContext(context, scriptRevision.getApiName(), scriptRevision.getApiVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Try to (dynamically) load the ApiScriptUtils object from the api middleware
|
||||||
|
** module -- in case the runtime doesn't have that module deployed (e.g, not in
|
||||||
|
** the project pom).
|
||||||
|
*******************************************************************************/
|
||||||
|
public static void addApiUtilityToContext(Map<String, Serializable> context, String apiName, String apiVersion)
|
||||||
|
{
|
||||||
|
if(!StringUtils.hasContent(apiName) || !StringUtils.hasContent(apiVersion))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -239,7 +251,7 @@ public class ExecuteCodeAction
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Class<?> apiScriptUtilsClass = Class.forName("com.kingsrook.qqq.api.utils.ApiScriptUtils");
|
Class<?> apiScriptUtilsClass = Class.forName("com.kingsrook.qqq.api.utils.ApiScriptUtils");
|
||||||
Object apiScriptUtilsObject = apiScriptUtilsClass.getConstructor(String.class, String.class).newInstance(scriptRevision.getApiName(), scriptRevision.getApiVersion());
|
Object apiScriptUtilsObject = apiScriptUtilsClass.getConstructor(String.class, String.class).newInstance(apiName, apiVersion);
|
||||||
context.put("api", (Serializable) apiScriptUtilsObject);
|
context.put("api", (Serializable) apiScriptUtilsObject);
|
||||||
}
|
}
|
||||||
catch(ClassNotFoundException e)
|
catch(ClassNotFoundException e)
|
||||||
|
@ -41,6 +41,7 @@ public class Log4jCodeExecutionLogger implements QCodeExecutionLoggerInterface
|
|||||||
private QCodeReference qCodeReference;
|
private QCodeReference qCodeReference;
|
||||||
private String uuid = UUID.randomUUID().toString();
|
private String uuid = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
private boolean includeUUID = true;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -52,7 +53,7 @@ public class Log4jCodeExecutionLogger implements QCodeExecutionLoggerInterface
|
|||||||
this.qCodeReference = executeCodeInput.getCodeReference();
|
this.qCodeReference = executeCodeInput.getCodeReference();
|
||||||
|
|
||||||
String inputString = StringUtils.safeTruncate(ValueUtils.getValueAsString(executeCodeInput.getInput()), 250, "...");
|
String inputString = StringUtils.safeTruncate(ValueUtils.getValueAsString(executeCodeInput.getInput()), 250, "...");
|
||||||
LOG.info("Starting script execution: " + qCodeReference.getName() + ", uuid: " + uuid + ", with input: " + inputString);
|
LOG.info("Starting script execution: " + qCodeReference.getName() + (includeUUID ? ", uuid: " + uuid : "") + ", with input: " + inputString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -63,7 +64,7 @@ public class Log4jCodeExecutionLogger implements QCodeExecutionLoggerInterface
|
|||||||
@Override
|
@Override
|
||||||
public void acceptLogLine(String logLine)
|
public void acceptLogLine(String logLine)
|
||||||
{
|
{
|
||||||
LOG.info("Script log: " + uuid + ": " + logLine);
|
LOG.info("Script log: " + (includeUUID ? uuid + ": " : "") + logLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -74,7 +75,7 @@ public class Log4jCodeExecutionLogger implements QCodeExecutionLoggerInterface
|
|||||||
@Override
|
@Override
|
||||||
public void acceptException(Exception exception)
|
public void acceptException(Exception exception)
|
||||||
{
|
{
|
||||||
LOG.info("Script Exception: " + uuid, exception);
|
LOG.info("Script Exception: " + (includeUUID ? uuid : ""), exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -86,7 +87,38 @@ public class Log4jCodeExecutionLogger implements QCodeExecutionLoggerInterface
|
|||||||
public void acceptExecutionEnd(Serializable output)
|
public void acceptExecutionEnd(Serializable output)
|
||||||
{
|
{
|
||||||
String outputString = StringUtils.safeTruncate(ValueUtils.getValueAsString(output), 250, "...");
|
String outputString = StringUtils.safeTruncate(ValueUtils.getValueAsString(output), 250, "...");
|
||||||
LOG.info("Finished script execution: " + qCodeReference.getName() + ", uuid: " + uuid + ", with output: " + outputString);
|
LOG.info("Finished script execution: " + qCodeReference.getName() + (includeUUID ? ", uuid: " + uuid : "") + ", with output: " + outputString);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for includeUUID
|
||||||
|
*******************************************************************************/
|
||||||
|
public boolean getIncludeUUID()
|
||||||
|
{
|
||||||
|
return (this.includeUUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for includeUUID
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setIncludeUUID(boolean includeUUID)
|
||||||
|
{
|
||||||
|
this.includeUUID = includeUUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for includeUUID
|
||||||
|
*******************************************************************************/
|
||||||
|
public Log4jCodeExecutionLogger withIncludeUUID(boolean includeUUID)
|
||||||
|
{
|
||||||
|
this.includeUUID = includeUUID;
|
||||||
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2022. Kingsrook, LLC
|
||||||
|
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||||
|
* contact@kingsrook.com
|
||||||
|
* https://github.com/Kingsrook/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.actions.scripts.logging;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.actions.scripts.ExecuteCodeInput;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Implementation of a code execution logger that logs to System.out and
|
||||||
|
** System.err (for exceptions)
|
||||||
|
*******************************************************************************/
|
||||||
|
public class SystemOutExecutionLogger implements QCodeExecutionLoggerInterface
|
||||||
|
{
|
||||||
|
private QCodeReference qCodeReference;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Override
|
||||||
|
public void acceptExecutionStart(ExecuteCodeInput executeCodeInput)
|
||||||
|
{
|
||||||
|
this.qCodeReference = executeCodeInput.getCodeReference();
|
||||||
|
|
||||||
|
String inputString = ValueUtils.getValueAsString(executeCodeInput.getInput());
|
||||||
|
System.out.println("Starting script execution: " + qCodeReference.getName() + ", with input: " + inputString);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Override
|
||||||
|
public void acceptLogLine(String logLine)
|
||||||
|
{
|
||||||
|
System.out.println("Script log: " + logLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Override
|
||||||
|
public void acceptException(Exception exception)
|
||||||
|
{
|
||||||
|
System.out.println("Script Exception: " + exception.getMessage());
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Override
|
||||||
|
public void acceptExecutionEnd(Serializable output)
|
||||||
|
{
|
||||||
|
String outputString = ValueUtils.getValueAsString(output);
|
||||||
|
System.out.println("Finished script execution: " + qCodeReference.getName() + ", with output: " + outputString);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -159,6 +159,15 @@ public class StoreScriptRevisionProcessStep implements BackendStep
|
|||||||
.toQRecord());
|
.toQRecord());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(StringUtils.hasContent(input.getValueString("contents")))
|
||||||
|
{
|
||||||
|
scriptRevisionFileRecords = new ArrayList<>();
|
||||||
|
scriptRevisionFileRecords.add(new ScriptRevisionFile()
|
||||||
|
.withScriptRevisionId(scriptRevisionId)
|
||||||
|
.withFileName("Script.js")
|
||||||
|
.withContents(input.getValueString("contents"))
|
||||||
|
.toQRecord());
|
||||||
|
}
|
||||||
|
|
||||||
if(CollectionUtils.nullSafeHasContents(scriptRevisionFileRecords))
|
if(CollectionUtils.nullSafeHasContents(scriptRevisionFileRecords))
|
||||||
{
|
{
|
||||||
|
@ -31,6 +31,7 @@ import com.kingsrook.qqq.backend.core.actions.scripts.logging.Log4jCodeExecution
|
|||||||
import com.kingsrook.qqq.backend.core.actions.scripts.logging.NoopCodeExecutionLogger;
|
import com.kingsrook.qqq.backend.core.actions.scripts.logging.NoopCodeExecutionLogger;
|
||||||
import com.kingsrook.qqq.backend.core.actions.scripts.logging.QCodeExecutionLoggerInterface;
|
import com.kingsrook.qqq.backend.core.actions.scripts.logging.QCodeExecutionLoggerInterface;
|
||||||
import com.kingsrook.qqq.backend.core.actions.scripts.logging.StoreScriptLogAndScriptLogLineExecutionLogger;
|
import com.kingsrook.qqq.backend.core.actions.scripts.logging.StoreScriptLogAndScriptLogLineExecutionLogger;
|
||||||
|
import com.kingsrook.qqq.backend.core.actions.scripts.logging.SystemOutExecutionLogger;
|
||||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QCodeException;
|
import com.kingsrook.qqq.backend.core.exceptions.QCodeException;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
@ -112,6 +113,21 @@ class ExecuteCodeActionTest extends BaseTest
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testSystemOutLogger() throws QException
|
||||||
|
{
|
||||||
|
QInstance qInstance = QContext.getQInstance();
|
||||||
|
ExecuteCodeInput executeCodeInput = setupInput(qInstance, Map.of("x", 4), new SystemOutExecutionLogger());
|
||||||
|
ExecuteCodeOutput executeCodeOutput = new ExecuteCodeOutput();
|
||||||
|
new ExecuteCodeAction().run(executeCodeInput, executeCodeOutput);
|
||||||
|
assertEquals(16, executeCodeOutput.getOutput());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -986,9 +986,16 @@ public class ApiImplementation
|
|||||||
{
|
{
|
||||||
String[] ids = paramMap.get(idParam).split(",");
|
String[] ids = paramMap.get(idParam).split(",");
|
||||||
|
|
||||||
QTableMetaData table = QContext.getQInstance().getTable(process.getTableName());
|
if(StringUtils.hasContent(process.getTableName()))
|
||||||
QQueryFilter filter = new QQueryFilter(new QFilterCriteria(table.getPrimaryKeyField(), IN, Arrays.asList(ids)));
|
{
|
||||||
runProcessInput.setCallback(getCallback(filter));
|
QTableMetaData table = QContext.getQInstance().getTable(process.getTableName());
|
||||||
|
QQueryFilter filter = new QQueryFilter(new QFilterCriteria(table.getPrimaryKeyField(), IN, Arrays.asList(ids)));
|
||||||
|
runProcessInput.setCallback(getProcessCallback(filter));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
runProcessInput.addValue(idParam, paramMap.get(idParam));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1517,7 +1524,7 @@ public class ApiImplementation
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
private static QProcessCallback getCallback(QQueryFilter filter)
|
public static QProcessCallback getProcessCallback(QQueryFilter filter)
|
||||||
{
|
{
|
||||||
return new QProcessCallback()
|
return new QProcessCallback()
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user