Merged dev into feature/meta-data-loaders

This commit is contained in:
2025-01-17 19:12:48 -06:00
14 changed files with 159 additions and 135 deletions

View File

@ -127,14 +127,9 @@ commands:
command: |
cd docs
asciidoctor -a docinfo=shared index.adoc
upload_docs_site:
steps:
- run:
name: scp html to justinsgotskinnylegs.com
command: |
cd docs
scp index.html dkelkhoff@45.79.44.221:/mnt/first-volume/dkelkhoff/nginx/html/justinsgotskinnylegs.com/qqq-docs.html
- store_artifacts:
path: docs/index.html
when: always
jobs:
mvn_test:
@ -159,7 +154,6 @@ jobs:
steps:
- install_asciidoctor
- run_asciidoctor
- upload_docs_site
workflows:
test_only:

View File

@ -147,8 +147,8 @@ public class BackendMetaDataProvider
As the size of your application grows, if you're doing per-object meta-data providers, you may find it
burdensome, when adding a new object to your instance, to have to write code for it in two places -
that is - a new class to produce that meta-data object, AND a single line of code to add that object
to your `QInstance`. As such, a mechanism to avoid that line-of-code to add the object to the
`QInstance` exists.
to your `QInstance`. As such, a mechanism exists to let you avoid that line-of-code for adding the object
to the `QInstance`.
This mechanism involves adding the `MetaDataProducerInterface` to all of your classes that produce a
meta-data object. This interface is generic, with a type parameter that will typically be the type of
@ -204,7 +204,7 @@ that are all related, and it's only a handful of lines of code for each one, may
produce them all in the same class. Or maybe when you define a table, you'd like to define its
joins and widgets at the same time.
This approach can be accomplished by making your `MetaDataProducerInterface`'s type argument by
This approach can be accomplished by making the type argument for your `MetaDataProducerInterface` be
`MetaDataProducerMultiOutput` - a simple class that just wraps a list of other `MetaDataProducerOutput`
objects.
@ -238,12 +238,13 @@ be specified in their meta-data object.
At the same time, if you're writing any custom code in your QQQ application
(e.g., any processes or table customizers), where you're working with records from tables, you may
prefer being able to work with entity beans (e.g., java classes with typed getter & setter methods),
rather than the default object type that QQQ's ORM actions return, the `QRecord`, which carriers all
of its values in a `Map`. QQQ has a mechanism for dealing with this - in the form of the `QRecordEntity`
class.
rather than the default object type that QQQ's ORM actions return, the `QRecord`, which carries all
of its values in a `Map` (where you don't get compile-time checks of field names or data types).
QQQ has a mechanism for dealing with this - in the form of the `QRecordEntity` class.
So - if you want to build your application using entity beans (which is recommended, for the compile-time
safety that they provide in custom code), you will be writing a `QRecordEntity` class, which will look like:
safety that they provide in custom code), you will be writing a `QRecordEntity` class for each of your tables,
which will look like:
[source,java]
.QRecordEntity example
@ -280,7 +281,7 @@ public QTableMetaData produce(QInstance qInstance) throws QExcpetion
----
That `withFieldsFromEntity` call is one of the biggest benefits of this technique. It allows you to avoid defining
all of the field in you table in two place (the entity and the table meta-data).
all of the fields in you table in two places (the entity and the table meta-data).
== MetaData Producing Annotations for Entities

View File

@ -186,7 +186,7 @@ public class AsyncRecordPipeLoop
if(recordCount > 0)
{
LOG.info("End of job summary", logPair("recordCount", recordCount), logPair("jobName", jobName), logPair("millis", endTime - jobStartTime), logPair("recordsPerSecond", 1000d * (recordCount / (.001d + (endTime - jobStartTime)))));
LOG.debug("End of job summary", logPair("recordCount", recordCount), logPair("jobName", jobName), logPair("millis", endTime - jobStartTime), logPair("recordsPerSecond", 1000d * (recordCount / (.001d + (endTime - jobStartTime)))));
}
return (recordCount);

View File

