BaseController.runOnInstance
now performs the json serialization on the target instance. This allows lighter-weight remote endpoint executions, that do not require object serialization. Applications must now provide aClusterJsonRequest
to this method rather than aClusterRequest
- Align all-built in log names to have form "App-Cluster-xxx.log"
- Dynamic configuration for distributed hazelcast objects is no longer supported -- all configuration
must be in place before an instance is started, per Hazelcast documentation. Therefore the
ClusterService.configureXXX
methods have been removed, and have been replaced by support for specifying a static closureClusterService.configureCluster
. This is not expected to have a practical impact on any existing applications.
- Fix to issue with a
Timer
interval specified as a config names failing to update dynamically.
- Increased max length of
Role.category
string to 100 chars. - Requires column modification to
xh_role
table with the following SQL or equivalent:
-- MySQL
ALTER TABLE `xh_role` CHANGE COLUMN `category` `category` VARCHAR(100) null
-- SQL Server
ALTER TABLE xh_role ALTER COLUMN category VARCHAR(100) null
- Requires
hoist-react >= 69
to support revised API for Activity Tracking and User Preference POSTs from client.
- Updated Activity Tracking endpoint to support client POSTing multiple track logs in a single request, helping to reduce network overhead for chatty apps.
- Improved the handling of track log timestamps - these can now be supplied by the client and are no longer bound to insert time of DB record. Latest Hoist React uses start of the tracked activity.
- Support for persisting of memory monitoring results
- New built-in monitor
xhClientErrorsMonitor
- New methods
MonitorResult.getParam
andMonitorResult.getRequiredParam
- Updated behavior of
withInfo
andwithDebug
log utils to print a "started" message if logging enabled atDEBUG
orTRACE
, respectively. Allows admins to see start messages for more importantwithInfo
logs, without necessarily printing both lines for allwithDebug
calls.
- Improvements to the efficiency of
CachedValue
for sharing of large objects. This included moving to its own packageio.xh.hoist.cachedvalue
for clarity. - New dynamic configuration for all distributed hazelcast objects. See methods
ClusterService.configureXXX
. These methods replace the static mapBaseService.clusterConfigs
.
- Misc. improvements to logging and performance of
Cache
andTimer
. - New configuration property
hoist.sensitiveParamTerms
allows customization of environment variables to be obscured in the admin client.
- Updated
Timer
,Cache
, andCachedValue
objects to require aname
property. Names are now mandatory to better support new cluster features, logging, and Admin Console tooling. - Migrated
BaseService
methodsgetIMap()
,getReplicatedMap()
andgetISet()
tocreateIMap()
,createReplicatedMap()
andcreateISet()
, respectively. Not expected to impact most apps, as these APIs are new and only used for distributed, multi-instance data.
- Added new
BaseService
factories to createCache
andCachedValue
objects. This streamlined interface reduces boilerplate and is consistent withTimer
creation. - Improved
Timer
to maintain consistent execution timing across primary instance changes. - Improved
RestController
to support domain objects linked to a non-primaryDataSource
.
- Enhanced the
xh/environmentPoll
payload to include any active Alert Banner spec. Clients runninghoist-react >= 68
will leverage this to avoid an extra polling request. - Exposed
/xh/ping
as whitelisted route for basic uptime/reachability checks. Retained legacy/ping
alias, but prefer this new path going forward. - Improved handling + rendering of exceptions during authentication and authorization requests.
- Updated
ClusterService
to use Hoist'sInstanceNotFoundException
, ensuring that common errors thrown due to instance changes are marked as routine and don't spam error reporting. - Added new
BaseService.resources
property to track and provide access toCache
objects andTimer
s by name, replacingBaseService.timers
.
- Resolved issue where connected clients would not display the upgrade prompt banner when an app was
first released with an update to
hoist-core >= 21.0.0
.
- Improved serialization efficiency of replicated
Cache
andCachedValue
.
- Requires
hoist-react >= 67.0.0
. - Requires minor DB schema additions (see below).
ReplicatedValue
has been replaced with the enhancedCachedValue
. This new object provides all the functionality of the old, plus additional features from theCache
API such as expiry,getOrCreate()
, event support, and blocking support for non-primary nodes.- Migrated previous
xhAppVersionCheck
to newxhEnvPollConfig
, which now governs a single polling interval on the client to check for app version and connected instance changes. The previous config'smode
value will be automatically migrated to the newonVersionChange
key. A shorter default interval of 10s will be set in all cases, to ensure timely detection of instance changes. - The
/xh/environment
endpoint is no longer whitelisted and requires / will trigger authentication flow.
- Client error reports include new
correlationId
field.- β NOTE - this requires a new column in the
xh_client_error
table. Review and run the following SQL, or an equivalent suitable for the particular database you are using:ALTER TABLE `xh_client_error` ADD COLUMN `correlation_id` VARCHAR(100) NULL;
- β NOTE - this requires a new column in the
- Activity tracking logs include new
correlationId
field.- β NOTE - this requires a new column in the
xh_track_log
table. Review and run the following SQL, or an equivalent suitable for the particular database you are using:ALTER TABLE `xh_track_log` ADD COLUMN `correlation_id` VARCHAR(100) NULL;
- β NOTE - this requires a new column in the
Cache
and the (new)CachedValue
provide a new common API for (potentially replicated) state in services. In particular the following new features are included with common API:- Dynamic expiry of values via fluid api
- New event handling via
addChangeHandler
- Improved trace logging of value serialization
- Offers both replicated and non-replicated modes
- New instance aware methods on
BaseController
:runOnInstance
,runOnPrimary
andrunOnAllInstances
. These were formerly onBaseClusterController
, which has been removed. - New
LdapService.authenticate()
API supports a new way to validate a domain user's credentials by confirming they can be used to bind to a configured LDAP server.
- Fixed bug where a role with a dot in its name could not be deleted.
LdapService
now binds to configured servers with TLS and supports newskipTlsCertVerification
flag in its config to allow for self-signed or otherwise untrusted certificates.
- Fixed sporadic serialization errors on status monitor results with an attached exception.
- Added configurable table name to
xhDbConnectionMonitor
status check to support edge case where XH tables are in a custom schema.
- Support for bulk updating of Role categories.
- Simplified the
xhDbConnectionMonitor
query to work with more SQL dialects.
- Improvements to the ability to configure Hibernate 2nd-level caches. See
ClusterConfig
for more information.
- Remove obsolete, non-functioning GSP support from
EmailService
.
- Fix to regression with
LdapObject
subclasses not fully populating all keys/properties.
- Common LDAP attributes
cn
,displayname
,mail
, andname
moved toLdapObject
class. - Websockets are now enabled by default. To disable, add
hoist.enableWebSockets = false
to your project'sapplication.groovy
file (note the lowercase "a" to ensure you have the correct one).
LdapService.searchOne
andsearchMany
methods have been made public.LdapPerson
class now includesdisplayName
,givenname
, andsn
fields.
LdapPerson
classemail
field changed tomail
to match LDAP attribute.
BaseProxyService
now correctly handles responses without content.BaseProxyService
now properly supports caching the underlyingHttpClient
between requests. This defaults tofalse
to reflect current behavior, but may be overridden to enable.
- Removed obsolete
BaseAuthenticationService.whitelistFileExtensions
- Restored routing of status monitor logging to dedicated file.
Hoist Core v20 provides support for running multi-instance clusters of Hoist application servers. Cluster management is powered by Hazelcast, an open-source library providing embedded Java support for inter-server communication, co-ordination, and data sharing.
See the new ClusterService.groovy
service, which provides the clustering implementation and main
API entry point for accessing the cluster.
Many apps will not need to implement significant changes to run with multiple instances. Hoist will setup the cluster, elect a primary instance, provide cluster-aware Hibernate caching and logging, and ensure cross-server consistency for its own APIs.
However, complex applications -- notably those that maintain significant server-side state or use their server to interact within external systems -- should take care to ensure the app is safe to run in multi-instance mode. Distributed data structures (e.g. Hazelcast Maps) should be used as needed, as well as limiting certain actions to the "primary" server.
Please contact XH to review your app's readiness for multi-instance operation!
- New support for reporting service statistics for troubleshooting/monitoring. Implement
BaseService.getAdminStats()
to provide diagnostic metadata about the state of your service. Output (in JSON format) can be easily viewed in the Hoist Admin Console. - New
DefaultMonitorDefinitionService
provides default implementations of several new status monitors to track core app health metrics. Extend this new superclass in your app'sMonitorDefinitionService
to enable support for these new monitors. - Includes new support for dynamic configuration of client-side authentication libraries. See new
method
Authentication.getClientConfig()
.
π₯ Breaking Changes (upgrade difficulty: π MEDIUM / π’ LOW for apps with minimal custom server-side functionality)
-
Requires
hoist-react >= 64.0
for essential Admin Console upgrades. -
Requires updated
gradle.properties
to specifyhazelcast.version=5.3.x
. Check hoist-core or Toolbox at time of upgrade to confirm exact recommended version. -
Requires column additions to three
xh_
tables with the following SQL or equivalent:ALTER TABLE `xh_client_error` ADD COLUMN `instance` VARCHAR(50) NULL; ALTER TABLE `xh_track_log` ADD COLUMN `instance` VARCHAR(50) NULL; ALTER TABLE `xh_monitor` ADD COLUMN `primary_only` BIT NOT NULL DEFAULT 0;
On MSSQL, the last column can be added with:
ALTER TABLE xh_monitor ADD COLUMN primary_only BIT DEFAULT 0 NOT NULL;
-
Apps can configure their HZ cluster by defining a
ClusterConfig
class:- This should extend
io.xh.hoist.ClusterConfig
and be within your primary application package (xhAppPackage
ingradle.properties
- e.g.io.xh.toolbox.ClusterConfig
). - We recommend placing it under
/grails-app/init/
- see Toolbox for an example. - Note XH clients with enterprise ("mycompany-hoist") plugins may have their own superclass which should be extended instead to provide appropriate defaults for their environment. Note that an app-level class is required in this case to pick up those defaults, although it will commonly not require any additional app-level overrides.
- This should extend
-
Apps that intend to run with more than one server must enable sticky sessions when routing clients to servers. This is critical for the correct operation of authentication and websocket communications. Check with XH or your networking team to ensure this is correctly configured.
-
Server-side events raised by Hoist are now implemented as cluster-wide Hazelcast messages rather than single-server Grails events. Any app code that listens to these events via
BaseService.subscribe
must update toBaseService.subscribeToTopic
. Check for:xhClientErrorReceived
xhConfigChanged
xhFeedbackReceived
xhMonitorStatusReport
-
The
exceptionRenderer
singleton has been simplified and renamed asxhExceptionHandler
. This change was needed to better support cross-cluster exception handling. This object is used by Hoist internally for catching uncaught exceptions and this change is not expected to impact most applications. -
Utils.dataSource
now returns a reference to the actualjavax.sql.DataSource.DataSource
. UseUtils.dataSourceConfig
to access the previous return of this method (DS config, as a map). -
Apps must replace the
buildProperties.doLast
block at the bottom of theirbuild.gradle
with:tasks.war.doFirst { File infoFile = layout.buildDirectory.file('resources/main/META-INF/grails.build.info').get().asFile Properties properties = new Properties() infoFile.withInputStream {properties.load(it)} properties.putAll(hoistMetaData) infoFile.withOutputStream {properties.store(it, null)} }
- Calls to URLs with the correct controller but a non-existent action were incorrectly returning
raw
500
errors. They now return a properly JSON-formatted404
error, as expected.
- All
Throwable
s are now serialized to JSON using Hoist's standard customization of Jackson.
Please ensure you review and update your gradle.properties
and gradle-wrapper.properties
files.
In gradle.properties
(partial contents of this file, with updated libraries only):
groovyVersion=3.0.21
grailsVersion=6.2.0
grailsGradlePluginVersion=6.2.0
gormVersion=8.1.0
grailsHibernatePluginVersion=8.1.0
hazelcast.version=5.3.7
In /gradle/wrapper/gradle-wrapper.properties
(note your app might have an internal artifact repo
in place of services.gradle.org - leave that as-is, updating the version only to 7.6.4):
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.4-bin.zip
- Requires
hoist-react >= 63.0
for client-side changes to accommodate updatedtrack
andsubmitError
APIs. See below for database column additions to support the same. - Implementations of
DefaultRoleService.doLoadUsersForDirectoryGroups
will need to handle a newstrictMode
flag provided as a second argument.
- Client error reports include a new
impersonating
field for additional troubleshooting context.- β NOTE - this requires a new column in the
xh_client_error
table. Review and run the following SQL, or an equivalent suitable for the particular database you are using:ALTER TABLE `xh_client_error` ADD COLUMN `impersonating` VARCHAR(50) NULL;
- β NOTE - this requires a new column in the
- Activity tracking logs include new
appVersion
,appEnvironment
andurl
fields.- β NOTE - this requires new columns in the
xh_track_log
table. Review and run the following SQL, or an equivalent suitable for the particular database you are using:ALTER TABLE `xh_track_log` ADD COLUMN `app_version` VARCHAR(100) NULL; ALTER TABLE `xh_track_log` ADD COLUMN `app_environment` VARCHAR(100) NULL; ALTER TABLE `xh_track_log` ADD COLUMN `url` VARCHAR(500) NULL;
- β NOTE - this requires new columns in the
DefaultRoleService
has improved error handling for failed directory group lookups.LdapService
bulk lookup methods now provide astrict
option to throw if a query fails rather than quietly returning an empty result.- New
TrackLogAdminService
andClientErrorAdminService
services provide improved APIs for queryingTrackLog
andClientError
records. Leveraged by updated Hoist Admin Console to post selected filters to the server and return more relevant data within configured row limits.
- Fixed bug in
DefaultRoleService.doLoadUsersForDirectoryGroups
where LDAP members withnull
samAccountNames were not being filtered out, causingNullPointerExceptions
.
- Quiet log warnings from
LdapNetworkConnection
inLdapService
by setting theLdapNetworkConnection
log level toERROR
.
- Method
DefaultRoleService.ensureUserHasRoles
has been renamed toassignRole
. The new name more clearly describes that the code will actually grant an additional role to the user.
- Fixed
LdapService
bug where querying multiple servers with same host yielded incomplete results.
InstanceConfigUtils
- used to read low-level configuration values such as database credentials - will now search for an environment variable with a matching name and return that value if it exists.- This can either override or entirely replace the use of a yaml file or Kubernetes secrets to specify this kind of configuration.
- To help namespace app-specific environment variables while also maintaining the conventions of
instance configs having
camelCase
identifiers and environment variables havingUPPER_SNAKE_CASE
identifiers,InstanceConfigUtils
will convert and prependAPP_[APP_CODE]_
to the requested key when looking for an environment variable. For example, in our Toolbox demo appInstanceConfigUtils.getInstanceConfig('dbUrl')
will check if an environment variable namedAPP_TOOLBOX_DB_URL
exists, and return its value if so.
ConfigService
methods now return override values from an instance config, if one exists with the same name as an app config.- Allows an instance-specific value specified via a yaml file or environment variable to override the config value saved to the app's database, including configs used by Hoist itself.
- Update to
hoist-react >= 60.2
for an Admin Console upgrade that checks for and clearly indicates any overridden values in the Config editor tab.
EnvAdminController
now obfuscates environment variables ending withpassword
and similarly sensitive strings.
- Fixed bug in
LdapService.lookupUser
where queries were not being formed correctly.
- Fixed bug in
DefaultRoleService
where not all effective roles were being returned for a user.
DefaultRoleService
now includes support for out-of-the-box LDAP groups.
- Refactor
DefaultRoleService
for more efficient and straightforward role/user resolution - Normalize role member usernames to lowercase and generally tighten up case-insensitive handling.
- Fixed
DefaultRoleService
unintended case-sensitive handling of usernames.
- Added new
LdapService
to provide out-of-the-box support for querying LDAP groups and users via the Apache Directory library. - Γ
dded
ConfigService.hasConfig()
method to check if a config exists.
-
Improved handling of requests during application initialization. HTTP requests received during App startup will now yield clean "App Initializing" Exceptions. This is an improvement over the current behavior where attempting to service requests prematurely can cause arbitrary and misleading exceptions.
-
Misc. Improvements to
DefaultRoleService
API and documentation.
- Fixed an issue preventing the creation of new roles.
- New support for Role Management.
- Hoist now supports an out-of-the-box, database-driven system for maintaining a hierarchical set of roles and associating them with individual users.
- New system supports app and plug-in specific integrations to AD and other enterprise systems.
- Hoist-react
v60
is now required and will provide an administrative UI to visualize and manage the new role system. - See
DefaultRoleService
for more information.
- Add
xh/echoHeaders
utility endpoint. Useful for verifying headers (e.g.jespa_connection_id
) that are installed by or must pass through multiple ingresses/load balancers. - Remove HTML tag escaping when parsing alert banner create/update request JSON.
- Applications will typically need to adjust their implementation of
BaseRoleService
. Most applications are expected to adopt the new providedDefaultRoleService
, and may be required to migrate existing code/data to the new API. Applications that wish to continue to use a completely customBaseRoleService
will need to implement one additional method:getUsersForRole
.
- Improvement to
BaseProxyService
to better handle exceptions during streaming. - Optimization to
WebSocketService
to remove an extra layer of async task wrapping when pushing to a single channel.
- Workaround for GORM issue with unconstrained findAll() and list() breaking eager fetching. See grails/gorm-hibernate5#750.
- New
ConfigService.setValue()
API supports programmatic updates to existing app configs.
- Lightweight monitoring collection of JDBC connection pool statistics, including counters for
active vs idle connections. Viewable in Hoist Admin Console for apps on
hoist-react >= 59.0
.
- Additional improvements to support hot-reloading.
This release upgrades Hoist to the latest 6.0.0 version of Grails and upgrades related libraries. It should be fully compatible with Java 11 and Java 17.
- This version of Hoist restores the ability to do development-time reloading via the java hotswap agent. See the readme for more information.
- The implementation of the
LogSupport
trait has been simplified, such that it no longer requires an @SLF4J annotation, orlog
property to be provided. Undocumented and problematic methodslogXXXInBase
were removed.
- grails
5.3.2 β 6.0.0
- gorm
7.3.2
β8.0.0
- groovy
3.0.9
β3.0.11
- Replace bullet points with hyphens in default
xhAppVersionCheck
config.
- Remove one remaining smart quote to make default notes in default config safer for all DBs.
- Make default notes in default config safer for all DBs by removing smart quotes.
- Make impersonation service more robust for applications with dynamic/lazy user generation.
- Additional validation of parameters to '/userAdmin/users' endpoint.
- Added new
logData
option toTrackService.track()
- allows applications to request that key/value pairs provided within thedata
block of a track statement be logged along with the standard output. Client-side support for this feature on a per-call basis added inhoist-react >= 57.1
, can also be defaulted within thexhActivityTrackingConfig
app config. - Deprecated config
xhAppVersionCheckEnabled
in favor of object basedxhAppVersionCheck
. Apps will migrate the existing value to this new config'smode
flag. This supports the newforceRefresh
mode introduced in hoist-react v58.
- Added support for saving alert banner presets (requires
hoist-react >= 57.0.0
to use this new functionality, but backwards compatible with earlier hoist-react releases). - Defined new
HOIST_IMPERSONATOR
role to control access to Hoist's user-impersonation feature.- This new role is inherited by
HOIST_ADMIN
(the role previously required) by default, although applications can overrideBaseUserService.getRolesForUser()
to customize. - Applications that have already overridden this method will need to re-implement this role inheritance, or assign the new role to appropriate users directly.
- This new role is inherited by
- Exposed new
BaseUserService.impersonationTargetsForUser()
template method to allow apps to customize the list of users that an admin can impersonate. - Added support for OWASP-encoding user submitted strings to
BaseController
via a newsafeEncode()
method and a newsafeEncode
option toparseRequestJSON()
andparseRequestJSONArray()
.- Apps are encouraged to run any user-provided inputs through this method to prevent XSS attacks.
- Added new
BaseController
methodsparseRequestJSON()
andparseRequestJSONArray()
.- These methods are the recommended way to parse JSON from a request body - they will use
Hoist's optimized, Jackson-based
JSONParser
.
- These methods are the recommended way to parse JSON from a request body - they will use
Hoist's optimized, Jackson-based
- Created new
xhExpectedServerTimeZone
app config, now read at startup to validate that the server is running in a particular, application-configured time zone.- Default value of
*
will skip validation but log a warning that no zone is configured. - If a zone is configured, Hoist will throw a fatal exception if it does not match the zone reported by Java.
- Most applications should ensure that this config and the runtime JVM are set to the same time zone as their primary database.
- Default value of
- Added
h2Config
method toRuntimeConfig
class to give apps the option of starting up with an H2 in-memory DB. This is intended for projects in their earliest, "just checked out, first run" stage, when a developer wants to get started before having set up an external database. - Updated
AlertBannerService
to append the environment name when creating/updating theJsonBlob
used to persist banner state in a non-production environment. This better supports apps where e.g.Beta
andProduction
environments share a database, but should display distinct banners. - Added support for the
caseSensitive
flag in log filtering endpoint.
- Fixed a regression preventing the culling of snapshots in the memory monitoring service.
- Enhance MemoryMonitoringService.
- Produce and use more appropriate usage metric (used/max)
- Produce GC statistics
- Support for taking a heap dump
- Fixed a regression with 404 errors being incorrectly handled and not serialized as JSON.
EmailService.sendEmail()
now supports theattachments
argument, for attaching one or more files to the email.- A new
xhActivityTrackingConfig
soft-configuration entry will be automatically created to control the behavior of built-in Activity Tracking (viaTrackService
).- Most notably, the size of any
data
objects included with track log entries will be constrained by this config, primarily to constrain memory usage when querying and serializing large numbers of log entries for the Admin Console. - Any track requests with data objects exceeding this length will be persisted, but without the requested data.
- Most notably, the size of any
-
Removed support for "local" preferences - any existing prefs previously marked as local will now work like all others, with their values persisted on the server.
- Apps upgrading to this Core release should simultaneously upgrade to Hoist React v56, which will automatically post any existing local preference values to the server.
- Alternatively, update client-side code to use browser local storage for persisting user state that should remain tightly bound to a particular computer.
- Update the schema to set
xh_preference
table'slocal
column to allow nulls. If this is not done, a Hibernate error (local
column cannot be null) will be thrown when an admin tries to add a new preference to the app.alter table xh_preference alter column local bit null
- Once they are sure no rollback is needed, apps can safely delete the
xh_preference
table'slocal
column.alter table xh_preference drop column local
-
Grails has been updated to
5.3.2
. While this change did not itself introduce any breaking changes, applications should update their Grails version withingradle.properties
to match.
- Client Error timestamps will now correctly reflect the exact time the error was received on the server rather than the time the error was bulk processed by the server.
- grails
5.2.1 β 5.3.2
Version 15 includes changes to support more flexible logging of structured data:
- The bulk of Hoist conventions around log formatting have been moved from
LogSupport
to a new log converter --LogSupportConverter
. This allows applications to more easily and fully customize their log formats by specifying custom converters. LogSupport
should still be the main entry point for most application logging. This class provides the support for enhanced meta data-handling as well as some important APIs - e.g.withDebug()
andwithInfo()
.- Applications are now encouraged to provide
LogSupport
methods with data inMap
form. Provided converters will serialize these maps as appropriate for target logs. - Hoist's
LogSupportConverter
is intended for easy reading by humans, allows specifying keys that should disappear in the final output with an_
prefix. This is useful for keys that are obvious, e.g.[_status: 'completed', rows: 100]
logs as'completed' | rows=100
. - Alternatively, applications may now specify custom converters that preserve all keys and are
more appropriate for automatic processing (e.g. splunk). An example of such a converter is
CustomLogSupportConverter
which can be found in the Toolbox project. - By default, Hoist now also logs the time in millis when a log message occurred.
- Improved the signatures of
LogSupport
methodswithInfo
(and similar) to pass through the return type of their closure argument.
- Allow database connection info to viewed by users with role:
HOIST_ADMIN_READER
and higher.
- The Hoist Admin Console is now accessible in a read-only capacity to users assigned the
new
HOIST_ADMIN_READER
role. - The pre-existing
HOIST_ADMIN
role inherits this new role, and is still required to take any actions that modify data. - Requires
hoist-react >= 53.0
for client-side support of this new readonly role.
- Status monitor now prepends its generated message to any more specific message provided by app-level status check code when the result is ERROR, FAIL, or WARN. Previously any app-specific messages were overridden entirely.
- Correct type specified for
notFoundValue
arg inConfigService.getLong()
andgetDouble()
method signatures.
- Excel exports now support per-cell data types and long values for
int
types.
- Fix to minor regression in client error emails.
- Activity tracking enhancements. Tracking can now be done without the context of a web request and an explicit specification of a username is allowed.
- Relaxed character limit on subject length for emails sent via
emailService
from70
to255
- Revert groovy version to
3.0.9
to support java/groovy compilation.
- groovy
3.0.11 β 3.0.9
β Note - applications should add logback.version=1.2.7
as a new line to their gradle.properties
file to fix logback on a version that remains compatible with Hoist's Groovy-based configuration.
PrefService.getClientConfig()
has been optimized to reduce the number of database calls. Previously one select was issued per non-local preference when the second-level query cache was cold for a given user. Now only a single select is required.DateTimeUtils
app/server timezone conversion utils default to current day/date if called without arguments.- Standard JSON serialization/deserialization of newer Java date classes added with registration of the JSR310 module.
LogSupport
methodswithInfo
,withDebug
, andwithTrace
will now output a pre-work " Starting" message whenever logging is at level 'debug' or above. Previously level 'trace' was required.- Additional logging added to
MemoryMonitoringService
.
- grails
5.1.1 β 5.2.1
- groovy
3.0.9 β 3.0.11
- gorm
7.1.2 β 7.3.2
- hibernate
5.6.3 β 5.6.10
- org.grails.plugins:hibernate
7.2.0 β 7.3.0
- httpclient
5.1.2
β5.1.3
- New method on
BaseController
runAsync
provides support for asynchronous controllers
- Fixed exporting to Excel file erroneously coercing certain strings (like "1e10") into numbers.
- Requires
hoist-react >= 50.0
. Exporting to Excel defaults to using column FieldType.
- Fixed a bug with JSON Blob diffing.
- Fixed a bug with impersonation not ending cleanly, causing the ex-impersonator's session to break upon server restart.
- Fixed a bug in implementation of
clearCachesConfigs
- Admin log file listing includes size and last modified date, visible with optional upgrade
to
hoist-react >= 48.0
.
- Support for reporting configuration state of Web Sockets
- New property
Utils.appPackage
for DRY configuration.
- Fix to regressions in Excel exports and logging due to changes in Groovy
list()
API.
LocalDate
s are now serialized in the more fully ISO standard "YYYY-MM-DD" format, rather than "YYYYMMDD". Note that this is consistent with similar changes toLocalDate
serialization in Hoist React v46.- Although this format will be accepted client-side by
hoist-react >= 45.0
, apps that are parsing these strings directly on the client may need to be updated accordingly.
- Fix to Regressions in JsonBlobService/AlertBannerService
This version includes a major upgrade of several underlying libraries, especially grails (5.1), spring (5.3), spring-boot (2.6), groovy (3.0), and gradle (7.3). With this version, Hoist can now be run on Java versions 11 - 17. We have also cleaned up and enhanced some core APIs around Exception Handling, JSON parsing and configuration.
Please see the Grails5 Toolbox update commit for the application-level changes to core configuration files and dependencies.
- The trait
AsyncSupport
with its single methodasyncTask
has been removed. Use the equivalent methodtask
fromgrails.async.Promises
instead. - The method
subscribeWithSession
onBaseService
has been removed. Usesubscribe
instead. - Application Tomcat Dockerfiles must be updated to use a new
xh-tomcat
base image on JDK 11/17. - Groovy Language:
list
methods changed:push()
now prepends an item to the start of the List. To append to the end, useadd()
.pop()
now removes the first item from the List. To remove the last item, useremoveLast()
.
- This release upgrades the major version of grails from 3.3.9 to 5.1. This major release includes
the following upgrades of related libraries:
- spring boot
1.x β 2.6
- groovy
2.4 β 3.0
- gradle
4.10 β 7.3
- gorm
6.1 β 7.1
- hibernate
5.1 β 5.6
- org.grails.plugins:mail
2.0 β 3.0
- apache poi
3.1
β4.1
- spring boot
- Default application configuration is now better bundled within hoist-core. See new
classes
ApplicationConfig
,LogbackConfig
, andRuntimeConfig
. Please consult the grails docs as well as the Toolbox update linked above for more information on required changes to config and dependency files. - Options for hot reloading have changed, as
spring-loaded
is now longer supported for java versions > jdk 8. As such, options for hot reloading of individual classes are more limited, and may require additional tools such as JRebel. See the grails upgrade guide for more info. - Applications will be required to add the
@Transactional
or@ReadOnly
annotations to service and controller methods that update data or read data from Hibernate/GORM. - HttpClient has been upgraded from
4.5 β 5.1
. Package names have changed, and applications using this API (e.g. withJSONClient
) will need to update their imports statements to reflect the new locations @org.apache.hc.client5.http
andorg.apache.hc.core5.http
. See Toolbox for examples. - WebSocket Support has been simplified. To enable WebSockets, simply set the application config
hoist.enableWebSockets = true
inapplication.groovy
. This can replace the custom annotation / enhancement of the Application class used in earlier versions of Hoist. - Hoist JSON Validation now uses the same Jackson configuration used by
JSONParser
. - The optional
withHibernate
argument toTimer
is obsolete and no longer needed.
-
Fix to Regression in v11 preventing proper display of stacktraces in log.
- Minor tweak to allow nested lists and arrays in
LogSupport
statements. Improved documentation.
- Enhancement to
LogSupport
to help standardize logging across all Service and Controllers. New methodslogInfo
,logDebug
,logTrace
,logWarn
, andlogError
now provide consistent formatting of log messages plus log-level aware output of any throwables passed to these methods. See LogSupport for more info.
- The methods
LogSupport.logErrorCompact
andLogSupport.logDebugCompact
have been removed. UselogError
andlogDebug
instead, passing yourThrowable
as the last argument to these methods.
- The
lastUpdatedBy
column found in various Admin grid now tracks the authenticated user's username, indicating if an update was made while impersonating a user. - Fix to bug causing 'Edge' browser to be incorrectly identified.
- New Admin endpoint to output environment variables and JVM system properties.
- Take (optional) update to
hoist-react >= 44.1.0
for corresponding Hoist Admin Console UI.
- Take (optional) update to
β NOTE - apps must update to hoist-react >= 44.0.0
when taking this hoist-core update.
- Log Levels now include information on when the custom config was last updated and by whom. Note required database modifications in Breaking Changes below.
- Client Error messages are now saved and sent in bulk on a timer. This allows Hoist to bundle multiple error reports into a single alert email and generally improves how a potential storm of error reports is handled.
- Improved
JsonBlob
editing now supports setting null values for relevant fields.
-
Update required to
hoist-react >= 44.0.0
due to changes inJsonBlobService
APIs and the addition of new, dedicated endpoints for Alert Banner management. -
Public methods on
JsonBlobService
have been updated - input parameters have changed in some cases, and they now returnJsonBlob
instances (instead of pre-formatted Maps). -
Two new columns should be added to the
xh_log_level
table in your app's database: a datetime column and a nullable varchar(50) column. Review and run the SQL below, or an equivalent suitable for your app's database. (Note that both columns are marked as nullable to allow the schema change to be applied to a database in advance of the upgraded deployment.)ALTER TABLE `xh_log_level` ADD `last_updated` DATETIME NULL; ALTER TABLE `xh_log_level` ADD`last_updated_by` VARCHAR(50) NULL;
- Dedicated admin endpoints added for Alert Banner management, backed by a new
AlertBannerService
.
- Log Viewer now supports downloading log files.
- Applications will no longer default to "development" environment in server deployments. A recognized environment must be explicitly provided.
EmailService
now requires an override or filter config before sending any mails in local development mode.ClientErrorEmailService
now relays any client URL captured with the error.
- Bootstrap new
xhSizingMode
core preference.
- Excel cell styles with grouped colors are now cached for re-use, avoiding previously common file error that limits Excel tables to 64,000 total styles.
- Client error reports now include the full URL for additional troubleshooting context.
-
β NOTE - this requires a new, nullable varchar(500) column be added to the xh_client_error table in your app's configuration database. Review and run the following SQL, or an equivalent suitable for the particular database you are using:
ALTER TABLE `xh_client_error` ADD COLUMN `url` VARCHAR(500) NULL;
-
- Parsing of
AppEnvironment
from a string provided via instance config / JVM opts is now case-insensitive.
- Replaced obsolete jcenter dependency (see https://blog.gradle.org/jcenter-shutdown).
GridExportImplService
now handles Excel table exports containing no data rows. Previously, the Excel file required repair, during which all table and column header formatting was lost.- Status Monitors no longer evaluate metric-based thresholds if an app-level check implementation
has already set marked the result with a
FAIL
orINACTIVE
status, allowing an app to fail or dynamically disable a check regardless of its metric. - Fix incorrect formatting pattern strings on
DateTimeUtils
.
- Restore JSON Serialization of
NaN
andInfinity
asnull
. This had long been the standard Hoist JSON serialization forDouble
s andFloat
s but was regressed in v7.0 with the move to Jackson-based JSON serialization.
- Improvements to the tracking / logging of admin impersonation sessions.
- Built-in logging utils
withDebug
,withInfo
,compactErrorLog
andcompactDebugLog
will log username when called in the context of a user request. - New method
IdentityService.getUsername()
for efficient access to username when no additional details about current user are needed.
- Improve consistency of exception descriptions in logs.
- Remove repeated exception descriptions in logs:
withDebug
andwithInfo
will no longer print exception details. - TrackService will now log to a dedicated daily log file.
LogSupport
API enhancements:logErrorCompact()
andlogDebugCompact()
now only show stacktraces onTRACE
withInfo()
andwithDebug()
now log only once after execution has completed. Raising the log level of the relevant class or package toTRACE
will cause these utils to also log a line before execution, as they did before. (As always, log levels can be adjusted dynamically at runtime via the Admin Console.)- The upgrade to these two utils mean that they completely replace
withShortInfo()
andwithShortDebug()
, which have both been removed as part of this change. - Additional stacktraces have been removed from default logging.
RoutineException
s are now returned with HttpStatus400
to client, rather than500
- Default exception logging in
ExceptionRender
will no longer include stacktraces, but will instead useLogSupport.logErrorCompact()
. To see stacktraces for any given logger, set the logging level toDEBUG
.
- Fixed bug preventing cleanup of MemoryMonitoringService snapshots.
- Minor enhancements to
JsonBlobService
API.
- org.apache.httpcomponents:httpclient
4.5.6 β 4.5.13
- Added new
MemoryMonitoringService
to sample and return simple statistics on heap (memory) usage from the JVM runtime. Stores a rolling, in-memory history of snapshots on a configurable interval.
- HTML-encode certain user-provided params to XhController endpoints (e.g. track, clientErrors, feedback) to sanitize before storing / emailing.
- Removed verbose stacktraces appended to the primary app log by the built-in Grails 'StackTrace' logger. This logger has now been set to level OFF by default. To re-enable these stacktraces, raise the log level of this logger in either logback.groovy or dynamically at runtime in the Hoist Admin Console.
-
JsonBlobService
- complete support for metadata with additionalmeta
property. Requires an additional column on blob table, e.g:alter table xh_json_blob add meta varchar(max) go
-
Introduce new
AppEnvironment.TEST
enumeration value.
JsonBlobService
: Enhancements to archiving, new columns and new unique key constraint.-
Apps will need to modify the
xh_json_blob
table with newarchived_date
column and related unique constraint. SAMPLE migration SQL below:alter table xh_json_blob add archived_date bigint not null go alter table xh_json_blob drop column archived go alter table xh_json_blob add constraint idx_xh_json_blob_unique_key unique (archived_date, type, owner, name)
-
Apps should update to
hoist-react >= 36.6.0
.
-
-
JsonBlobService
: Use more scalable token-based access; support archiving. Requires additional columns on blob table, e.g:alter table xh_json_blob add token varchar(255) not null go alter table xh_json_blob add archived boolean default false go
Note that the
archived
column is dropped in subsequent versions, and thus need not be added unless you are using 8.5.0 specifically.
JsonBlobService
: Security enhancements and finalization of API.- Server Support for Bulk editing of Configs and Preferences.
β NOTE - apps should update to hoist-react >= 36.1.0
when taking this hoist-core update. This is
required to support the updates to Admin Activity and Client Error tracking described below.
- Adds support for storing and retrieving
JsonBlob
s - chunks of arbitrary JSON data used by the correspondingJsonBlobService
introduced in hoist-react v36.1.0.
- Improved time zone handling in the Admin Console "Activity Tracking" and "Client Errors" tabs.
- Users will now see consistent bucketing of activity into an "App Day" that corresponds to the LocalDate when the event occurred in the application's timezone.
- This day will be reported consistently regardless of the time zones of the local browser or deployment server.
- Add new
RoutineRuntimeException
- Pref and Config Differ now record the admin user applying any changes via these tools.
- Fix bug with monitoring when monitor script times out.
- Specify default DB indices on a small number of bundled domain classes.
- Add support for Preference Diffing in the Hoist React Admin console.
- Fix minor regression to reporting of hoist-core version.
As of this release, Hoist is now licensed under the popular and permissive Apache 2.0 open source license. Previously, Hoist was "source available" via our public GitHub repository but still covered by a proprietary license.
We are making this change to align Hoist's licensing with our ongoing commitment to openness, transparency and ease-of-use, and to clarify and emphasize the suitability of Hoist for use within a wide variety of enterprise software projects. For any questions regarding this change, please contact us.
- New support for
appTimeZone
andserverTimeZone
inEnvironmentService
. - New support for eliding long strings:
StringUtils.elide()
. - New support for the enhanced Admin Activity Tracking tab shipping in hoist-react v35.
- Improvements to formatting of monitoring and error emails.
- Bootstrap
xhEnableMonitoring
config - Add Grails Quartz plugin (v2.0.13)
- Fixed a regression to TrackService, preventing persisting lists in the
data
property.
-
Exception Handling has been improved in the newly enhanced
exceptionRenderer
bean. This bean will catch uncaught exceptions from all Controllers and Timers and has been newly configured to limit the logging of unnecessary stack traces. -
New exception classes for
HttpException
andExternalHttpException
have been added. -
JSON parsing in Hoist has been reworked to simplify and standardize based on the high-performance Jackson library. (https://github.com/FasterXML/jackson). Benchmarking shows a speedup in parsing times of 10x to 20x over the
grails.converter.JSON
library currently used by Hoist. In particular, this change includes:- A new
JSONParser
API in theio.xh.hoist.json
package that provides JSON parsing of text and input streams. This API is designed to be symmetrical with the existingJSONFormatter.
- All core hoist classes now rely on the API above. Of special note are
JSONClient
, andRestController
. - Cleanups to the APIs for
JSONClient
,ConfigService
, andPrefService
. These methods now return java object representations using the standard javaMap
andList
interfaces rather than the confusingJSONObject
,JSONArray
andJSONElement
objects.
- A new
- The
getJSONObject()
,getJSONArray()
, andgetJSON()
methods onConfigService
andPrefService
have been replaced withgetMap()
andgetList()
. - The
executeAsJSONObject()
andexecuteAsJSONArray()
methods onJSONClient
have been replaced withexecuteAsMap()
andexecuteAsList()
. - The method
RestController.preprocessSubmit()
now takes aMap
as its single input, rather than aJSONObject
.
Timer.delay
now expects either a millisecond value, or a boolean. It no longer will take a string/closure andTimer.delayUnits
has been removed. This has been changed to enhance the functionality and make it consistent with its client-side counterpart in hoist-react.
- New
xhEnableLogViewer
config available to fully disable the log viewer built into the Admin console. Intended for scenarios where the UI server logs are not material/helpful, or potentially for cases where they are too chatty/large to be effectively viewed in the Admin UI.
- Added support for setting custom logging layouts. Applications can use this to further customize built-in Hoist logging, including changing it to use alternative file formats such as JSON.
- Also includes enhanced documentation and an example of how to configure logging in Hoist.
- Fixed issue where attempting to read very large log files would overly stress server processor and memory resources. #115
- Add ability to configure WebSocketService resource limits using soft configuration.
- Note intermediate builds 6.4.2/6.4.3 not for use.
- Fixed an issue where GORM validation exceptions would trigger MethodNotFoundException
- Switch to using nanoJson for JSON validation, which ensures stricter adherence to the JSON spec.
- Added a new
xhEnableImpersonation
config for enabling or disabling impersonation app-wide. Note that this config will be defaulted to false if not yet defined - set to true after upgrade to continue supporting impersonation for your application. - The
xhMonitorConfig
config supports a new propertymonitorTimeoutSecs
to control the max runtime for any individual monitor check. - Any
appBuild
tag is now included in the output ofxh/version
, allowing for client-side version checking to take the particular build into account when running on a SNAPSHOT.
- All exceptions are now rendered as JSON. HTML exception rendering is no longer supported.
- Exceptions in GORM validation will now be treated as routine and will not be logged. (#95)
- GORM validation exceptions are now handled by
BaseController
rather thanRestController
, so all endpoints will be handled consistently. (#68)
- JSON preferences accept any valid
JSONElement
for their value, not just aJSONObject
. - Default
TrackLog.severity
toINFO
vs. non-standardOK
. - Bootstrapped
xhEmailSupport
config now properlyclientVisible
.
- Grid exports to Excel now support setting an export format on a per-cell basis. Requires an updated Hoist React build for client-side support, but is backwards compatible with existing API.
JSONClient
can be constructed without providing a configuredClosableHttpClient
. A default client will be created and used.- When pointed to a directory,
InstanceConfigUtils
will first check to see if it contains a file named[appCode].yml
and, if so, will load configs from that single file and return. Otherwise, individual files within that directory will be loaded as key/value pairs, as they were previously. This allows a single-Dio.xh.hoist.instanceConfigFile
value to be baked into a container build and resolve to either single-file or directory-mode configs based on the deployment environment.
- The
Timer
class has been enhanced to support intervals as low as 500ms. Previously,Timer
had a minimum interval of 2 seconds.
- WebSocket support has been added in the form of
WebSocketService
. The new service maintains and provides send/receive functionality to connected Hoist client apps, each associated with a unique channel identifier.- β Note this change requires that applications specify a new dependency in their
build.gradle
file oncompile "org.springframework:spring-websocket"
. If missing, apps will throw an exception on startup related to a failure instantiatingWebSocketService
. Apps should not need to make any changes to their own code / services aside from this new dep. - This service and its related endpoints integrate with client-side websocket support and admin tools added to Hoist React v26.
- As per the included class-level documentation, applications must update their
Application.groovy file to expose an endpoint for connections and wire up
a
HoistWebSocketHandler
to relay connection events to the new service.
- β Note this change requires that applications specify a new dependency in their
- Dedicated Jackson JSON serializer added for Groovy
GString
objects - outputstoString()
as expected vs. obscure/unwanted object representation (#87).
- Grid exports will no longer fail if any values fail to parse as per the specified data type. Previously a single unexpected value could spoil the export - now they will be passed through as-is to the generated worksheet.
- Ensure JSON is rendered with
charset=UTF-8
vs. an unexpected ISO fallback we started getting once we stopped using the built-in Grails JSON converter in favor of rendering the String output from Jackson . Fixes issue with unicode characters getting munged in JSON responses.
- A
RoutineException
interface has been added. Implement this interface to mark any exception that is a part of normal operations and should not necessarily be logged on the server as an error. - The
DataNotAvailableException
has been added. This class implementsRoutineException
and is intended to be thrown when requested data is not currently available due to normal, expected business conditions (e.g. the business day has just rolled and new data is not yet ready). - The Jackson library is now used for JSON Serialization. This provides a faster, more standardized approach to rendering JSON. Groovy Traits are also no longer used for Hoist's Cached JSON support, improving the ability to use this feature with Java.
- Added
/ping
endpoint for trivial server up / connectivity checks.
- The
cacheJSON()
method on JSONFormat is no longer available for specifying cached JSON serialization. Extend theJSONFormatCached
class instead.
- New default pref
xhShowVersionBar
, remove deco'd prefxhForceEnvironmentFooter
.
- New default config + preference definitions added in Bootstrap to support client-side AutoRefreshService.
- Memory/processors available to JVM logged at startup.
- Throw new
SessionMismatchException
when client provides aclientUsername
to /xh endpoints that does not match the current session user. (The dedicated exception class is new, not the behavior.)
- Admin endpoint to run log archiving routine on demand.
- Further work to ensure admin log viewer endpoint is completely wrapped in try/catch to avoid throwing repeated stack traces if supplied incorrect parameters.
- Monitors will now log all activity to a daily dedicated log of the form
[appName]-monitor.log
. This behavior can be controlled with the optionwriteToMonitorLog
in thexhMonitorConfig
block.
- Activity tracking logs are now written to the database by default, even in local development mode.
An optional
disableTrackLog
instance config value is now available to prevent them from being persisted (in any environment).
- Corrected auto-defaulted required config for the log file archive directory path.
- Avoid any attempt to evaluate thresholds for Status Monitor results that do not produce a metric.
- Track log entries are now written correctly when an admin starts/stops impersonation.
- InstanceConfigUtils will warn via stdout if a config file is not found or cannot be parsed.
- Environment information now includes details on the primary database connection, including the JDBC connection string, user, and dbCreate setting. Note this additional info is only returned when the requesting user is a Hoist Admin (and is intended for display in the admin JS client).
- Additional
AppEnvironment
enums added for UAT and BCP.
- Grails
3.3.8 β 3.3.9
- GORM
6.1.10 β 6.1.11
- Apache HttpClient
4.5.3 β 4.5.6
- AppConfigs and Preferences now serialize their values / defaultValues with appropriate types in their formatForJSON serializations. (Previously values were all serialized as strings.) This allows for more direct binding with admin editor form controls of the appropriate type, and generally centralizes their serialization in a more consistent way.
- Processing of uploaded grid data for Excel export modified to handle even larger export sets.
β οΈ Note requires client-side toolkit updates (>= v16 for Hoist React).
InstanceConfigUtils
can now read bootstrap configuration values from a directory of files, each containing a single config, in addition to the previous support for yaml files. This supports reading low-level configuration from Docker/Kubernetes configs and secrets, which are mounted to the container filesystem as a directory.
- An admin client that happens to be polling for a non-existent log file (e.g. one that has just been archived) will no longer spam the logs with stack traces.
- Avoids the use of (sometimes) reserved SQL word
level
in theLogLevel
config object. Remapped tolog_level
column.
This release includes several core API changes to how users and their roles (permissions) are loaded. (Note that the breaking changes below will typically be handled by updates to a custom enterprise plugin and not require individual app changes.)
- Applications (or enterprise plugins) must implement a new
RoleService
extending fromBaseRoleService
to provide a map of users to their app-specific roles. Roles continue to be modelled as simple strings for use both on server and client. - The
HoistUser
superclass no longer holds / caches its roles directly, but instead calls into the new requiredRoleService
dynamically when asked. - Boilerplate around auth whitelists and resources has been better consolidated into the plugin,
helping to clean up some repeated application-level
AuthenticationService
code. - Hoist implementation endpoints have moved from
/hoistImpl/ β /xh/
for brevity / clarity. Client-side plugins will be updated to use this new path. The implementation APIs used to login/logout and confirm auth / roles have changed, but again are handled by Hoist client plugin updates and do not require application-level changes.
- Server-side Excel export supports
LONG_TEXT
format with wrapped multi-line cells.
- Objects extending
JSONFormat
withcacheJSON
enabled can be rendered at the top-level of a return.
- Added support for
activeOnly
argument toUserAdminController
- required for xh/hoist-react#567
- Added support for PUT, PATCH, DELETE to BaseProxyService.
- Grails
3.3.5 β 3.3.8
- Relevant
HoistImplController
endpoints now require aclientUsername
param to ensure the client and server are in sync re. the currently active user. This resolves edge-case bugs around impersonation and preference, dashboard changes flushing changes on unload to the wrong server-side user. (#46)
- The
xhEmailDefaultDomain
config no longer needs a leading (and confusing)@
- EmailService will prepend this automatically.β οΈ Note app-level configs with a leading@
in place will need to be adjusted. (#43)
- IdentityService.getUser() should not throw when called outside context of a request -- just return null. Important when e.g. looking for a username within service calls that might be triggered by a controller-based web request or a timer-based thread. 4130a9add8dd8ba22376ea69cfa3a3d095bdf6b0
- Group field added to Preferences for better organization and consistency with AppConfigs.
β οΈ Note schema update required:
--MySQL
ALTER TABLE xh_preference
ADD group_name VARCHAR(255);
UPDATE xh_preference
SET group_name = 'Default'
WHERE group_name IS NULL;
ALTER TABLE xh_preference MODIFY group_name VARCHAR (255) NOT NULL;
--SQL Server
ALTER TABLE xh_preference
ADD group_name VARCHAR(255);
UPDATE xh_preference
SET group_name = 'Default'
WHERE group_name IS NULL;
ALTER TABLE xh_preference ALTER COLUMN group_name varchar(255) NOT NULL
- ClientError tracking gets a
userAlerted
flag to record whether or not the user was shown a pop-up dialog (vs. an error being reported quietly in the background).
β οΈ Note schema update required:
-- SQL Server
ALTER TABLE xh_client_error
ADD user_alerted bit NOT NULL DEFAULT 0
-- MySQL
ALTER TABLE xh_client_error
ADD user_alerted bit(1) NOT NULL DEFAULT 0
- Log archiving fixed for apps with a dash or underscore in their appCode.
- Removed plugin grails-x-frame-options-plugin. It will be put into the hoist-sencha project. It is only needed in hoist-sencha apps. Hoist-react apps will get this header set by nginx.
- Added plugin grails-x-frame-options-plugin
- This prevents XSS attacks by setting by default the most strict header setting
X-Frame-Options: DENY
on all responses from the grails server. You can relax this strict setting toSAMEORIGIN
(and will probably want to) by addingplugin.xframeoptions.sameOrigin = true
inside the grails clause of your application.groovy file (see piq-react for example).
- Gradle wrapper
4.8
- Updates of following libraries:
grailsVersion=3.3.1 β 3.3.5
grailsAsyncVersion=3.3.1 β 3.3.2
gormVersion=6.1.7.RELEASE β 6.1.9.RELEASE
- Note Grails update fixes support for the pathJar which helps fix long class path issues on Windows.
- Default theme is now the 'light' theme.
- This release unwinds the multi environment config concept. See #30 for the corresponding issue.
- To take this update, developers need to also migrate to v5.X.X of hoist-react or v2.X.X of hoist-sencha and follow these steps in each environment:
If you are doing this migration in a lower environment (dev, stage, uat) you may want to keep that environment's configs. For example, if you are migrating the dev env app to this new code, and there are configs in the dev_value column that you would like to keep in the dev environment, you first need to manually copy these values from the dev field to the prod field in the dev admin config UI.
Turn off your grails server and your webpack server (if applicable). Add a new 'value' column with allow null, allow null in the old 'prod_value' column, then copy prod_value values over to the new value column:
ALTER TABLE `xh_config` ADD `value` LONGTEXT;
ALTER TABLE `xh_config` MODIFY `prod_value` LONGTEXT;
ALTER TABLE xh_config
ADD value varchar(max) NULL
ALTER COLUMN prod_value varchar(max)
UPDATE `xh_config` SET `value` = `prod_value`
UPDATE xh_config SET value = prod_value
Update app code in environment to use hoist-core v3.0.0 and hoist-react v5.X.X or hoist-sencha v2.0.0.
Remove
supportedEnvironments = ['Staging', 'Development']
from grails-app/conf/application.groovy in your app. (Note that this line might appear twice - once near the top if an app has customized and once in the "hoistDefaults" section.)
Set value to not accept NULL and drop old columns:
ALTER TABLE `xh_config`
MODIFY `value` LONGTEXT NOT NULL;
ALTER TABLE `xh_config`
DROP COLUMN `beta_value`, `stage_value`, `dev_value`, `prod_value`;
ALTER TABLE xh_config
ALTER COLUMN value varchar(max) NOT NULL
ALTER TABLE xh_config
DROP COLUMN prod_value, dev_value, stage_value, beta_value
- None
- None
- This release includes updates around how the key
appCode
andappName
identifiers are read from application builds and what they represent. See #33 for the corresponding issue. This standardizes the meaning of these two identifiers on the client and server, and decouples the server-side appCode from the Gradle project name. - To take this update, applications must ensure their
build.gradle
file populates these variables within a grails.build.info file created by Grails itself during the build. See e.g. this commit to the Toolbox app for an example of this change. - Apps should audit their use of
Utils.appName
on the server-side and update toUtils.appCode
if they need to continue accessing the shortname variant.
- None
- None
- None
This release adds support for InstanceConfigUtils , a utility for loading configuration properties from an external YAML file once on startup and exposing them to the application as a map.
- These are intended to be minimal, low-level configs that apply to a particular deployed instance of the application and therefore are better sourced from a local file/volume vs. source code, JavaOpts, or database-driven ConfigService entries.
- Examples include the AppEnvironment as well as common Bootstrap requirements such as database credentials.
- See the class-level doc comment for additional details. Use of InstanceUtils is not required to take this release.
- Fix NPE breaking FeedbackService emailing. 8f07caf677dc0ed3a5ae6c8dd99dc59e2ffd8508
- Make LogLevel adjustments synchronous, so they reflect immediately in Admin console UI. dc387e885bea14b0443d5e984ccd74238fa6e7b7
Copyright Β© 2024 Extremely Heavy Industries Inc. - all rights reserved
π«βοΈπ [email protected] | https://xh.io