From bbb9c3c4cfe8ad96b70ed25977acab419fcdf10d Mon Sep 17 00:00:00 2001 From: lbwexler Date: Thu, 5 Sep 2024 22:18:53 -0400 Subject: [PATCH 1/9] Consolidate transport mechanism for AlertBanner --- .../controllers/io/xh/hoist/impl/XhController.groovy | 3 +++ .../io/xh/hoist/alertbanner/AlertBannerService.groovy | 4 +++- .../io/xh/hoist/environment/EnvironmentService.groovy | 10 ++++++---- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/grails-app/controllers/io/xh/hoist/impl/XhController.groovy b/grails-app/controllers/io/xh/hoist/impl/XhController.groovy index 5822f875..2b8af577 100644 --- a/grails-app/controllers/io/xh/hoist/impl/XhController.groovy +++ b/grails-app/controllers/io/xh/hoist/impl/XhController.groovy @@ -267,6 +267,9 @@ class XhController extends BaseController { //---------------------- // Alert Banner //---------------------- + /** + * @deprecated. Used by hoist-react <= 67.0.0 + */ def alertBanner() { renderJSON(alertBannerService.alertBanner) } diff --git a/grails-app/services/io/xh/hoist/alertbanner/AlertBannerService.groovy b/grails-app/services/io/xh/hoist/alertbanner/AlertBannerService.groovy index 88795e74..4a0e0608 100644 --- a/grails-app/services/io/xh/hoist/alertbanner/AlertBannerService.groovy +++ b/grails-app/services/io/xh/hoist/alertbanner/AlertBannerService.groovy @@ -27,7 +27,9 @@ import static java.lang.System.currentTimeMillis * * This class uses a single {@link io.xh.hoist.jsonblob.JsonBlob} to persist its state. * The published alert state is updated via the Hoist Admin console and is regularly refreshed - * on a timer to catch banner expiry. + * by EnvironmentService. + * + * For this service to be active, `xhAlertBannerConfig` config must be specified as `{enabled:true}`. */ @CompileStatic class AlertBannerService extends BaseService { diff --git a/grails-app/services/io/xh/hoist/environment/EnvironmentService.groovy b/grails-app/services/io/xh/hoist/environment/EnvironmentService.groovy index 48bae256..229955b8 100644 --- a/grails-app/services/io/xh/hoist/environment/EnvironmentService.groovy +++ b/grails-app/services/io/xh/hoist/environment/EnvironmentService.groovy @@ -11,6 +11,7 @@ import grails.plugins.GrailsPlugin import grails.util.GrailsUtil import grails.util.Holders import io.xh.hoist.BaseService +import io.xh.hoist.alertbanner.AlertBannerService import io.xh.hoist.config.ConfigService import io.xh.hoist.util.Utils import io.xh.hoist.websocket.WebSocketService @@ -24,9 +25,9 @@ class EnvironmentService extends BaseService { ConfigService configService WebSocketService webSocketService + AlertBannerService alertBannerService private TimeZone _appTimeZone - private Map _pollResult static clearCachesConfigs = ['xhAppTimeZone', 'xhEnvPollConfig'] @@ -66,6 +67,7 @@ class EnvironmentService extends BaseService { appTimeZoneOffset: appTz.getOffset(now), webSocketsEnabled: webSocketService.enabled, instanceName: clusterService.instanceName, + alertBanner: alertBannerService.alertBanner, pollConfig: configService.getMap('xhEnvPollConfig') ] @@ -88,12 +90,13 @@ class EnvironmentService extends BaseService { * Designed to be called frequently by client. Should be minimal and highly optimized. */ Map environmentPoll() { - return _pollResult ?= [ + return [ appCode : Utils.appCode, appVersion : Utils.appVersion, appBuild : Utils.appBuild, instanceName: clusterService.instanceName, - pollConfig : configService.getMap('xhEnvPollConfig'), + alertBanner : alertBannerService.alertBanner, + pollConfig : configService.getMap('xhEnvPollConfig') ] } @@ -119,7 +122,6 @@ class EnvironmentService extends BaseService { void clearCaches() { _appTimeZone = null - _pollResult = null super.clearCaches() } } From d85883257d23b84866492a3d15d53a6fb2471117 Mon Sep 17 00:00:00 2001 From: lbwexler Date: Thu, 5 Sep 2024 22:20:44 -0400 Subject: [PATCH 2/9] Consolidate transport mechanism for AlertBanner --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a784ffb9..21477bf3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## 22.0-SNAPSHOT - unreleased +### ⚙️ Technical +* Deliver AlertBanner data with environment polling. + ## 21.0.0 - 2024-09-03 ### 💥 Breaking Changes (upgrade difficulty: 🟢 LOW - latest Hoist React + DB col additions) From ac2b65de325b8803f04a642b2c23f4c2ee56b22b Mon Sep 17 00:00:00 2001 From: lbwexler Date: Thu, 5 Sep 2024 22:56:45 -0400 Subject: [PATCH 3/9] Consolidate transport mechanism for AlertBanner --- .../io/xh/hoist/alertbanner/AlertBannerService.groovy | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/grails-app/services/io/xh/hoist/alertbanner/AlertBannerService.groovy b/grails-app/services/io/xh/hoist/alertbanner/AlertBannerService.groovy index 4a0e0608..718d5195 100644 --- a/grails-app/services/io/xh/hoist/alertbanner/AlertBannerService.groovy +++ b/grails-app/services/io/xh/hoist/alertbanner/AlertBannerService.groovy @@ -74,7 +74,7 @@ class AlertBannerService extends BaseService { blob ? parseObject(blob.value) : emptyAlert } - void setAlertSpec(Map value) { + Map setAlertSpec(Map value) { def svc = jsonBlobService, blob = svc.list(blobType, blobOwner).find { it.name == blobName } if (blob) { @@ -105,7 +105,7 @@ class AlertBannerService extends BaseService { //---------------------------- // Implementation //----------------------------- - private void readFromSpec() { + private Map readFromSpec() { def conf = configService.getMap('xhAlertBannerConfig'), newSpec = emptyAlert @@ -119,6 +119,7 @@ class AlertBannerService extends BaseService { } _alertBanner.set(newSpec) + newSpec } void clearCaches() { From 19f77cff59033203ae67525f1067028acb1c1633 Mon Sep 17 00:00:00 2001 From: lbwexler Date: Thu, 5 Sep 2024 23:21:19 -0400 Subject: [PATCH 4/9] Consolidate transport mechanism for AlertBanner --- .../io/xh/hoist/alertbanner/AlertBannerService.groovy | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/grails-app/services/io/xh/hoist/alertbanner/AlertBannerService.groovy b/grails-app/services/io/xh/hoist/alertbanner/AlertBannerService.groovy index 718d5195..47925ac8 100644 --- a/grails-app/services/io/xh/hoist/alertbanner/AlertBannerService.groovy +++ b/grails-app/services/io/xh/hoist/alertbanner/AlertBannerService.groovy @@ -7,7 +7,6 @@ package io.xh.hoist.alertbanner - import groovy.transform.CompileStatic import io.xh.hoist.BaseService import io.xh.hoist.cache.CachedValue @@ -74,7 +73,7 @@ class AlertBannerService extends BaseService { blob ? parseObject(blob.value) : emptyAlert } - Map setAlertSpec(Map value) { + void setAlertSpec(Map value) { def svc = jsonBlobService, blob = svc.list(blobType, blobOwner).find { it.name == blobName } if (blob) { @@ -105,7 +104,7 @@ class AlertBannerService extends BaseService { //---------------------------- // Implementation //----------------------------- - private Map readFromSpec() { + private void readFromSpec() { def conf = configService.getMap('xhAlertBannerConfig'), newSpec = emptyAlert @@ -119,7 +118,6 @@ class AlertBannerService extends BaseService { } _alertBanner.set(newSpec) - newSpec } void clearCaches() { From 8306ebeabc4abc72fd26f1f1b92f589f15c9bba8 Mon Sep 17 00:00:00 2001 From: Anselm McClain Date: Tue, 17 Sep 2024 11:10:18 -0700 Subject: [PATCH 5/9] Minor comment / changelog cleanups --- CHANGELOG.md | 5 ++--- .../controllers/io/xh/hoist/impl/XhController.groovy | 2 +- .../io/xh/hoist/environment/EnvironmentService.groovy | 8 +++++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 119edbd7..9b5eca4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ ### ⚙️ Technical +* Enhanced the `xh/environmentPoll` payload to include any active Alert Banner spec. Clients running + `hoist-react >= 67.1` 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. @@ -38,9 +40,6 @@ * Improved serialization efficiency of replicated `Cache` and `CachedValue`. -### ⚙️ Technical -* Deliver AlertBanner data with environment polling. - ## 21.0.0 - 2024-09-03 ### 💥 Breaking Changes (upgrade difficulty: 🟢 LOW - latest Hoist React + DB col additions) diff --git a/grails-app/controllers/io/xh/hoist/impl/XhController.groovy b/grails-app/controllers/io/xh/hoist/impl/XhController.groovy index fc25d491..cc489c6a 100644 --- a/grails-app/controllers/io/xh/hoist/impl/XhController.groovy +++ b/grails-app/controllers/io/xh/hoist/impl/XhController.groovy @@ -268,7 +268,7 @@ class XhController extends BaseController { // Alert Banner //---------------------- /** - * @deprecated. Used by hoist-react <= 67.0.0 + * @deprecated - used by hoist-react <= 67.0.0, now nested within {@link #environmentPoll}. */ def alertBanner() { renderJSON(alertBannerService.alertBanner) diff --git a/grails-app/services/io/xh/hoist/environment/EnvironmentService.groovy b/grails-app/services/io/xh/hoist/environment/EnvironmentService.groovy index 229955b8..43543e81 100644 --- a/grails-app/services/io/xh/hoist/environment/EnvironmentService.groovy +++ b/grails-app/services/io/xh/hoist/environment/EnvironmentService.groovy @@ -19,7 +19,9 @@ import io.xh.hoist.websocket.WebSocketService /** * Service with metadata describing the runtime environment of Hoist and this application. - * For the AppEnvironment (e.g. Development/Production), reference `Utils.appEnvironment`. + * + * If you are simply looking to read the `AppEnvironment` (e.g. Development/Production), use + * the static {@link io.xh.hoist.util.Utils#getAppEnvironment} instead. */ class EnvironmentService extends BaseService { @@ -86,8 +88,8 @@ class EnvironmentService extends BaseService { } /** - * Report server version and instance identity to the client. - * Designed to be called frequently by client. Should be minimal and highly optimized. + * Report server version, instance identity, and any active alert banner to the client. + * Designed for rapid polling - keep this minimal and highly optimized. */ Map environmentPoll() { return [ From ca4368b909bbe747e2fceeda3cc89ad4bec5d85a Mon Sep 17 00:00:00 2001 From: Anselm McClain Date: Tue, 17 Sep 2024 11:21:03 -0700 Subject: [PATCH 6/9] Minor comment / changelog cleanups --- CHANGELOG.md | 2 +- grails-app/controllers/io/xh/hoist/impl/XhController.groovy | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b5eca4a..57dd9f98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ ### ⚙️ Technical * Enhanced the `xh/environmentPoll` payload to include any active Alert Banner spec. Clients running - `hoist-react >= 67.1` will leverage this to avoid an extra polling request. + `hoist-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. diff --git a/grails-app/controllers/io/xh/hoist/impl/XhController.groovy b/grails-app/controllers/io/xh/hoist/impl/XhController.groovy index cc489c6a..092e5084 100644 --- a/grails-app/controllers/io/xh/hoist/impl/XhController.groovy +++ b/grails-app/controllers/io/xh/hoist/impl/XhController.groovy @@ -268,7 +268,7 @@ class XhController extends BaseController { // Alert Banner //---------------------- /** - * @deprecated - used by hoist-react <= 67.0.0, now nested within {@link #environmentPoll}. + * @deprecated - used by hoist-react <= 67, now nested within {@link #environmentPoll}. */ def alertBanner() { renderJSON(alertBannerService.alertBanner) From c04cf986a15636adf68b72ec420569e435507151 Mon Sep 17 00:00:00 2001 From: Anselm McClain Date: Tue, 17 Sep 2024 11:24:57 -0700 Subject: [PATCH 7/9] Update bootstrap for `xhAlertBannerConfig` + I think it's safe to assume that any apps bootstrapping that config at this point will start on hoist-react v68+ --- grails-app/init/io/xh/hoist/BootStrap.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grails-app/init/io/xh/hoist/BootStrap.groovy b/grails-app/init/io/xh/hoist/BootStrap.groovy index 0a5b21ea..f19e3453 100644 --- a/grails-app/init/io/xh/hoist/BootStrap.groovy +++ b/grails-app/init/io/xh/hoist/BootStrap.groovy @@ -80,10 +80,10 @@ class BootStrap implements LogSupport { ], xhAlertBannerConfig: [ valueType: 'json', - defaultValue: [enabled: true, interval: 30], + defaultValue: [enabled: true], clientVisible: true, groupName: 'xh.io', - note: 'Configures support for showing an app-wide alert banner.\n\nAdmins configure and activate alert banners from the Hoist Admin console. To generally enable this system, set "enabled" to true and "interval" to a positive value (in seconds) to control how often connected apps check for a new alert.' + note: 'Configures support for showing an app-wide alert banner.\n\nAdmins configure and activate alert banners from the Hoist Admin console. To generally enable this system, set "enabled" to true. The xhEnvPollConfig.interval config governs client polling for updates.' ], xhAppInstances: [ valueType: 'json', From 3280fe5b99a9a7390f966757e71553317bb6a737 Mon Sep 17 00:00:00 2001 From: Anselm McClain Date: Tue, 17 Sep 2024 11:25:46 -0700 Subject: [PATCH 8/9] Tweak --- .../io/xh/hoist/alertbanner/AlertBannerService.groovy | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/grails-app/services/io/xh/hoist/alertbanner/AlertBannerService.groovy b/grails-app/services/io/xh/hoist/alertbanner/AlertBannerService.groovy index 316ed84f..c62cd9d1 100644 --- a/grails-app/services/io/xh/hoist/alertbanner/AlertBannerService.groovy +++ b/grails-app/services/io/xh/hoist/alertbanner/AlertBannerService.groovy @@ -102,10 +102,9 @@ class AlertBannerService extends BaseService { // Implementation //----------------------------- private void readFromSpec() { - def conf = configService.getMap('xhAlertBannerConfig'), - newSpec = emptyAlert + def newSpec = emptyAlert - if (conf.enabled) { + if (configService.getMap('xhAlertBannerConfig').enabled) { def spec = getAlertSpec(), expires = spec.expires as Long From 5c68c11f062bd472ae4d806f1bb7878e9e54c344 Mon Sep 17 00:00:00 2001 From: Anselm McClain Date: Tue, 17 Sep 2024 11:28:49 -0700 Subject: [PATCH 9/9] Tweak --- .../services/io/xh/hoist/environment/EnvironmentService.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grails-app/services/io/xh/hoist/environment/EnvironmentService.groovy b/grails-app/services/io/xh/hoist/environment/EnvironmentService.groovy index 43543e81..eac52df3 100644 --- a/grails-app/services/io/xh/hoist/environment/EnvironmentService.groovy +++ b/grails-app/services/io/xh/hoist/environment/EnvironmentService.groovy @@ -31,7 +31,7 @@ class EnvironmentService extends BaseService { private TimeZone _appTimeZone - static clearCachesConfigs = ['xhAppTimeZone', 'xhEnvPollConfig'] + static clearCachesConfigs = ['xhAppTimeZone'] /** * Official TimeZone for this application - e.g. the zone of the head office or trading center.