@ -120,6 +120,16 @@ public enum QFieldType
/*******************************************************************************
**
*******************************************************************************/
public boolean isTemporal()
{
return this == QFieldType.DATE || this == QFieldType.DATE_TIME || this == QFieldType.TIME;
}
/*******************************************************************************
**
*******************************************************************************/

View File

@ -189,7 +189,7 @@ public class StreamedETLExecuteStep extends BaseStreamedETLStep implements Backe
if(recordCount > 0)
{
LOG.info("Processed [" + recordCount + "] records.");
LOG.debug("Processed [" + recordCount + "] records.");
}
//////////////////////////////////////////////////////////////////////////////

View File

@ -223,7 +223,7 @@ public abstract class AbstractTableSyncTransformStep extends AbstractTransformSt
{
if(CollectionUtils.nullSafeIsEmpty(runBackendStepInput.getRecords()))
{
LOG.info("No input records were found.");
LOG.debug("No input records were found.");
return;
}

View File

@ -159,6 +159,10 @@ public class RDBMSAggregateAction extends AbstractRDBMSAction implements Aggrega
{
fieldType = QFieldType.DECIMAL;
}
else if(field.getType().isTemporal() && (aggregate.getOperator().equals(AggregateOperator.COUNT)) || aggregate.getOperator().equals(AggregateOperator.COUNT_DISTINCT))
{
fieldType = QFieldType.INTEGER;
}
}
if(fieldType != null)

View File

