Skip to content

Commit

Permalink
Added support for loading data on start with entity_on_start_load_typ…
Browse files Browse the repository at this point in the history
…es and entity_on_start_load_components properties/env-vars
  • Loading branch information
jonesde committed Jun 14, 2023
1 parent 0a06a90 commit 9bd047b
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -699,70 +699,112 @@ class ExecutionContextFactoryImpl implements ExecutionContextFactory {
logger.info("Initialized ClassLoaders in ${System.currentTimeMillis() - startTime}ms")
}

/** Called from MoquiContextListener.contextInitialized after ECFI init */
@Override boolean checkEmptyDb() {
/* NOTE: Called from Moqui.dynamicInit() after ECFI init (which is also called from MoquiContextListener.contextInitialized()) */
MNode toolsNode = confXmlRoot.first("tools")
toolsNode.setSystemExpandAttributes(true)

boolean needsRestartEcfi = false
boolean emptyDbLoadRan = false

// if empty-db-load has a value and is not 'none' then load those
String emptyDbLoad = toolsNode.attribute("empty-db-load")
if (!emptyDbLoad || emptyDbLoad == 'none') return false
if (emptyDbLoad && emptyDbLoad != 'none') {
long enumCount = getEntity().find("moqui.basic.Enumeration").disableAuthz().count()
if (enumCount == 0) {
logger.info("Found ${enumCount} Enumeration records, loading empty-db-load data types (${emptyDbLoad})")

ExecutionContext ec = getExecutionContext()
try {
ec.getArtifactExecution().disableAuthz()
ec.getArtifactExecution().push("loadDataEmptyDb", ArtifactExecutionInfo.AT_OTHER, ArtifactExecutionInfo.AUTHZA_ALL, false)
ec.getArtifactExecution().setAnonymousAuthorizedAll()
ec.getUser().loginAnonymousIfNoUser()

EntityDataLoader edl = ec.getEntity().makeDataLoader()
if (emptyDbLoad != 'all') edl.dataTypes(new HashSet(emptyDbLoad.split(",") as List))

try {
long startTime = System.currentTimeMillis()
long records = edl.load()

long enumCount = getEntity().find("moqui.basic.Enumeration").disableAuthz().count()
if (enumCount == 0) {
logger.info("Found ${enumCount} Enumeration records, loading empty-db-load data types (${emptyDbLoad})")
logger.info("Loaded [${records}] records (with types from empty-db-load: ${emptyDbLoad}) in ${(System.currentTimeMillis() - startTime)/1000} seconds.")
} catch (Throwable t) {
logger.error("Error loading empty DB data (with types: ${emptyDbLoad})", t)
}

} finally {
ec.destroy()
}

needsRestartEcfi = true
emptyDbLoadRan = true
} else {
logger.info("Found ${enumCount} Enumeration records, NOT loading empty-db-load data types (${emptyDbLoad})")
}
}

// if on-start-load-types has a value and is not 'none' then load those
String onStartLoadTypes = toolsNode.attribute("on-start-load-types")
String onStartLoadComponents = toolsNode.attribute("on-start-load-components")
if (!emptyDbLoadRan && onStartLoadTypes && onStartLoadTypes != 'none') {
logger.info("Loading on-start-load-types data types [${onStartLoadTypes}] and components [${onStartLoadComponents ?: 'all'}]")

ExecutionContext ec = getExecutionContext()
try {
ec.getArtifactExecution().disableAuthz()
ec.getArtifactExecution().push("loadData", ArtifactExecutionInfo.AT_OTHER, ArtifactExecutionInfo.AUTHZA_ALL, false)
ec.getArtifactExecution().push("loadDataOnStart", ArtifactExecutionInfo.AT_OTHER, ArtifactExecutionInfo.AUTHZA_ALL, false)
ec.getArtifactExecution().setAnonymousAuthorizedAll()
ec.getUser().loginAnonymousIfNoUser()

EntityDataLoader edl = ec.getEntity().makeDataLoader()
if (emptyDbLoad != 'all') edl.dataTypes(new HashSet(emptyDbLoad.split(",") as List))
if (onStartLoadTypes != 'all') edl.dataTypes(new HashSet(onStartLoadTypes.split(",") as List))
if (onStartLoadComponents && onStartLoadComponents != 'all') edl.componentNameList(onStartLoadComponents.split(",") as List)

try {
long startTime = System.currentTimeMillis()
long records = edl.load()

logger.info("Loaded [${records}] records (with types: ${emptyDbLoad}) in ${(System.currentTimeMillis() - startTime)/1000} seconds.")
logger.info("Loaded [${records}] records (with types from on-start-load-types: [${onStartLoadTypes}] components: [${onStartLoadComponents ?: 'all'}]) in ${(System.currentTimeMillis() - startTime)/1000} seconds.")
} catch (Throwable t) {
logger.error("Error loading empty DB data (with types: ${emptyDbLoad})", t)
logger.error("Error loading on-start DB data (with types: [${onStartLoadTypes}] components: [${onStartLoadComponents ?: 'all'}])", t)
}

} finally {
ec.destroy()
}
return true
} else {
logger.info("Found ${enumCount} Enumeration records, NOT loading empty-db-load data types (${emptyDbLoad})")
// if this instance_purpose is test load type 'test' data
if ("test".equals(System.getProperty("instance_purpose"))) {
logger.warn("Loading 'test' type data (instance_purpose=test)")
ExecutionContext ec = getExecutionContext()
try {
ec.getArtifactExecution().disableAuthz()
ec.getArtifactExecution().push("loadData", ArtifactExecutionInfo.AT_OTHER, ArtifactExecutionInfo.AUTHZA_ALL, false)
ec.getArtifactExecution().setAnonymousAuthorizedAll()
ec.getUser().loginAnonymousIfNoUser()

EntityDataLoader edl = ec.getEntity().makeDataLoader()
edl.dataTypes(new HashSet(['test']))
needsRestartEcfi = true
}

try {
long startTime = System.currentTimeMillis()
long records = edl.load()
// if this instance_purpose is test load type 'test' data
if ("test".equals(System.getProperty("instance_purpose"))) {
logger.warn("Loading 'test' type data (because instance_purpose=test)")
ExecutionContext ec = getExecutionContext()
try {
ec.getArtifactExecution().disableAuthz()
ec.getArtifactExecution().push("loadDataTest", ArtifactExecutionInfo.AT_OTHER, ArtifactExecutionInfo.AUTHZA_ALL, false)
ec.getArtifactExecution().setAnonymousAuthorizedAll()
ec.getUser().loginAnonymousIfNoUser()

logger.info("Loaded [${records}] records (with type test) in ${(System.currentTimeMillis() - startTime)/1000} seconds.")
} catch (Throwable t) {
logger.error("Error loading empty DB data (with type test)", t)
}
EntityDataLoader edl = ec.getEntity().makeDataLoader()
edl.dataTypes(new HashSet(['test']))

} finally {
ec.destroy()
try {
long startTime = System.currentTimeMillis()
long records = edl.load()

logger.info("Loaded [${records}] records (with type test) in ${(System.currentTimeMillis() - startTime)/1000} seconds.")
} catch (Throwable t) {
logger.error("Error loading empty DB data (with type test)", t)
}

} finally {
ec.destroy()
}
return false
}

return needsRestartEcfi
}

@Override void destroy() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ public interface ExecutionContextFactory {
/** Destroy the active Execution Context. When another is requested in this thread a new one will be created. */
void destroyActiveExecutionContext();

/** Called after construction but before registration with Moqui/Servlet, check for empty database and load configured data. */
/** Called after construction but before registration with Moqui/Servlet, check for empty database and load configured data.
* If empty-db-load is not done and on-start-load-types has a value handles that as well.
* Also loads type 'test' data if instance_purpose=test. */
boolean checkEmptyDb();
/** Destroy this ExecutionContextFactory and all resources it uses (all facades, tools, etc) */
void destroy();
Expand Down
6 changes: 5 additions & 1 deletion framework/src/main/resources/MoquiDefaultConf.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
<default-property name="entity_lock_track" value="false"/>
<default-property name="entity_statement_timeout" value="false"/>
<default-property name="entity_empty_db_load" value="seed,seed-initial,install"/>
<default-property name="entity_on_start_load_types" value="none"/>
<default-property name="entity_on_start_load_components" value=""/>

<!-- Properties for a database clone; note that without overriding the transactional#clone1 datasource the default works only
with MySQL and Postgres because of different properties on XADataSource classes of other JDBC drivers -->
Expand All @@ -81,7 +83,9 @@
<default-property name="kibana_host" value="127.0.0.1"/>
<default-property name="kibana_port" value="5601"/>

<tools empty-db-load="${entity_empty_db_load}" worker-queue="65535" worker-pool-core="16" worker-pool-max="32" worker-pool-alive="60">
<tools worker-queue="65535" worker-pool-core="16" worker-pool-max="32" worker-pool-alive="60"
empty-db-load="${entity_empty_db_load}"
on-start-load-types="${entity_on_start_load_types}" on-start-load-components="${entity_on_start_load_components}">
<tool-factory class="org.moqui.impl.tools.MCacheToolFactory" init-priority="03" disabled="false"/>
<!-- Apache Commons JCS, an alternative for distributed caches (cannot be used as local cache as requires Serializable keys/values just like Hazelcast) -->
<!-- <tool-factory class="org.moqui.impl.tools.JCSCacheToolFactory" init-priority="09" disabled="true"/> -->
Expand Down
8 changes: 8 additions & 0 deletions framework/xsd/moqui-conf-3.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ along with this software (see the LICENSE.md file). If not, see
table for moqui.basic.Enumeration). Empty or 'none' means load nothing, use 'all' to load all found
data files regardless of type.</xs:documentation></xs:annotation>
</xs:attribute>
<xs:attribute name="on-start-load-types" type="xs:string"><xs:annotation><xs:documentation>
Comma-separated list of data file types to load on start. Empty or 'none' means load nothing.
Does not run if empty-db-load runs.</xs:documentation></xs:annotation>
</xs:attribute>
<xs:attribute name="on-start-load-components" type="xs:string"><xs:annotation><xs:documentation>
Comma-separated list of component names to load on start, used with on-start-load-types.
Does not run if empty-db-load runs.</xs:documentation></xs:annotation>
</xs:attribute>
<xs:attribute name="worker-queue" type="xs:integer"><xs:annotation><xs:documentation>
The maximum size of the worker queue.</xs:documentation></xs:annotation></xs:attribute>
<xs:attribute name="worker-pool-core" type="xs:integer"><xs:annotation><xs:documentation>
Expand Down

0 comments on commit 9bd047b

Please sign in to comment.