package gw.api.startup
uses com.google.common.base.Stopwatch
uses com.guidewire.pl.system.dependency.ServerDependencies
uses com.guidewire.rating.flow.domain.util.CalcRoutineCodeGenerator
uses com.guidewire.rating.flow.domain.util.CalcRoutineCodeGeneratorFactory
uses com.guidewire.rating.flow.domain.util.CalcRoutineCodeGeneratorUtils
uses gw.api.startable.IStartablePlugin
uses gw.api.startable.StartablePluginCallbackHandler
uses gw.api.startable.StartablePluginState
uses gw.api.system.PCConfigParameters
uses gw.api.system.PCDependenciesGateway
uses gw.api.system.PCLoggerCategory
uses gw.lang.reflect.TypeSystem
uses gw.plugin.InitializablePlugin
uses gw.plugin.Plugins
uses gw.plugin.rateflow.RateBookPreloadPlugin
uses org.slf4j.Logger
uses java.io.File
uses java.nio.file.Path
uses java.nio.file.Paths
uses java.util.concurrent.Callable
uses java.util.concurrent.TimeUnit
uses java.util.concurrent.atomic.AtomicInteger
uses java.util.stream.Stream
/**
* A Startable plugin for experimental source code generation of CalcRoutines.
*
* Parameters:
*
* - Directory - the directory to write artifacts to
* - Compile - if true then the generated sources are also compiled
* - Strategy - {@link com.guidewire.rating.flow.domain.util.CalcRoutineCodeGeneratorFactory.CodegenStrategy code
* generation strategy}
*
*/
@SuppressWarnings("HiddenPackageReference")
class RateRoutineSourcesWriter implements IStartablePlugin, InitializablePlugin {
static final var DIRECTORY_PARAMETER_KEY = "Directory"
static final var COMPILE_PARAMETER_KEY = "Compile"
static final var CODEGEN_STRATEGY_PARAMETER_KEY = "Strategy"
static final var SOURCE_FILE_EXTENSION = ".gs"
static final var CLASS_FILE_EXTENSION = ".class"
static final var DEFAULT_DIRECTORY_PATH = CalcRoutineCodeGeneratorUtils.CompiledClassesDirectory
static final var GOSU_CLASS_LOADER = TypeSystem.GosuClassLoader
static final var _logger = PCLoggerCategory.RATEFLOW
var _directory = DEFAULT_DIRECTORY_PATH
var _policyLine : String = null
var _compile = false
var _state : StartablePluginState as readonly State = Stopped
@SuppressWarnings("unused")
var _routineCount: int as readonly RoutineCount = 0 // Used elsewhere via property name
@SuppressWarnings("unused")
var _processedCount: int as readonly ProcessedCount = 0 // Used elsewhere via property name
construct() {
}
construct(policyLine : String, directory : String, compile : boolean) {
_policyLine = policyLine
_directory = directory
_compile = compile
}
override function start(pluginCallbackHandler : StartablePluginCallbackHandler, serverStarting : boolean) {
write();
}
function write() {
_state = Started
writeSources()
}
function write(definitions: Collection) {
_state = Started
writeSources(definitions)
}
private function writeSources() {
com.guidewire.pc.domain.rating.RateTableDefinitionCacheImpl.init()
PCDependenciesGateway.RateTableDefinitionCache.start()
var activeRateBooks = allRateBooksToExportFor(_policyLine)
var definitions = new ArrayList()
activeRateBooks.forEach(\book -> definitions.addAll(book.RateBookCalcRoutines*.CalcRoutineDefinition.toList()))
writeSources(definitions)
}
private function writeSources(definitions: Collection) {
try {
_routineCount = definitions.size()
var stopwatch = Stopwatch.createStarted()
_logger.info("Writing rate routine generated sources to directory ${_directory} started")
var routineCount = new AtomicInteger(0)
var errorCount = new AtomicInteger(0)
var filesWritten = new AtomicInteger(0)
var stats = new RateRoutineStatistics()
var definitionsStream = definitions.stream()
if (PCConfigParameters.ParallelStreamsForRateRoutinesLoad.Value) {
definitionsStream = definitionsStream.parallel()
}
definitionsStream.forEach(\definition -> {
if (_state == Stopped) {
return
}
routineCount.incrementAndGet()
try {
var sourceCodeWriter = new CalcRoutineSourceCodeWriterCallable(definition, _directory, _compile)
filesWritten.addAndGet(sourceCodeWriter.call().size())
stats.update(definition, sourceCodeWriter.CodeGenerator)
} catch (ex : Exception) {
_logger.warn("Error writing and/or compiling rate routine ${definition.Code} v${definition.Version}", ex)
errorCount.incrementAndGet()
}
var numRoutines = routineCount.get()
_processedCount = numRoutines
if ((numRoutines % 1000) == 0) {
_logger.info("Processed ${numRoutines} routine definitions with ${errorCount.get()} errors. " +
"Files = ${filesWritten.get()}")
}
})
if (_state == Stopped) {
return
}
var duration = stopwatch.elapsed(TimeUnit.SECONDS)
_logger.info("Writing rate routine generated sources to ${_directory} completed. " +
"Processed ${routineCount.get()} routine definitions with ${errorCount} errors. #Files written = ${filesWritten}. Time = ${duration}seconds")
if (errorCount.get() > 0) {
throw new IllegalStateException("Code generation and/or compilation failed for ${errorCount.get()} rate routines.")
}
if (routineCount.get() > 0) {
stats.log(_logger)
}
} finally {
_state = Stopped
}
}
override function stop(serverShuttingDown : boolean) {
_logger.info("CalcRoutinesSourcesWriter: Stop requested.")
_state = Stopped
}
override property set Parameters(params : Map