@ -23,6 +23,7 @@ package com.kingsrook.qqq.backend.module.rdbms.actions;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
@ -42,13 +43,16 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterOrderBy;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryJoin;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType;
import com.kingsrook.qqq.backend.core.model.session.QSession;
import com.kingsrook.qqq.backend.core.utils.ExceptionUtils;
import com.kingsrook.qqq.backend.module.rdbms.TestUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
@ -83,20 +87,56 @@ public class RDBMSAggregateActionTest extends RDBMSActionTest
Aggregate averageOfDaysWorked = new Aggregate("daysWorked", AggregateOperator.AVG);
Aggregate maxAnnualSalary = new Aggregate("annualSalary", AggregateOperator.MAX);
Aggregate minFirstName = new Aggregate("firstName", AggregateOperator.MIN);
Aggregate countOfBirthDate = new Aggregate("birthDate", AggregateOperator.COUNT);
aggregateInput.withAggregate(countOfId);
aggregateInput.withAggregate(sumOfId);
aggregateInput.withAggregate(averageOfDaysWorked);
aggregateInput.withAggregate(maxAnnualSalary);
aggregateInput.withAggregate(minFirstName);
aggregateInput.withAggregate(countOfBirthDate);
AggregateOutput aggregateOutput = new RDBMSAggregateAction().execute(aggregateInput);
AggregateResult aggregateResult = aggregateOutput.getResults().get(0);
Assertions.assertEquals(5, aggregateResult.getAggregateValue(countOfId));
Assertions.assertEquals(15, aggregateResult.getAggregateValue(sumOfId));
Assertions.assertEquals(new BigDecimal("96.4"), aggregateResult.getAggregateValue(averageOfDaysWorked));
Assertions.assertEquals(new BigDecimal("1000000.00"), aggregateResult.getAggregateValue(maxAnnualSalary));
Assertions.assertEquals("Darin", aggregateResult.getAggregateValue(minFirstName));
assertEquals(5, aggregateResult.getAggregateValue(countOfId));
assertEquals(15, aggregateResult.getAggregateValue(sumOfId));
assertEquals(new BigDecimal("96.4"), aggregateResult.getAggregateValue(averageOfDaysWorked));
assertEquals(new BigDecimal("1000000.00"), aggregateResult.getAggregateValue(maxAnnualSalary));
assertEquals("Darin", aggregateResult.getAggregateValue(minFirstName));
assertEquals(4, aggregateResult.getAggregateValue(countOfBirthDate));
}
/*******************************************************************************
**
*******************************************************************************/
@Test
@Disabled("Interesting to see effects of all operators on all types, but failures are expected (e.g., avg(string), so not for CI.")
void testOperatorsCrossTypes()
{
List<String> failures = new ArrayList<>();
for(QFieldMetaData field : QContext.getQInstance().getTable(TestUtils.TABLE_NAME_PERSON).getFields().values())
{
for(AggregateOperator aggregateOperator : AggregateOperator.values())
{
try
{
AggregateInput aggregateInput = initAggregateRequest();
Aggregate aggregate = new Aggregate(field.getName(), aggregateOperator);
aggregateInput.withAggregate(aggregate);
AggregateOutput aggregateOutput = new RDBMSAggregateAction().execute(aggregateInput);
AggregateResult aggregateResult = aggregateOutput.getResults().get(0);
assertNotNull(aggregateResult.getAggregateValue(aggregate));
}
catch(Exception e)
{
failures.add(ExceptionUtils.getRootException(e).getMessage());
}
}
}
failures.forEach(System.out::println);
}
@ -123,11 +163,11 @@ public class RDBMSAggregateActionTest extends RDBMSActionTest
AggregateOutput aggregateOutput = new RDBMSAggregateAction().execute(aggregateInput);
AggregateResult aggregateResult = aggregateOutput.getResults().get(0);
Assertions.assertEquals(2, aggregateResult.getAggregateValue(countOfId));
Assertions.assertEquals(5, aggregateResult.getAggregateValue(sumOfId));
Assertions.assertEquals(new BigDecimal("62.0"), aggregateResult.getAggregateValue(averageOfDaysWorked));
Assertions.assertEquals(new BigDecimal("26000.00"), aggregateResult.getAggregateValue(maxAnnualSalary));
Assertions.assertEquals("James", aggregateResult.getAggregateValue(minFirstName));
assertEquals(2, aggregateResult.getAggregateValue(countOfId));
assertEquals(5, aggregateResult.getAggregateValue(sumOfId));
assertEquals(new BigDecimal("62.0"), aggregateResult.getAggregateValue(averageOfDaysWorked));
assertEquals(new BigDecimal("26000.00"), aggregateResult.getAggregateValue(maxAnnualSalary));
assertEquals("James", aggregateResult.getAggregateValue(minFirstName));
}
@ -156,15 +196,15 @@ public class RDBMSAggregateActionTest extends RDBMSActionTest
AggregateOutput aggregateOutput = new RDBMSAggregateAction().execute(aggregateInput);
{
AggregateResult aggregateResult = aggregateOutput.getResults().get(0);
Assertions.assertEquals("Chamberlain", aggregateResult.getGroupByValue(lastNameGroupBy));
Assertions.assertEquals(2, aggregateResult.getAggregateValue(countOfId));
Assertions.assertEquals(17, aggregateResult.getAggregateValue(sumOfDaysWorked));
assertEquals("Chamberlain", aggregateResult.getGroupByValue(lastNameGroupBy));
assertEquals(2, aggregateResult.getAggregateValue(countOfId));
assertEquals(17, aggregateResult.getAggregateValue(sumOfDaysWorked));
}
{
AggregateResult aggregateResult = aggregateOutput.getResults().get(1);
Assertions.assertEquals("Kelkhoff", aggregateResult.getGroupByValue(lastNameGroupBy));
Assertions.assertEquals(4, aggregateResult.getAggregateValue(countOfId));
Assertions.assertEquals(11364, aggregateResult.getAggregateValue(sumOfDaysWorked));
assertEquals("Kelkhoff", aggregateResult.getGroupByValue(lastNameGroupBy));
assertEquals(4, aggregateResult.getAggregateValue(countOfId));
assertEquals(11364, aggregateResult.getAggregateValue(sumOfDaysWorked));
}
}
@ -201,29 +241,29 @@ public class RDBMSAggregateActionTest extends RDBMSActionTest
AggregateResult aggregateResult;
aggregateResult = iterator.next();
Assertions.assertEquals("Chamberlain", aggregateResult.getGroupByValue(lastNameGroupBy));
Assertions.assertEquals("Donny", aggregateResult.getGroupByValue(firstNameGroupBy));
Assertions.assertEquals(1, aggregateResult.getAggregateValue(countOfId));
assertEquals("Chamberlain", aggregateResult.getGroupByValue(lastNameGroupBy));
assertEquals("Donny", aggregateResult.getGroupByValue(firstNameGroupBy));
assertEquals(1, aggregateResult.getAggregateValue(countOfId));
aggregateResult = iterator.next();
Assertions.assertEquals("Chamberlain", aggregateResult.getGroupByValue(lastNameGroupBy));
Assertions.assertEquals("Tim", aggregateResult.getGroupByValue(firstNameGroupBy));
Assertions.assertEquals(1, aggregateResult.getAggregateValue(countOfId));
assertEquals("Chamberlain", aggregateResult.getGroupByValue(lastNameGroupBy));
assertEquals("Tim", aggregateResult.getGroupByValue(firstNameGroupBy));
assertEquals(1, aggregateResult.getAggregateValue(countOfId));
aggregateResult = iterator.next();
Assertions.assertEquals("Kelkhoff", aggregateResult.getGroupByValue(lastNameGroupBy));
Assertions.assertEquals("Aaron", aggregateResult.getGroupByValue(firstNameGroupBy));
Assertions.assertEquals(1, aggregateResult.getAggregateValue(countOfId));
assertEquals("Kelkhoff", aggregateResult.getGroupByValue(lastNameGroupBy));
assertEquals("Aaron", aggregateResult.getGroupByValue(firstNameGroupBy));
assertEquals(1, aggregateResult.getAggregateValue(countOfId));
aggregateResult = iterator.next();
Assertions.assertEquals("Kelkhoff", aggregateResult.getGroupByValue(lastNameGroupBy));
Assertions.assertEquals("Darin", aggregateResult.getGroupByValue(firstNameGroupBy));
Assertions.assertEquals(2, aggregateResult.getAggregateValue(countOfId));
assertEquals("Kelkhoff", aggregateResult.getGroupByValue(lastNameGroupBy));
assertEquals("Darin", aggregateResult.getGroupByValue(firstNameGroupBy));
assertEquals(2, aggregateResult.getAggregateValue(countOfId));
aggregateResult = iterator.next();
Assertions.assertEquals("Kelkhoff", aggregateResult.getGroupByValue(lastNameGroupBy));
Assertions.assertEquals("Trevor", aggregateResult.getGroupByValue(firstNameGroupBy));
Assertions.assertEquals(1, aggregateResult.getAggregateValue(countOfId));
assertEquals("Kelkhoff", aggregateResult.getGroupByValue(lastNameGroupBy));
assertEquals("Trevor", aggregateResult.getGroupByValue(firstNameGroupBy));
assertEquals(1, aggregateResult.getAggregateValue(countOfId));
}
@ -255,24 +295,24 @@ public class RDBMSAggregateActionTest extends RDBMSActionTest
AggregateResult aggregateResult;
aggregateResult = iterator.next();
Assertions.assertEquals("Kelkhoff", aggregateResult.getGroupByValue(lastNameGroupBy));
Assertions.assertEquals(4, aggregateResult.getAggregateValue(countOfId));
assertEquals("Kelkhoff", aggregateResult.getGroupByValue(lastNameGroupBy));
assertEquals(4, aggregateResult.getAggregateValue(countOfId));
aggregateResult = iterator.next();
Assertions.assertEquals("Richardson", aggregateResult.getGroupByValue(lastNameGroupBy));
Assertions.assertEquals(1, aggregateResult.getAggregateValue(countOfId));
assertEquals("Richardson", aggregateResult.getGroupByValue(lastNameGroupBy));
assertEquals(1, aggregateResult.getAggregateValue(countOfId));
aggregateResult = iterator.next();
Assertions.assertEquals("Maes", aggregateResult.getGroupByValue(lastNameGroupBy));
Assertions.assertEquals(1, aggregateResult.getAggregateValue(countOfId));
assertEquals("Maes", aggregateResult.getGroupByValue(lastNameGroupBy));
assertEquals(1, aggregateResult.getAggregateValue(countOfId));
aggregateResult = iterator.next();
Assertions.assertEquals("Samples", aggregateResult.getGroupByValue(lastNameGroupBy));
Assertions.assertEquals(1, aggregateResult.getAggregateValue(countOfId));
assertEquals("Samples", aggregateResult.getGroupByValue(lastNameGroupBy));
assertEquals(1, aggregateResult.getAggregateValue(countOfId));
aggregateResult = iterator.next();
Assertions.assertEquals("Chamberlain", aggregateResult.getGroupByValue(lastNameGroupBy));
Assertions.assertEquals(2, aggregateResult.getAggregateValue(countOfId));
assertEquals("Chamberlain", aggregateResult.getGroupByValue(lastNameGroupBy));
assertEquals(2, aggregateResult.getAggregateValue(countOfId));
}
@ -293,7 +333,7 @@ public class RDBMSAggregateActionTest extends RDBMSActionTest
////////////////////////////////////////////////////////////
AggregateOutput aggregateOutput = new RDBMSAggregateAction().execute(aggregateInput);
AggregateResult aggregateResult = aggregateOutput.getResults().get(0);
Assertions.assertEquals(0, aggregateResult.getAggregateValue(countOfId));
assertEquals(0, aggregateResult.getAggregateValue(countOfId));
/////////////////////////////////////////////////////////////////////////////////////////
// but re-run w/ a group-by -- then, if no rows are found, there are 0 result objects. //
@ -324,12 +364,12 @@ public class RDBMSAggregateActionTest extends RDBMSActionTest
QContext.setQSession(new QSession().withSecurityKeyValue(TestUtils.SECURITY_KEY_STORE_ALL_ACCESS, true));
aggregateOutput = new RDBMSAggregateAction().execute(aggregateInput);
aggregateResult = aggregateOutput.getResults().get(0);
Assertions.assertEquals(43, aggregateResult.getAggregateValue(sumOfQuantity));
assertEquals(43, aggregateResult.getAggregateValue(sumOfQuantity));
QContext.setQSession(new QSession().withSecurityKeyValue(TestUtils.TABLE_NAME_STORE, 1));
aggregateOutput = new RDBMSAggregateAction().execute(aggregateInput);
aggregateResult = aggregateOutput.getResults().get(0);
Assertions.assertEquals(33, aggregateResult.getAggregateValue(sumOfQuantity));
assertEquals(33, aggregateResult.getAggregateValue(sumOfQuantity));
}

View File

@ -38,6 +38,7 @@ import com.kingsrook.qqq.middleware.javalin.specs.v1.MiddlewareVersionV1;
import io.javalin.Javalin;
import io.javalin.http.Context;
import org.apache.commons.lang.BooleanUtils;
import org.eclipse.jetty.util.resource.Resource;
/*******************************************************************************
@ -102,17 +103,23 @@ public class QApplicationJavalinServer
{
////////////////////////////////////////////////////////////////////////////////////////
// If you have any assets to add to the web server (e.g., logos, icons) place them at //
// src/main/resources/material-dashboard-overlay (or a directory of your choice //
// under src/main/resources) and use this line of code to tell javalin about it. //
// Make sure to add your app-specific directory to the javalin config before the core //
// material-dashboard directory, so in case the same file exists in both (e.g., //
// favicon.png), the app-specific one will be used. //
// src/main/resources/material-dashboard-overlay //
// we'll use the same check that javalin (jetty?) internally uses to see if this //
// directory exists - because if it doesn't, then it'll fail to start the server... //
// note that that Resource object is auto-closable, hence the try-with-resources //
////////////////////////////////////////////////////////////////////////////////////////
config.staticFiles.add("/material-dashboard-overlay");
try(Resource resource = Resource.newClassPathResource("/material-dashboard-overlay"))
{
if(resource !=null)
{
config.staticFiles.add("/material-dashboard-overlay");
}
}
/////////////////////////////////////////////////////////////////////
// tell javalin where to find material-dashboard static web assets //
/////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// tell javalin where to find material-dashboard static web assets //
// in this case, this path is coming from the qqq-frontend-material-dashboard jar //
////////////////////////////////////////////////////////////////////////////////////
config.staticFiles.add("/material-dashboard");
////////////////////////////////////////////////////////////

View File

@ -68,7 +68,7 @@
<dependency>
<groupId>com.kingsrook.qqq</groupId>
<artifactId>qqq-frontend-material-dashboard</artifactId>
<version>0.20.0</version>
<version>0.24.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
@ -119,12 +119,16 @@
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.kingsrook.sampleapp.SampleCli</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>

View File

@ -23,10 +23,8 @@ package com.kingsrook.sampleapp;
import com.kingsrook.qqq.backend.core.logging.QLogger;
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
import com.kingsrook.qqq.backend.javalin.QJavalinImplementation;
import com.kingsrook.qqq.middleware.javalin.QApplicationJavalinServer;
import com.kingsrook.sampleapp.metadata.SampleMetaDataProvider;
import io.javalin.Javalin;
/*******************************************************************************
@ -36,12 +34,6 @@ public class SampleJavalinServer
{
private static final QLogger LOG = QLogger.getLogger(SampleJavalinServer.class);
private static final int PORT = 8000;
private QInstance qInstance;
private Javalin javalinService;
/*******************************************************************************
@ -49,7 +41,7 @@ public class SampleJavalinServer
*******************************************************************************/
public static void main(String[] args)
{
new SampleJavalinServer().startJavalinServer();
new SampleJavalinServer().start();
}
@ -57,38 +49,11 @@ public class SampleJavalinServer
/*******************************************************************************
**
*******************************************************************************/
public void startJavalinServer()
public void start()
{
try
{
qInstance = SampleMetaDataProvider.defineInstance();
QJavalinImplementation qJavalinImplementation = new QJavalinImplementation(qInstance);
javalinService = Javalin.create(config ->
{
config.router.apiBuilder(qJavalinImplementation.getRoutes());
// todo - not all?
config.bundledPlugins.enableCors(cors -> cors.addRule(corsRule -> corsRule.anyHost()));
}).start(PORT);
/////////////////////////////////////////////////////////////////
// set the server to hot-swap the q instance before all routes //
/////////////////////////////////////////////////////////////////
QJavalinImplementation.setQInstanceHotSwapSupplier(() ->
{
try
{
return (SampleMetaDataProvider.defineInstance());
}
catch(Exception e)
{
LOG.warn("Error hot-swapping meta data", e);
return (null);
}
});
javalinService.before(QJavalinImplementation::hotSwapQInstance);
javalinService.after(ctx -> ctx.res().setHeader("Access-Control-Allow-Origin", "http://localhost:3000"));
new QApplicationJavalinServer(new SampleMetaDataProvider()).start();
}
catch(Exception e)
{
@ -96,16 +61,4 @@ public class SampleJavalinServer
}
}
/*******************************************************************************
**
*******************************************************************************/
public void stopJavalinServer()
{
if(javalinService != null)
{
javalinService.stop();
}
}
}

View File

@ -31,6 +31,7 @@ import com.kingsrook.qqq.backend.core.actions.dashboard.widgets.QuickSightChartR
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.exceptions.QValueException;
import com.kingsrook.qqq.backend.core.instances.AbstractQQQApplication;
import com.kingsrook.qqq.backend.core.instances.QInstanceEnricher;
import com.kingsrook.qqq.backend.core.instances.QMetaDataVariableInterpreter;
import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput;
@ -78,7 +79,7 @@ import com.kingsrook.sampleapp.processes.clonepeople.ClonePeopleTransformStep;
/*******************************************************************************
**
*******************************************************************************/
public class SampleMetaDataProvider
public class SampleMetaDataProvider extends AbstractQQQApplication
{
public static boolean USE_MYSQL = true;
@ -108,6 +109,17 @@ public class SampleMetaDataProvider
/***************************************************************************
**
***************************************************************************/
@Override
public QInstance defineQInstance() throws QException
{
return (defineInstance());
}
/*******************************************************************************
**
*******************************************************************************/
@ -145,7 +157,7 @@ public class SampleMetaDataProvider
private static void defineBranding(QInstance qInstance)
{
qInstance.setBranding(new QBrandingMetaData()
.withLogo("/kr-logo.png")
.withLogo("/samples-logo.png")
.withIcon("/kr-icon.png"));
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

View File

@ -38,8 +38,7 @@ class SampleJavalinServerTest
void testStartStop()
{
SampleJavalinServer sampleJavalinServer = new SampleJavalinServer();
sampleJavalinServer.startJavalinServer();
sampleJavalinServer.stopJavalinServer();
sampleJavalinServer.start();
}
}