From f65f245688e7942f5af9686984413520a4846979 Mon Sep 17 00:00:00 2001 From: Mark Daugherty Date: Tue, 12 Jan 2021 10:45:15 -0600 Subject: [PATCH 01/47] versions. --- all/pom.xml | 2 +- bundle/pom.xml | 2 +- pom.xml | 2 +- ui.apps.structure/pom.xml | 2 +- ui.apps/pom.xml | 2 +- ui.config/pom.xml | 2 +- ui.content/pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/all/pom.xml b/all/pom.xml index 0a3a32dc..d2f0f834 100644 --- a/all/pom.xml +++ b/all/pom.xml @@ -6,7 +6,7 @@ org.cid15.aem.groovy.console aem-groovy-console - 17.0.0 + 17.1.0-SNAPSHOT aem-groovy-console-all diff --git a/bundle/pom.xml b/bundle/pom.xml index 07898a7f..807af4fd 100644 --- a/bundle/pom.xml +++ b/bundle/pom.xml @@ -8,7 +8,7 @@ org.cid15.aem.groovy.console aem-groovy-console - 17.0.0 + 17.1.0-SNAPSHOT aem-groovy-console-bundle diff --git a/pom.xml b/pom.xml index 7d787c2d..1e072153 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ org.cid15.aem.groovy.console aem-groovy-console pom - 17.0.0 + 17.1.0-SNAPSHOT AEM Groovy Console The AEM Groovy Console provides an interface for running Groovy scripts in the AEM container. Scripts can be diff --git a/ui.apps.structure/pom.xml b/ui.apps.structure/pom.xml index 9beff4ee..70bb84cf 100644 --- a/ui.apps.structure/pom.xml +++ b/ui.apps.structure/pom.xml @@ -5,7 +5,7 @@ org.cid15.aem.groovy.console aem-groovy-console - 17.0.0 + 17.1.0-SNAPSHOT aem-groovy-console-ui.apps.structure diff --git a/ui.apps/pom.xml b/ui.apps/pom.xml index bf422994..f50810ea 100644 --- a/ui.apps/pom.xml +++ b/ui.apps/pom.xml @@ -5,7 +5,7 @@ org.cid15.aem.groovy.console aem-groovy-console - 17.0.0 + 17.1.0-SNAPSHOT aem-groovy-console-ui.apps diff --git a/ui.config/pom.xml b/ui.config/pom.xml index 07203d93..e78aa31e 100644 --- a/ui.config/pom.xml +++ b/ui.config/pom.xml @@ -5,7 +5,7 @@ org.cid15.aem.groovy.console aem-groovy-console - 17.0.0 + 17.1.0-SNAPSHOT aem-groovy-console-ui.config diff --git a/ui.content/pom.xml b/ui.content/pom.xml index e66ab83d..3e023113 100644 --- a/ui.content/pom.xml +++ b/ui.content/pom.xml @@ -5,7 +5,7 @@ org.cid15.aem.groovy.console aem-groovy-console - 17.0.0 + 17.1.0-SNAPSHOT aem-groovy-console-ui.content From 05aff536a9aa0dea5c0f92175dc6782d0ebe5652 Mon Sep 17 00:00:00 2001 From: Barry d'Hoine Date: Tue, 13 Dec 2022 16:27:30 +0100 Subject: [PATCH 02/47] Create separate groovyconsole-config package to avoid overwrites --- ui.config/src/main/content/META-INF/vault/filter.xml | 2 +- ...apping.impl.ServiceUserMapperImpl.amended-groovy-console.xml | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename ui.config/src/main/content/jcr_root/apps/{groovyconsole => groovyconsole-config}/osgiconfig/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-groovy-console.xml (100%) diff --git a/ui.config/src/main/content/META-INF/vault/filter.xml b/ui.config/src/main/content/META-INF/vault/filter.xml index 9582439f..b69b60a7 100644 --- a/ui.config/src/main/content/META-INF/vault/filter.xml +++ b/ui.config/src/main/content/META-INF/vault/filter.xml @@ -1,4 +1,4 @@ - + diff --git a/ui.config/src/main/content/jcr_root/apps/groovyconsole/osgiconfig/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-groovy-console.xml b/ui.config/src/main/content/jcr_root/apps/groovyconsole-config/osgiconfig/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-groovy-console.xml similarity index 100% rename from ui.config/src/main/content/jcr_root/apps/groovyconsole/osgiconfig/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-groovy-console.xml rename to ui.config/src/main/content/jcr_root/apps/groovyconsole-config/osgiconfig/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-groovy-console.xml From 3210010b65476c9510110f9e8ff228dfd97252ca Mon Sep 17 00:00:00 2001 From: Barry d'Hoine Date: Tue, 13 Dec 2022 16:29:33 +0100 Subject: [PATCH 03/47] Update project structure Add sling-maven-plugin Change to wcmio-content-package-maven-plugin Use io.wcm.maven.aem-cloud-dependencies for SDK --- all/pom.xml | 26 +++---- bundle/pom.xml | 4 ++ .../audit/impl/DefaultAuditServiceSpec.groovy | 6 +- .../DefaultGroovyConsoleServiceSpec.groovy | 22 +++--- pom.xml | 72 +++++++++++++++---- ui.apps/pom.xml | 8 +-- ui.config/pom.xml | 4 +- ui.content/pom.xml | 8 +-- 8 files changed, 91 insertions(+), 59 deletions(-) diff --git a/all/pom.xml b/all/pom.xml index d2f0f834..a6ca1409 100644 --- a/all/pom.xml +++ b/all/pom.xml @@ -65,13 +65,9 @@ - com.day.jcr.vault - content-package-maven-plugin + io.wcm.maven.plugins + wcmio-content-package-maven-plugin true - - true - true - maven-clean-plugin @@ -98,8 +94,8 @@ - com.day.jcr.vault - content-package-maven-plugin + io.wcm.maven.plugins + wcmio-content-package-maven-plugin install-package @@ -107,8 +103,7 @@ install - http://${aem.host}:${aem.port}/crx/packmgr/service.jsp - true + http://${aem.host}:${aem.port}/crx/packmgr/service.jsp @@ -124,8 +119,8 @@ - com.day.jcr.vault - content-package-maven-plugin + io.wcm.maven.plugins + wcmio-content-package-maven-plugin install-package @@ -157,8 +152,8 @@ - com.day.jcr.vault - content-package-maven-plugin + io.wcm.maven.plugins + wcmio-content-package-maven-plugin install-package-publish @@ -166,8 +161,7 @@ install - http://${aem.publish.host}:${aem.publish.port}/crx/packmgr/service.jsp - true + http://${aem.publish.host}:${aem.publish.port}/crx/packmgr/service.jsp diff --git a/bundle/pom.xml b/bundle/pom.xml index 807af4fd..3c7d736a 100644 --- a/bundle/pom.xml +++ b/bundle/pom.xml @@ -95,6 +95,10 @@ + + org.apache.sling + sling-maven-plugin + diff --git a/bundle/src/test/groovy/org/cid15/aem/groovy/console/audit/impl/DefaultAuditServiceSpec.groovy b/bundle/src/test/groovy/org/cid15/aem/groovy/console/audit/impl/DefaultAuditServiceSpec.groovy index e190891c..d42343f8 100644 --- a/bundle/src/test/groovy/org/cid15/aem/groovy/console/audit/impl/DefaultAuditServiceSpec.groovy +++ b/bundle/src/test/groovy/org/cid15/aem/groovy/console/audit/impl/DefaultAuditServiceSpec.groovy @@ -1,11 +1,11 @@ package org.cid15.aem.groovy.console.audit.impl -import org.cid15.aem.groovy.console.api.impl.RequestScriptContext -import org.cid15.aem.groovy.console.configuration.impl.DefaultConfigurationService import com.icfolson.aem.prosper.specs.ProsperSpec import org.apache.commons.lang3.exception.ExceptionUtils -import org.apache.sling.jcr.resource.JcrResourceConstants +import org.apache.sling.jcr.resource.api.JcrResourceConstants +import org.cid15.aem.groovy.console.api.impl.RequestScriptContext import org.cid15.aem.groovy.console.audit.AuditRecord +import org.cid15.aem.groovy.console.configuration.impl.DefaultConfigurationService import org.cid15.aem.groovy.console.response.impl.DefaultRunScriptResponse import spock.lang.Shared import spock.lang.Unroll diff --git a/bundle/src/test/groovy/org/cid15/aem/groovy/console/impl/DefaultGroovyConsoleServiceSpec.groovy b/bundle/src/test/groovy/org/cid15/aem/groovy/console/impl/DefaultGroovyConsoleServiceSpec.groovy index 5ac7290f..c94955e5 100755 --- a/bundle/src/test/groovy/org/cid15/aem/groovy/console/impl/DefaultGroovyConsoleServiceSpec.groovy +++ b/bundle/src/test/groovy/org/cid15/aem/groovy/console/impl/DefaultGroovyConsoleServiceSpec.groovy @@ -4,14 +4,14 @@ import com.day.cq.commons.jcr.JcrConstants import com.day.cq.replication.Replicator import com.day.cq.search.QueryBuilder import com.google.common.base.Charsets +import com.icfolson.aem.prosper.specs.ProsperSpec +import org.apache.sling.event.jobs.JobManager +import org.apache.sling.jcr.resource.api.JcrResourceConstants import org.cid15.aem.groovy.console.GroovyConsoleService import org.cid15.aem.groovy.console.api.impl.RequestScriptContext import org.cid15.aem.groovy.console.api.impl.RequestScriptData -import org.cid15.aem.groovy.console.configuration.ConfigurationService -import com.icfolson.aem.prosper.specs.ProsperSpec -import org.apache.sling.event.jobs.JobManager -import org.apache.sling.jcr.resource.JcrResourceConstants import org.cid15.aem.groovy.console.audit.AuditService +import org.cid15.aem.groovy.console.configuration.ConfigurationService import org.cid15.aem.groovy.console.constants.GroovyConsoleConstants import org.cid15.aem.groovy.console.extension.impl.DefaultBindingExtensionProvider import org.cid15.aem.groovy.console.extension.impl.DefaultExtensionService @@ -52,11 +52,11 @@ class DefaultGroovyConsoleServiceSpec extends ProsperSpec { def outputStream = new ByteArrayOutputStream() def scriptContext = new RequestScriptContext( - request: request, - response: response, - outputStream: outputStream, - printStream: new PrintStream(outputStream, true, Charsets.UTF_8.name()), - script: scriptAsString + request: request, + response: response, + outputStream: outputStream, + printStream: new PrintStream(outputStream, true, Charsets.UTF_8.name()), + script: scriptAsString ) when: @@ -87,7 +87,7 @@ class DefaultGroovyConsoleServiceSpec extends ProsperSpec { assertNodeExists(PATH_SCRIPTS_FOLDER, JcrConstants.NT_FOLDER) assertNodeExists(PATH_FILE, JcrConstants.NT_FILE) assertNodeExists(PATH_FILE_CONTENT, JcrConstants.NT_RESOURCE, - [(JcrConstants.JCR_MIMETYPE): "application/octet-stream"]) + [(JcrConstants.JCR_MIMETYPE): "application/octet-stream"]) and: assert session.getNode(PATH_FILE_CONTENT).get(JcrConstants.JCR_DATA).stream.text == scriptAsString @@ -113,4 +113,4 @@ class DefaultGroovyConsoleServiceSpec extends ProsperSpec { private Map getParameterMap() { [(GroovyConsoleConstants.FILE_NAME): (SCRIPT_NAME), (SCRIPT): scriptAsString] } -} \ No newline at end of file +} diff --git a/pom.xml b/pom.xml index 1e072153..b6008a21 100644 --- a/pom.xml +++ b/pom.xml @@ -139,6 +139,31 @@ + + autoInstallBundle + + false + + + + + + org.apache.sling + sling-maven-plugin + + + install-bundle + + install + + + + + + + + + autoInstallPackage @@ -160,8 +185,8 @@ - com.day.jcr.vault - content-package-maven-plugin + io.wcm.maven.plugins + wcmio-content-package-maven-plugin install-package @@ -169,7 +194,7 @@ install - http://${aem.host}:${aem.port}/crx/packmgr/service.jsp + http://${aem.host}:${aem.port}/crx/packmgr/service.jsp @@ -200,8 +225,8 @@ - com.day.jcr.vault - content-package-maven-plugin + io.wcm.maven.plugins + wcmio-content-package-maven-plugin install-package-publish @@ -209,7 +234,9 @@ install - http://${aem.publish.host}:${aem.publish.port}/crx/packmgr/service.jsp + + http://${aem.publish.host}:${aem.publish.port}/crx/packmgr/service.jsp + @@ -319,6 +346,15 @@ maven-deploy-plugin 2.8.2 + + org.apache.sling + sling-maven-plugin + 2.4.0 + + http://${aem.host}:${aem.port}/system/console + WebConsole + + org.apache.jackrabbit filevault-package-maven-plugin @@ -349,12 +385,10 @@ - com.day.jcr.vault - content-package-maven-plugin - 1.0.2 + io.wcm.maven.plugins + wcmio-content-package-maven-plugin + 2.1.2 - http://${aem.host}:${aem.port}/crx/packmgr/service.jsp - true ${vault.user} ${vault.password} @@ -365,6 +399,13 @@ + + org.jetbrains + annotations + 23.0.0 + provided + + org.codehaus.groovy @@ -389,10 +430,11 @@ - com.adobe.aem - aem-sdk-api - ${aem.sdk.version} - provided + io.wcm.maven + io.wcm.maven.aem-cloud-dependencies + ${aem.sdk.version}.0000 + pom + import diff --git a/ui.apps/pom.xml b/ui.apps/pom.xml index f50810ea..66b1d662 100644 --- a/ui.apps/pom.xml +++ b/ui.apps/pom.xml @@ -41,13 +41,9 @@ - com.day.jcr.vault - content-package-maven-plugin + io.wcm.maven.plugins + wcmio-content-package-maven-plugin true - - true - true - diff --git a/ui.config/pom.xml b/ui.config/pom.xml index e78aa31e..cd0bb45f 100644 --- a/ui.config/pom.xml +++ b/ui.config/pom.xml @@ -30,8 +30,8 @@ - com.day.jcr.vault - content-package-maven-plugin + io.wcm.maven.plugins + wcmio-content-package-maven-plugin diff --git a/ui.content/pom.xml b/ui.content/pom.xml index 3e023113..16c180f1 100644 --- a/ui.content/pom.xml +++ b/ui.content/pom.xml @@ -46,13 +46,9 @@ - com.day.jcr.vault - content-package-maven-plugin + io.wcm.maven.plugins + wcmio-content-package-maven-plugin true - - true - true - From 654e1a18a093d9aa8ea1f6108a7808a66b8ab4d6 Mon Sep 17 00:00:00 2001 From: Barry d'Hoine Date: Tue, 13 Dec 2022 16:29:49 +0100 Subject: [PATCH 04/47] Add IntelliJ run configurations --- .run/[author] aem-groovy-console.run.xml | 30 ++++++++++++++++++++++++ .run/[author] all.run.xml | 30 ++++++++++++++++++++++++ .run/[author] bundle.run.xml | 30 ++++++++++++++++++++++++ .run/[author] ui.apps.run.xml | 30 ++++++++++++++++++++++++ .run/[author] ui.config.run.xml | 30 ++++++++++++++++++++++++ .run/[author] ui.content.run.xml | 30 ++++++++++++++++++++++++ 6 files changed, 180 insertions(+) create mode 100644 .run/[author] aem-groovy-console.run.xml create mode 100644 .run/[author] all.run.xml create mode 100644 .run/[author] bundle.run.xml create mode 100644 .run/[author] ui.apps.run.xml create mode 100644 .run/[author] ui.config.run.xml create mode 100644 .run/[author] ui.content.run.xml diff --git a/.run/[author] aem-groovy-console.run.xml b/.run/[author] aem-groovy-console.run.xml new file mode 100644 index 00000000..33ca3ad4 --- /dev/null +++ b/.run/[author] aem-groovy-console.run.xml @@ -0,0 +1,30 @@ + + + + + + + + \ No newline at end of file diff --git a/.run/[author] all.run.xml b/.run/[author] all.run.xml new file mode 100644 index 00000000..9dcd6716 --- /dev/null +++ b/.run/[author] all.run.xml @@ -0,0 +1,30 @@ + + + + + + + + \ No newline at end of file diff --git a/.run/[author] bundle.run.xml b/.run/[author] bundle.run.xml new file mode 100644 index 00000000..54e7c556 --- /dev/null +++ b/.run/[author] bundle.run.xml @@ -0,0 +1,30 @@ + + + + + + + + \ No newline at end of file diff --git a/.run/[author] ui.apps.run.xml b/.run/[author] ui.apps.run.xml new file mode 100644 index 00000000..8e599507 --- /dev/null +++ b/.run/[author] ui.apps.run.xml @@ -0,0 +1,30 @@ + + + + + + + + \ No newline at end of file diff --git a/.run/[author] ui.config.run.xml b/.run/[author] ui.config.run.xml new file mode 100644 index 00000000..a6f93f33 --- /dev/null +++ b/.run/[author] ui.config.run.xml @@ -0,0 +1,30 @@ + + + + + + + + \ No newline at end of file diff --git a/.run/[author] ui.content.run.xml b/.run/[author] ui.content.run.xml new file mode 100644 index 00000000..572cbbd9 --- /dev/null +++ b/.run/[author] ui.content.run.xml @@ -0,0 +1,30 @@ + + + + + + + + \ No newline at end of file From 6dec375c74a578f8d91f586c929bc50139bd0b3c Mon Sep 17 00:00:00 2001 From: Barry d'Hoine Date: Tue, 13 Dec 2022 16:30:06 +0100 Subject: [PATCH 05/47] Add replication resource listener --- .../api/impl/ResourceScriptContext.groovy | 23 +++++++ .../ReplicatedScriptListener.groovy | 65 +++++++++++++++++++ .../groovyconsole/replication/.content.xml | 6 ++ 3 files changed, 94 insertions(+) create mode 100644 bundle/src/main/groovy/org/cid15/aem/groovy/console/api/impl/ResourceScriptContext.groovy create mode 100644 bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy create mode 100644 ui.content/src/main/content/jcr_root/var/groovyconsole/replication/.content.xml diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/api/impl/ResourceScriptContext.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/api/impl/ResourceScriptContext.groovy new file mode 100644 index 00000000..ab4feb1c --- /dev/null +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/api/impl/ResourceScriptContext.groovy @@ -0,0 +1,23 @@ +package org.cid15.aem.groovy.console.api.impl + +import groovy.transform.TupleConstructor +import org.apache.sling.api.resource.ResourceResolver +import org.cid15.aem.groovy.console.api.context.ScriptContext + +@TupleConstructor +class ResourceScriptContext implements ScriptContext { + ResourceResolver resourceResolver + + ByteArrayOutputStream outputStream + + PrintStream printStream + + String script + + String data + + @Override + public String getUserId() { + return resourceResolver.userID + } +} diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy new file mode 100644 index 00000000..8a4cd8a6 --- /dev/null +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy @@ -0,0 +1,65 @@ +package org.cid15.aem.groovy.console.replication + +import com.day.cq.commons.jcr.JcrConstants +import com.google.common.base.Charsets +import org.apache.sling.api.resource.ResourceResolver +import org.apache.sling.api.resource.ResourceResolverFactory +import org.apache.sling.api.resource.observation.ResourceChange +import org.apache.sling.api.resource.observation.ResourceChangeListener +import org.cid15.aem.groovy.console.GroovyConsoleService +import org.cid15.aem.groovy.console.api.context.ScriptContext +import org.cid15.aem.groovy.console.api.impl.ResourceScriptContext +import org.jetbrains.annotations.NotNull +import org.osgi.service.component.annotations.Component +import org.osgi.service.component.annotations.Reference + +import javax.jcr.Session + +import static com.google.common.base.Preconditions.checkNotNull + +@Component(service = ResourceChangeListener.class, property = [ + "resource.paths=/var/groovyconsole/replication/**/*.groovy", + "resource.change.types=ADDED" +]) +public class ReplicatedScriptListener implements ResourceChangeListener { + @Reference + private GroovyConsoleService consoleService; + + @Reference + private ResourceResolverFactory resourceResolverFactory; + + @Override + public void onChange(@NotNull List list) { + list.each { change -> + resourceResolverFactory.getServiceResourceResolver(null).withCloseable { resourceResolver -> + consoleService.runScript(getScriptContext(resourceResolver, change.path)); + } + } + } + + private ScriptContext getScriptContext(ResourceResolver resourceResolver, String scriptPath) { + def outputStream = new ByteArrayOutputStream() + + new ResourceScriptContext( + resourceResolver: resourceResolver, + outputStream: outputStream, + printStream: new PrintStream(outputStream, true, Charsets.UTF_8.name()), + script: checkNotNull(loadScript(resourceResolver, scriptPath), "Script cannot be empty.") + ) + } + + private String loadScript(ResourceResolver resourceResolver, String scriptPath) { + def session = resourceResolver.adaptTo(Session) + + def binary = session.getNode(scriptPath) + .getNode(JcrConstants.JCR_CONTENT) + .getProperty(JcrConstants.JCR_DATA) + .binary + + def script = binary.stream.text + + binary.dispose() + + script + } +} diff --git a/ui.content/src/main/content/jcr_root/var/groovyconsole/replication/.content.xml b/ui.content/src/main/content/jcr_root/var/groovyconsole/replication/.content.xml new file mode 100644 index 00000000..a5b18056 --- /dev/null +++ b/ui.content/src/main/content/jcr_root/var/groovyconsole/replication/.content.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file From cd48d52c798ae4ea64551211e266fea3879bec95 Mon Sep 17 00:00:00 2001 From: Barry d'Hoine Date: Wed, 14 Dec 2022 01:14:06 +0100 Subject: [PATCH 06/47] Refactor project initialisation Move to repoinit scripts Use /conf path because of cloud service restrictions on /var Update SDK version --- .../console/constants/GroovyConsoleConstants.groovy | 2 +- .../replication/ReplicatedScriptListener.groovy | 6 ++++-- pom.xml | 2 +- .../src/main/content/META-INF/vault/filter.xml | 1 + ...oinit.RepositoryInitializer-groovyconsole.config | 13 +++++++++++++ ...ServiceUserMapperImpl.amended-groovy-console.xml | 2 +- .../src/main/content/META-INF/vault/filter.xml | 4 +--- .../src/main/content/jcr_root/_rep_policy.xml | 8 -------- .../groovyconsole/scripts/samples/.content.xml | 1 + .../scripts/samples/CreateOsgiConfigurations.groovy | 0 .../scripts/samples/CreatePackage.groovy | 0 .../scripts/samples/DeleteOsgiConfigurations.groovy | 0 .../scripts/samples/FindOrphanedComponents.groovy | 0 .../scripts/samples/FindPagesWithProperty.groovy | 0 .../scripts/samples/FindPagesWithTemplate.groovy | 0 .../scripts/samples/FindReferences.groovy | 0 .../scripts/samples/FulltextQuery.groovy | 0 .../groovyconsole/scripts/samples/JcrSearch.groovy | 0 .../scripts/samples/ListTemplates.groovy | 0 .../scripts/samples/UpdateOsgiConfiguration.groovy | 0 .../scripts/samples/UpdatePageTitles.groovy | 0 .../system/groovy-console-system-user/.content.xml | 6 ------ .../content/jcr_root/var/groovyconsole/.content.xml | 4 ---- .../jcr_root/var/groovyconsole/audit/.content.xml | 5 ----- .../var/groovyconsole/audit/_rep_policy.xml | 8 -------- .../var/groovyconsole/replication/.content.xml | 6 ------ .../jcr_root/var/groovyconsole/scripts/.content.xml | 6 ------ 27 files changed, 23 insertions(+), 51 deletions(-) create mode 100644 ui.config/src/main/content/jcr_root/apps/groovyconsole-config/osgiconfig/config/org.apache.sling.jcr.repoinit.RepositoryInitializer-groovyconsole.config delete mode 100644 ui.content/src/main/content/jcr_root/_rep_policy.xml rename ui.content/src/main/content/jcr_root/{var => conf}/groovyconsole/scripts/samples/.content.xml (85%) rename ui.content/src/main/content/jcr_root/{var => conf}/groovyconsole/scripts/samples/CreateOsgiConfigurations.groovy (100%) rename ui.content/src/main/content/jcr_root/{var => conf}/groovyconsole/scripts/samples/CreatePackage.groovy (100%) rename ui.content/src/main/content/jcr_root/{var => conf}/groovyconsole/scripts/samples/DeleteOsgiConfigurations.groovy (100%) rename ui.content/src/main/content/jcr_root/{var => conf}/groovyconsole/scripts/samples/FindOrphanedComponents.groovy (100%) rename ui.content/src/main/content/jcr_root/{var => conf}/groovyconsole/scripts/samples/FindPagesWithProperty.groovy (100%) rename ui.content/src/main/content/jcr_root/{var => conf}/groovyconsole/scripts/samples/FindPagesWithTemplate.groovy (100%) rename ui.content/src/main/content/jcr_root/{var => conf}/groovyconsole/scripts/samples/FindReferences.groovy (100%) rename ui.content/src/main/content/jcr_root/{var => conf}/groovyconsole/scripts/samples/FulltextQuery.groovy (100%) rename ui.content/src/main/content/jcr_root/{var => conf}/groovyconsole/scripts/samples/JcrSearch.groovy (100%) rename ui.content/src/main/content/jcr_root/{var => conf}/groovyconsole/scripts/samples/ListTemplates.groovy (100%) rename ui.content/src/main/content/jcr_root/{var => conf}/groovyconsole/scripts/samples/UpdateOsgiConfiguration.groovy (100%) rename ui.content/src/main/content/jcr_root/{var => conf}/groovyconsole/scripts/samples/UpdatePageTitles.groovy (100%) delete mode 100644 ui.content/src/main/content/jcr_root/home/users/system/groovy-console-system-user/.content.xml delete mode 100644 ui.content/src/main/content/jcr_root/var/groovyconsole/.content.xml delete mode 100644 ui.content/src/main/content/jcr_root/var/groovyconsole/audit/.content.xml delete mode 100644 ui.content/src/main/content/jcr_root/var/groovyconsole/audit/_rep_policy.xml delete mode 100644 ui.content/src/main/content/jcr_root/var/groovyconsole/replication/.content.xml delete mode 100644 ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/.content.xml diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/constants/GroovyConsoleConstants.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/constants/GroovyConsoleConstants.groovy index c0251e3e..5ef69bca 100644 --- a/bundle/src/main/groovy/org/cid15/aem/groovy/console/constants/GroovyConsoleConstants.groovy +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/constants/GroovyConsoleConstants.groovy @@ -5,7 +5,7 @@ import com.google.common.net.MediaType class GroovyConsoleConstants { - public static final String SYSTEM_USER_NAME = "groovy-console-system-user" + public static final String SYSTEM_USER_NAME = "aem-groovy-console-service" public static final String PATH_CONSOLE_ROOT = "/var/groovyconsole" diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy index 8a4cd8a6..e125dbd7 100644 --- a/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy @@ -17,8 +17,9 @@ import javax.jcr.Session import static com.google.common.base.Preconditions.checkNotNull -@Component(service = ResourceChangeListener.class, property = [ - "resource.paths=/var/groovyconsole/replication/**/*.groovy", +// TODO: Use const references for properties +@Component(property = [ + "resource.paths=/conf/groovyconsole/distribution", "resource.change.types=ADDED" ]) public class ReplicatedScriptListener implements ResourceChangeListener { @@ -51,6 +52,7 @@ public class ReplicatedScriptListener implements ResourceChangeListener { private String loadScript(ResourceResolver resourceResolver, String scriptPath) { def session = resourceResolver.adaptTo(Session) + // FIXME: use adaptTo(InputStream.class) to get binary data def binary = session.getNode(scriptPath) .getNode(JcrConstants.JCR_CONTENT) .getProperty(JcrConstants.JCR_DATA) diff --git a/pom.xml b/pom.xml index b6008a21..f5171c78 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ aem-groovy-console - 2020.12.4676.20201216T130744Z-201201 + 2022.10.9398.20221020T071514Z-220800 diff --git a/ui.config/src/main/content/META-INF/vault/filter.xml b/ui.config/src/main/content/META-INF/vault/filter.xml index b69b60a7..e92819a4 100644 --- a/ui.config/src/main/content/META-INF/vault/filter.xml +++ b/ui.config/src/main/content/META-INF/vault/filter.xml @@ -1,4 +1,5 @@ + diff --git a/ui.config/src/main/content/jcr_root/apps/groovyconsole-config/osgiconfig/config/org.apache.sling.jcr.repoinit.RepositoryInitializer-groovyconsole.config b/ui.config/src/main/content/jcr_root/apps/groovyconsole-config/osgiconfig/config/org.apache.sling.jcr.repoinit.RepositoryInitializer-groovyconsole.config new file mode 100644 index 00000000..e1e8eaa8 --- /dev/null +++ b/ui.config/src/main/content/jcr_root/apps/groovyconsole-config/osgiconfig/config/org.apache.sling.jcr.repoinit.RepositoryInitializer-groovyconsole.config @@ -0,0 +1,13 @@ +scripts=[ +" +create path /conf/groovyconsole/distribution(sling:Folder) +create path /conf/groovyconsole/scripts(sling:Folder) + +create path /var/groovyconsole/audit(nt:unstructured) + +create service user aem-groovy-console-service with path system/aem-groovy-console +set ACL for aem-groovy-console-service + allow jcr:all on / + allow jcr:all on /var/groovyconsole/audit +end +"] diff --git a/ui.config/src/main/content/jcr_root/apps/groovyconsole-config/osgiconfig/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-groovy-console.xml b/ui.config/src/main/content/jcr_root/apps/groovyconsole-config/osgiconfig/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-groovy-console.xml index 50bdb556..3066899e 100644 --- a/ui.config/src/main/content/jcr_root/apps/groovyconsole-config/osgiconfig/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-groovy-console.xml +++ b/ui.config/src/main/content/jcr_root/apps/groovyconsole-config/osgiconfig/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-groovy-console.xml @@ -1,4 +1,4 @@ \ No newline at end of file + user.mapping="aem-groovy-console-bundle=[aem-groovy-console-service]"/> diff --git a/ui.content/src/main/content/META-INF/vault/filter.xml b/ui.content/src/main/content/META-INF/vault/filter.xml index 79a3dd8f..ca13cf42 100644 --- a/ui.content/src/main/content/META-INF/vault/filter.xml +++ b/ui.content/src/main/content/META-INF/vault/filter.xml @@ -1,6 +1,4 @@ - - - + diff --git a/ui.content/src/main/content/jcr_root/_rep_policy.xml b/ui.content/src/main/content/jcr_root/_rep_policy.xml deleted file mode 100644 index 94e3f191..00000000 --- a/ui.content/src/main/content/jcr_root/_rep_policy.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/.content.xml b/ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/.content.xml similarity index 85% rename from ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/.content.xml rename to ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/.content.xml index 628c34d2..42fa95b5 100644 --- a/ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/.content.xml +++ b/ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/.content.xml @@ -4,3 +4,4 @@ xmlns:rep="internal" jcr:mixinTypes="[rep:AccessControllable]" jcr:primaryType="sling:Folder"/> + diff --git a/ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/CreateOsgiConfigurations.groovy b/ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/CreateOsgiConfigurations.groovy similarity index 100% rename from ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/CreateOsgiConfigurations.groovy rename to ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/CreateOsgiConfigurations.groovy diff --git a/ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/CreatePackage.groovy b/ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/CreatePackage.groovy similarity index 100% rename from ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/CreatePackage.groovy rename to ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/CreatePackage.groovy diff --git a/ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/DeleteOsgiConfigurations.groovy b/ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/DeleteOsgiConfigurations.groovy similarity index 100% rename from ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/DeleteOsgiConfigurations.groovy rename to ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/DeleteOsgiConfigurations.groovy diff --git a/ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/FindOrphanedComponents.groovy b/ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/FindOrphanedComponents.groovy similarity index 100% rename from ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/FindOrphanedComponents.groovy rename to ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/FindOrphanedComponents.groovy diff --git a/ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/FindPagesWithProperty.groovy b/ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/FindPagesWithProperty.groovy similarity index 100% rename from ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/FindPagesWithProperty.groovy rename to ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/FindPagesWithProperty.groovy diff --git a/ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/FindPagesWithTemplate.groovy b/ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/FindPagesWithTemplate.groovy similarity index 100% rename from ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/FindPagesWithTemplate.groovy rename to ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/FindPagesWithTemplate.groovy diff --git a/ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/FindReferences.groovy b/ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/FindReferences.groovy similarity index 100% rename from ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/FindReferences.groovy rename to ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/FindReferences.groovy diff --git a/ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/FulltextQuery.groovy b/ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/FulltextQuery.groovy similarity index 100% rename from ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/FulltextQuery.groovy rename to ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/FulltextQuery.groovy diff --git a/ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/JcrSearch.groovy b/ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/JcrSearch.groovy similarity index 100% rename from ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/JcrSearch.groovy rename to ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/JcrSearch.groovy diff --git a/ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/ListTemplates.groovy b/ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/ListTemplates.groovy similarity index 100% rename from ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/ListTemplates.groovy rename to ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/ListTemplates.groovy diff --git a/ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/UpdateOsgiConfiguration.groovy b/ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/UpdateOsgiConfiguration.groovy similarity index 100% rename from ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/UpdateOsgiConfiguration.groovy rename to ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/UpdateOsgiConfiguration.groovy diff --git a/ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/UpdatePageTitles.groovy b/ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/UpdatePageTitles.groovy similarity index 100% rename from ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/samples/UpdatePageTitles.groovy rename to ui.content/src/main/content/jcr_root/conf/groovyconsole/scripts/samples/UpdatePageTitles.groovy diff --git a/ui.content/src/main/content/jcr_root/home/users/system/groovy-console-system-user/.content.xml b/ui.content/src/main/content/jcr_root/home/users/system/groovy-console-system-user/.content.xml deleted file mode 100644 index 9d41f89a..00000000 --- a/ui.content/src/main/content/jcr_root/home/users/system/groovy-console-system-user/.content.xml +++ /dev/null @@ -1,6 +0,0 @@ - - \ No newline at end of file diff --git a/ui.content/src/main/content/jcr_root/var/groovyconsole/.content.xml b/ui.content/src/main/content/jcr_root/var/groovyconsole/.content.xml deleted file mode 100644 index 7da43861..00000000 --- a/ui.content/src/main/content/jcr_root/var/groovyconsole/.content.xml +++ /dev/null @@ -1,4 +0,0 @@ - - \ No newline at end of file diff --git a/ui.content/src/main/content/jcr_root/var/groovyconsole/audit/.content.xml b/ui.content/src/main/content/jcr_root/var/groovyconsole/audit/.content.xml deleted file mode 100644 index 94eaa260..00000000 --- a/ui.content/src/main/content/jcr_root/var/groovyconsole/audit/.content.xml +++ /dev/null @@ -1,5 +0,0 @@ - - \ No newline at end of file diff --git a/ui.content/src/main/content/jcr_root/var/groovyconsole/audit/_rep_policy.xml b/ui.content/src/main/content/jcr_root/var/groovyconsole/audit/_rep_policy.xml deleted file mode 100644 index 94e3f191..00000000 --- a/ui.content/src/main/content/jcr_root/var/groovyconsole/audit/_rep_policy.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/ui.content/src/main/content/jcr_root/var/groovyconsole/replication/.content.xml b/ui.content/src/main/content/jcr_root/var/groovyconsole/replication/.content.xml deleted file mode 100644 index a5b18056..00000000 --- a/ui.content/src/main/content/jcr_root/var/groovyconsole/replication/.content.xml +++ /dev/null @@ -1,6 +0,0 @@ - - \ No newline at end of file diff --git a/ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/.content.xml b/ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/.content.xml deleted file mode 100644 index a5b18056..00000000 --- a/ui.content/src/main/content/jcr_root/var/groovyconsole/scripts/.content.xml +++ /dev/null @@ -1,6 +0,0 @@ - - \ No newline at end of file From 1e9162da1f906eae5d93557fa1cebf5f4fe86a7b Mon Sep 17 00:00:00 2001 From: Barry d'Hoine Date: Wed, 14 Dec 2022 01:24:46 +0100 Subject: [PATCH 07/47] Add AEM Analyser plugin --- all/pom.xml | 12 ++++++++++++ pom.xml | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/all/pom.xml b/all/pom.xml index a6ca1409..c1355343 100644 --- a/all/pom.xml +++ b/all/pom.xml @@ -15,6 +15,18 @@ + + com.adobe.aem + aemanalyser-maven-plugin + + + aem-analyser + + project-analyse + + + + org.apache.jackrabbit filevault-package-maven-plugin diff --git a/pom.xml b/pom.xml index f5171c78..b88bda10 100644 --- a/pom.xml +++ b/pom.xml @@ -393,6 +393,12 @@ ${vault.password} + + com.adobe.aem + aemanalyser-maven-plugin + 1.5.8 + true + From 3ef83f66deaaf6b4dc64c5ec71605b1d9d29e370 Mon Sep 17 00:00:00 2001 From: Barry d'Hoine Date: Wed, 14 Dec 2022 02:25:55 +0100 Subject: [PATCH 08/47] Move remaining content from /var to /conf --- README.md | 6 +++--- .../groovy/console/constants/GroovyConsoleConstants.groovy | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ce04a178..2a59a9b9 100644 --- a/README.md +++ b/README.md @@ -61,11 +61,11 @@ Saved scripts can be remotely executed by sending a POST request to the console ### Single Script - curl -d "scriptPath=/var/groovyconsole/scripts/samples/JcrSearch.groovy" -X POST -u admin:admin http://localhost:4502/bin/groovyconsole/post.json + curl -d "scriptPath=/conf/groovyconsole/scripts/samples/JcrSearch.groovy" -X POST -u admin:admin http://localhost:4502/bin/groovyconsole/post.json ### Multiple Scripts - curl -d "scriptPaths=/var/groovyconsole/scripts/samples/JcrSearch.groovy&scriptPaths=/var/groovyconsole/scripts/samples/FulltextQuery.groovy" -X POST -u admin:admin http://localhost:4502/bin/groovyconsole/post.json + curl -d "scriptPaths=/conf/groovyconsole/scripts/samples/JcrSearch.groovy&scriptPaths=/conf/groovyconsole/scripts/samples/FulltextQuery.groovy" -X POST -u admin:admin http://localhost:4502/bin/groovyconsole/post.json ## Extensions @@ -96,4 +96,4 @@ Sample scripts can be found in the `src/main/scripts` directory. ## Versioning -Follows [Semantic Versioning](http://semver.org/) guidelines. \ No newline at end of file +Follows [Semantic Versioning](http://semver.org/) guidelines. diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/constants/GroovyConsoleConstants.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/constants/GroovyConsoleConstants.groovy index 5ef69bca..729c6aca 100644 --- a/bundle/src/main/groovy/org/cid15/aem/groovy/console/constants/GroovyConsoleConstants.groovy +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/constants/GroovyConsoleConstants.groovy @@ -9,7 +9,7 @@ class GroovyConsoleConstants { public static final String PATH_CONSOLE_ROOT = "/var/groovyconsole" - public static final String PATH_SCRIPTS_FOLDER = "$PATH_CONSOLE_ROOT/scripts" + public static final String PATH_SCRIPTS_FOLDER = "/conf/groovyconsole/scripts" public static final String EXTENSION_GROOVY = ".groovy" From 3d050fd43dd2cb7a0f17e2ea2f9a68ec3f3f0008 Mon Sep 17 00:00:00 2001 From: Barry d'Hoine Date: Wed, 14 Dec 2022 02:52:47 +0100 Subject: [PATCH 09/47] Add replicate servlet skeleton --- .../ReplicatedScriptListener.groovy | 4 +++ .../servlets/ReplicateScriptServlet.groovy | 30 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy index e125dbd7..98c27623 100644 --- a/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy @@ -2,6 +2,7 @@ package org.cid15.aem.groovy.console.replication import com.day.cq.commons.jcr.JcrConstants import com.google.common.base.Charsets +import groovy.util.logging.Slf4j import org.apache.sling.api.resource.ResourceResolver import org.apache.sling.api.resource.ResourceResolverFactory import org.apache.sling.api.resource.observation.ResourceChange @@ -22,6 +23,7 @@ import static com.google.common.base.Preconditions.checkNotNull "resource.paths=/conf/groovyconsole/distribution", "resource.change.types=ADDED" ]) +@Slf4j("LOG") public class ReplicatedScriptListener implements ResourceChangeListener { @Reference private GroovyConsoleService consoleService; @@ -31,8 +33,10 @@ public class ReplicatedScriptListener implements ResourceChangeListener { @Override public void onChange(@NotNull List list) { + // TODO: Only run on publish list.each { change -> resourceResolverFactory.getServiceResourceResolver(null).withCloseable { resourceResolver -> + LOG.info("Detected replicated script on path '{}'", change.path) consoleService.runScript(getScriptContext(resourceResolver, change.path)); } } diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy new file mode 100644 index 00000000..78977feb --- /dev/null +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy @@ -0,0 +1,30 @@ +package org.cid15.aem.groovy.console.servlets + +import org.apache.sling.api.SlingHttpServletRequest +import org.apache.sling.api.SlingHttpServletResponse +import org.cid15.aem.groovy.console.configuration.ConfigurationService +import org.jetbrains.annotations.NotNull +import org.osgi.service.component.annotations.Component +import org.osgi.service.component.annotations.Reference + +import javax.servlet.Servlet +import javax.servlet.ServletException + +import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN + +@Component(service = Servlet, immediate = true, property = [ + "sling.servlet.paths=/bin/groovyconsole/replicate" +]) +class ReplicateScriptServlet extends AbstractJsonResponseServlet { + @Reference + private ConfigurationService configurationService + + @Override + protected void doPost(@NotNull SlingHttpServletRequest request, @NotNull SlingHttpServletResponse response) throws ServletException, IOException { + if (configurationService.hasPermission(request)) { + // TODO: read script, create node, replicate script, cleanup + } else { + response.status = SC_FORBIDDEN + } + } +} From 5350fc2591902ebf1da9ab638091722c0a6c4c33 Mon Sep 17 00:00:00 2001 From: Barry d'Hoine Date: Wed, 14 Dec 2022 04:48:37 +0100 Subject: [PATCH 10/47] Create script resource for replication --- .../constants/GroovyConsoleConstants.groovy | 2 + .../ReplicatedScriptListener.groovy | 2 +- .../servlets/ReplicateScriptServlet.groovy | 43 ++++++++++++++++++- ...RepositoryInitializer-groovyconsole.config | 2 +- 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/constants/GroovyConsoleConstants.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/constants/GroovyConsoleConstants.groovy index 729c6aca..92bf7966 100644 --- a/bundle/src/main/groovy/org/cid15/aem/groovy/console/constants/GroovyConsoleConstants.groovy +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/constants/GroovyConsoleConstants.groovy @@ -11,6 +11,8 @@ class GroovyConsoleConstants { public static final String PATH_SCRIPTS_FOLDER = "/conf/groovyconsole/scripts" + public static final String PATH_REPLICATION_FOLDER = "/conf/groovyconsole/replication" + public static final String EXTENSION_GROOVY = ".groovy" public static final String CHARSET = Charsets.UTF_8.name() diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy index 98c27623..ce37cdeb 100644 --- a/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy @@ -20,7 +20,7 @@ import static com.google.common.base.Preconditions.checkNotNull // TODO: Use const references for properties @Component(property = [ - "resource.paths=/conf/groovyconsole/distribution", + "resource.paths=/conf/groovyconsole/replication", "resource.change.types=ADDED" ]) @Slf4j("LOG") diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy index 78977feb..e1b6cbde 100644 --- a/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy @@ -1,7 +1,13 @@ package org.cid15.aem.groovy.console.servlets +import com.day.cq.commons.jcr.JcrConstants +import com.google.common.base.Charsets +import com.google.common.net.MediaType +import groovy.util.logging.Slf4j +import org.apache.commons.io.IOUtils import org.apache.sling.api.SlingHttpServletRequest import org.apache.sling.api.SlingHttpServletResponse +import org.apache.sling.api.resource.ResourceResolverFactory import org.cid15.aem.groovy.console.configuration.ConfigurationService import org.jetbrains.annotations.NotNull import org.osgi.service.component.annotations.Component @@ -10,21 +16,56 @@ import org.osgi.service.component.annotations.Reference import javax.servlet.Servlet import javax.servlet.ServletException +import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN +import static org.cid15.aem.groovy.console.constants.GroovyConsoleConstants.CHARSET +import static org.cid15.aem.groovy.console.constants.GroovyConsoleConstants.PATH_REPLICATION_FOLDER +import static org.cid15.aem.groovy.console.constants.GroovyConsoleConstants.SCRIPT @Component(service = Servlet, immediate = true, property = [ "sling.servlet.paths=/bin/groovyconsole/replicate" ]) +@Slf4j("LOG") class ReplicateScriptServlet extends AbstractJsonResponseServlet { @Reference private ConfigurationService configurationService + @Reference + private ResourceResolverFactory resourceResolverFactory; + @Override protected void doPost(@NotNull SlingHttpServletRequest request, @NotNull SlingHttpServletResponse response) throws ServletException, IOException { if (configurationService.hasPermission(request)) { - // TODO: read script, create node, replicate script, cleanup + def script = request.getRequestParameter(SCRIPT)?.getString(Charsets.UTF_8.name()) + if (script) { + LOG.info("Replicate script") + createScriptResource(script) + // TODO: replicate script, cleanup + } else { + LOG.warn("Script should not be empty") + response.status = SC_BAD_REQUEST + } } else { response.status = SC_FORBIDDEN } } + + void createScriptResource(String script) { + resourceResolverFactory.getServiceResourceResolver(null).withCloseable { resourceResolver -> + def parent = resourceResolver.getResource(PATH_REPLICATION_FOLDER) + Map properties = new HashMap<>() + + properties.put(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_FILE) + def scriptResource = resourceResolver.create(parent, "script.groovy", properties) + + properties.clear() + properties.put(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_RESOURCE) + properties.put(JcrConstants.JCR_ENCODING, CHARSET) + properties.put(JcrConstants.JCR_MIMETYPE, MediaType.OCTET_STREAM.toString()) + properties.put(JcrConstants.JCR_DATA, IOUtils.toInputStream(script, CHARSET)) + resourceResolver.create(scriptResource, JcrConstants.JCR_CONTENT, properties) + + resourceResolver.commit() + } + } } diff --git a/ui.config/src/main/content/jcr_root/apps/groovyconsole-config/osgiconfig/config/org.apache.sling.jcr.repoinit.RepositoryInitializer-groovyconsole.config b/ui.config/src/main/content/jcr_root/apps/groovyconsole-config/osgiconfig/config/org.apache.sling.jcr.repoinit.RepositoryInitializer-groovyconsole.config index e1e8eaa8..95817846 100644 --- a/ui.config/src/main/content/jcr_root/apps/groovyconsole-config/osgiconfig/config/org.apache.sling.jcr.repoinit.RepositoryInitializer-groovyconsole.config +++ b/ui.config/src/main/content/jcr_root/apps/groovyconsole-config/osgiconfig/config/org.apache.sling.jcr.repoinit.RepositoryInitializer-groovyconsole.config @@ -1,6 +1,6 @@ scripts=[ " -create path /conf/groovyconsole/distribution(sling:Folder) +create path /conf/groovyconsole/replication(sling:Folder) create path /conf/groovyconsole/scripts(sling:Folder) create path /var/groovyconsole/audit(nt:unstructured) From e5dc6f41505bb092c87eeeb9e6cfea417834f3fa Mon Sep 17 00:00:00 2001 From: Barry d'Hoine Date: Wed, 14 Dec 2022 05:44:14 +0100 Subject: [PATCH 11/47] Add xpathQuery method --- .../impl/DefaultScriptMetaClassExtensionProvider.groovy | 4 ++++ .../apps/groovyconsole/components/console/methods.html | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/extension/impl/DefaultScriptMetaClassExtensionProvider.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/extension/impl/DefaultScriptMetaClassExtensionProvider.groovy index 2ce9790f..817a6a70 100755 --- a/bundle/src/main/groovy/org/cid15/aem/groovy/console/extension/impl/DefaultScriptMetaClassExtensionProvider.groovy +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/extension/impl/DefaultScriptMetaClassExtensionProvider.groovy @@ -128,6 +128,10 @@ class DefaultScriptMetaClassExtensionProvider implements ScriptMetaClassExtensio queryBuilder.createQuery(PredicateGroup.create(predicates), session) } + delegate.xpathQuery { String query -> + session.workspace.queryManager.createQuery(query, "xpath").execute().nodes + } + delegate.table = { Closure closure -> def table = new Table() diff --git a/ui.apps/src/main/content/jcr_root/apps/groovyconsole/components/console/methods.html b/ui.apps/src/main/content/jcr_root/apps/groovyconsole/components/console/methods.html index 4835bdf7..8d98a42f 100755 --- a/ui.apps/src/main/content/jcr_root/apps/groovyconsole/components/console/methods.html +++ b/ui.apps/src/main/content/jcr_root/apps/groovyconsole/components/console/methods.html @@ -25,7 +25,8 @@

  • deactivate(String path) - Deactivate the node at the given path.
  • deactivate(String path, ReplicationOptions options) - Deactivate the node at the given path with supplied options.
  • createQuery(Map predicates) - Create a Query instance from the QueryBuilder for the current JCR session.
  • +
  • xpathQuery(String query) - Execute an XPath query using the QueryManager for the current JCR session.
  • - \ No newline at end of file + From 8556857c4d53d5fe1377cf3d262c601f3feab814 Mon Sep 17 00:00:00 2001 From: Barry d'Hoine Date: Wed, 14 Dec 2022 09:06:52 +0100 Subject: [PATCH 12/47] Add publish IntelliJ run configs --- .run/Author.run.xml | 15 ++++++++++++ .run/Publish.run.xml | 15 ++++++++++++ .run/[publish] aem-groovy-console.run.xml | 30 +++++++++++++++++++++++ .run/[publish] all.run.xml | 30 +++++++++++++++++++++++ .run/[publish] bundle.run.xml | 30 +++++++++++++++++++++++ .run/[publish] ui.apps.run.xml | 30 +++++++++++++++++++++++ .run/[publish] ui.config.run.xml | 30 +++++++++++++++++++++++ .run/[publish] ui.content.run.xml | 30 +++++++++++++++++++++++ pom.xml | 28 +++++++++++++++++++++ 9 files changed, 238 insertions(+) create mode 100644 .run/Author.run.xml create mode 100644 .run/Publish.run.xml create mode 100644 .run/[publish] aem-groovy-console.run.xml create mode 100644 .run/[publish] all.run.xml create mode 100644 .run/[publish] bundle.run.xml create mode 100644 .run/[publish] ui.apps.run.xml create mode 100644 .run/[publish] ui.config.run.xml create mode 100644 .run/[publish] ui.content.run.xml diff --git a/.run/Author.run.xml b/.run/Author.run.xml new file mode 100644 index 00000000..e519e64f --- /dev/null +++ b/.run/Author.run.xml @@ -0,0 +1,15 @@ + + + + \ No newline at end of file diff --git a/.run/Publish.run.xml b/.run/Publish.run.xml new file mode 100644 index 00000000..3a6dc185 --- /dev/null +++ b/.run/Publish.run.xml @@ -0,0 +1,15 @@ + + + + \ No newline at end of file diff --git a/.run/[publish] aem-groovy-console.run.xml b/.run/[publish] aem-groovy-console.run.xml new file mode 100644 index 00000000..2c93f5be --- /dev/null +++ b/.run/[publish] aem-groovy-console.run.xml @@ -0,0 +1,30 @@ + + + + + + + + \ No newline at end of file diff --git a/.run/[publish] all.run.xml b/.run/[publish] all.run.xml new file mode 100644 index 00000000..5b1b1be7 --- /dev/null +++ b/.run/[publish] all.run.xml @@ -0,0 +1,30 @@ + + + + + + + + \ No newline at end of file diff --git a/.run/[publish] bundle.run.xml b/.run/[publish] bundle.run.xml new file mode 100644 index 00000000..6e502c8b --- /dev/null +++ b/.run/[publish] bundle.run.xml @@ -0,0 +1,30 @@ + + + + + + + + \ No newline at end of file diff --git a/.run/[publish] ui.apps.run.xml b/.run/[publish] ui.apps.run.xml new file mode 100644 index 00000000..ea1ebfbb --- /dev/null +++ b/.run/[publish] ui.apps.run.xml @@ -0,0 +1,30 @@ + + + + + + + + \ No newline at end of file diff --git a/.run/[publish] ui.config.run.xml b/.run/[publish] ui.config.run.xml new file mode 100644 index 00000000..85bce355 --- /dev/null +++ b/.run/[publish] ui.config.run.xml @@ -0,0 +1,30 @@ + + + + + + + + \ No newline at end of file diff --git a/.run/[publish] ui.content.run.xml b/.run/[publish] ui.content.run.xml new file mode 100644 index 00000000..5d578c07 --- /dev/null +++ b/.run/[publish] ui.content.run.xml @@ -0,0 +1,30 @@ + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index b88bda10..76e435b5 100644 --- a/pom.xml +++ b/pom.xml @@ -164,6 +164,34 @@ + + autoInstallBundlePublish + + false + + + + + + org.apache.sling + sling-maven-plugin + + http://${aem.publish.host}:${aem.publish.port}/system/console + + + + install-bundle + + install + + + + + + + + + autoInstallPackage From a9d7adbb704eef13f8e205023fc6d8c19c1f4ceb Mon Sep 17 00:00:00 2001 From: Barry d'Hoine Date: Wed, 14 Dec 2022 22:04:53 +0100 Subject: [PATCH 13/47] Update FIXME and TODO's --- .../console/replication/ReplicatedScriptListener.groovy | 7 ++++--- .../groovy/console/servlets/ReplicateScriptServlet.groovy | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy index ce37cdeb..23000170 100644 --- a/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy @@ -18,7 +18,6 @@ import javax.jcr.Session import static com.google.common.base.Preconditions.checkNotNull -// TODO: Use const references for properties @Component(property = [ "resource.paths=/conf/groovyconsole/replication", "resource.change.types=ADDED" @@ -33,10 +32,11 @@ public class ReplicatedScriptListener implements ResourceChangeListener { @Override public void onChange(@NotNull List list) { - // TODO: Only run on publish + // TODO: only run on publish list.each { change -> resourceResolverFactory.getServiceResourceResolver(null).withCloseable { resourceResolver -> - LOG.info("Detected replicated script on path '{}'", change.path) + // FIXME: more robust detection if Groovy script is found + LOG.debug("Detected replicated script on path '{}'", change.path) consoleService.runScript(getScriptContext(resourceResolver, change.path)); } } @@ -53,6 +53,7 @@ public class ReplicatedScriptListener implements ResourceChangeListener { ) } + // FIXME: extract to service that can be shared between services and servlets private String loadScript(ResourceResolver resourceResolver, String scriptPath) { def session = resourceResolver.adaptTo(Session) diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy index e1b6cbde..52031d7e 100644 --- a/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy @@ -40,7 +40,7 @@ class ReplicateScriptServlet extends AbstractJsonResponseServlet { if (script) { LOG.info("Replicate script") createScriptResource(script) - // TODO: replicate script, cleanup + // TODO: replicate script, cleanup and provide response code } else { LOG.warn("Script should not be empty") response.status = SC_BAD_REQUEST @@ -56,6 +56,7 @@ class ReplicateScriptServlet extends AbstractJsonResponseServlet { Map properties = new HashMap<>() properties.put(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_FILE) + // TODO: generate file name script-.groovy def scriptResource = resourceResolver.create(parent, "script.groovy", properties) properties.clear() From 4fe8230d7cbbd2e48dc98120fe8716a35a335133 Mon Sep 17 00:00:00 2001 From: Barry d'Hoine Date: Wed, 14 Dec 2022 22:35:07 +0100 Subject: [PATCH 14/47] Add replication of scripts --- .../ReplicatedScriptListener.groovy | 7 ++--- .../servlets/ReplicateScriptServlet.groovy | 28 ++++++++++++------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy index 23000170..08e3bb88 100644 --- a/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy @@ -19,7 +19,7 @@ import javax.jcr.Session import static com.google.common.base.Preconditions.checkNotNull @Component(property = [ - "resource.paths=/conf/groovyconsole/replication", + "resource.paths=glob:/conf/groovyconsole/replication/*.groovy", "resource.change.types=ADDED" ]) @Slf4j("LOG") @@ -35,9 +35,8 @@ public class ReplicatedScriptListener implements ResourceChangeListener { // TODO: only run on publish list.each { change -> resourceResolverFactory.getServiceResourceResolver(null).withCloseable { resourceResolver -> - // FIXME: more robust detection if Groovy script is found - LOG.debug("Detected replicated script on path '{}'", change.path) - consoleService.runScript(getScriptContext(resourceResolver, change.path)); + LOG.info("Detected replicated script on path '{}'", change.path) + consoleService.runScript(getScriptContext(resourceResolver, change.path)) } } } diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy index 52031d7e..4700eea1 100644 --- a/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy @@ -1,6 +1,8 @@ package org.cid15.aem.groovy.console.servlets import com.day.cq.commons.jcr.JcrConstants +import com.day.cq.replication.ReplicationActionType +import com.day.cq.replication.Replicator import com.google.common.base.Charsets import com.google.common.net.MediaType import groovy.util.logging.Slf4j @@ -13,14 +15,13 @@ import org.jetbrains.annotations.NotNull import org.osgi.service.component.annotations.Component import org.osgi.service.component.annotations.Reference +import javax.jcr.Session import javax.servlet.Servlet import javax.servlet.ServletException import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN -import static org.cid15.aem.groovy.console.constants.GroovyConsoleConstants.CHARSET -import static org.cid15.aem.groovy.console.constants.GroovyConsoleConstants.PATH_REPLICATION_FOLDER -import static org.cid15.aem.groovy.console.constants.GroovyConsoleConstants.SCRIPT +import static org.cid15.aem.groovy.console.constants.GroovyConsoleConstants.* @Component(service = Servlet, immediate = true, property = [ "sling.servlet.paths=/bin/groovyconsole/replicate" @@ -31,16 +32,22 @@ class ReplicateScriptServlet extends AbstractJsonResponseServlet { private ConfigurationService configurationService @Reference - private ResourceResolverFactory resourceResolverFactory; + private ResourceResolverFactory resourceResolverFactory + + @Reference + Replicator replicator @Override protected void doPost(@NotNull SlingHttpServletRequest request, @NotNull SlingHttpServletResponse response) throws ServletException, IOException { if (configurationService.hasPermission(request)) { def script = request.getRequestParameter(SCRIPT)?.getString(Charsets.UTF_8.name()) if (script) { - LOG.info("Replicate script") - createScriptResource(script) - // TODO: replicate script, cleanup and provide response code + def resourceResolver = request.resourceResolver + def scriptName = createScriptResource(script) + LOG.info("Replicate script '{}'", scriptName) + def session = resourceResolver.adaptTo(Session) + replicator.replicate(session, ReplicationActionType.ACTIVATE, "${PATH_REPLICATION_FOLDER}/${scriptName}") + // TODO: provide response code } else { LOG.warn("Script should not be empty") response.status = SC_BAD_REQUEST @@ -50,14 +57,14 @@ class ReplicateScriptServlet extends AbstractJsonResponseServlet { } } - void createScriptResource(String script) { + private String createScriptResource(String script) { resourceResolverFactory.getServiceResourceResolver(null).withCloseable { resourceResolver -> def parent = resourceResolver.getResource(PATH_REPLICATION_FOLDER) Map properties = new HashMap<>() properties.put(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_FILE) - // TODO: generate file name script-.groovy - def scriptResource = resourceResolver.create(parent, "script.groovy", properties) + def scriptName = "script-${System.currentTimeMillis()}.groovy" + def scriptResource = resourceResolver.create(parent, scriptName, properties) properties.clear() properties.put(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_RESOURCE) @@ -67,6 +74,7 @@ class ReplicateScriptServlet extends AbstractJsonResponseServlet { resourceResolver.create(scriptResource, JcrConstants.JCR_CONTENT, properties) resourceResolver.commit() + scriptName } } } From 8befbbf5448a9072b6cdddd4189371fde5972a9e Mon Sep 17 00:00:00 2001 From: Barry d'Hoine Date: Thu, 15 Dec 2022 18:15:14 +0100 Subject: [PATCH 15/47] Add feature toggle for distributed script execution and block on author --- .../configuration/ConfigurationService.groovy | 16 +++++++++++++++- .../impl/DefaultConfigurationService.groovy | 19 ++++++++++++++++++- .../ReplicatedScriptListener.groovy | 15 ++++++++++----- .../servlets/ReplicateScriptServlet.groovy | 4 ++-- .../impl/ConfigurationServiceProperties.java | 11 ++++++++--- 5 files changed, 53 insertions(+), 12 deletions(-) diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/configuration/ConfigurationService.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/configuration/ConfigurationService.groovy index e79605ed..8406a653 100644 --- a/bundle/src/main/groovy/org/cid15/aem/groovy/console/configuration/ConfigurationService.groovy +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/configuration/ConfigurationService.groovy @@ -58,4 +58,18 @@ interface ConfigurationService { * @return thread timeout */ long getThreadTimeout() -} \ No newline at end of file + + /** + * Check if distributed replication is enabled. In this way scripts can be replicated and auto executed on replication. + * + * @retyrn true is distributed replication is enabled + */ + boolean isDistributedReplicationEnabled() + + /** + * Check if the service is running on an author instance + * + * @return true if the author runmode is present + */ + boolean isAuthor() +} diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/configuration/impl/DefaultConfigurationService.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/configuration/impl/DefaultConfigurationService.groovy index d407bd3c..89cdb857 100755 --- a/bundle/src/main/groovy/org/cid15/aem/groovy/console/configuration/impl/DefaultConfigurationService.groovy +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/configuration/impl/DefaultConfigurationService.groovy @@ -7,6 +7,7 @@ import org.apache.jackrabbit.api.security.user.UserManager import org.apache.sling.api.SlingHttpServletRequest import org.apache.sling.api.resource.ResourceResolverFactory import org.cid15.aem.groovy.console.configuration.ConfigurationService +import org.osgi.framework.BundleContext import org.osgi.service.component.annotations.Activate import org.osgi.service.component.annotations.Component import org.osgi.service.component.annotations.Modified @@ -35,6 +36,10 @@ class DefaultConfigurationService implements ConfigurationService { private long threadTimeout + private boolean distributedExecutionEnabled + + private boolean author + @Override boolean hasPermission(SlingHttpServletRequest request) { isAdminOrAllowedGroupMember(request, allowedGroups) @@ -70,10 +75,20 @@ class DefaultConfigurationService implements ConfigurationService { threadTimeout } + @Override + boolean isDistributedReplicationEnabled() { + distributedExecutionEnabled + } + + @Override + boolean isAuthor() { + return author + } + @Activate @Modified @Synchronized - void activate(ConfigurationServiceProperties properties) { + void activate(ConfigurationServiceProperties properties, BundleContext bundleContext) { emailEnabled = properties.emailEnabled() emailRecipients = (properties.emailRecipients() ?: []).findAll() as Set allowedGroups = (properties.allowedGroups() ?: []).findAll() as Set @@ -81,6 +96,8 @@ class DefaultConfigurationService implements ConfigurationService { auditDisabled = properties.auditDisabled() displayAllAuditRecords = properties.auditDisplayAll() threadTimeout = properties.threadTimeout() + distributedExecutionEnabled = properties.distributedExecutionEnabled() + author = bundleContext.getProperty("sling.run.modes").contains("author") } private boolean isAdminOrAllowedGroupMember(SlingHttpServletRequest request, Set groupIds) { diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy index 08e3bb88..34ae733d 100644 --- a/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy @@ -10,6 +10,7 @@ import org.apache.sling.api.resource.observation.ResourceChangeListener import org.cid15.aem.groovy.console.GroovyConsoleService import org.cid15.aem.groovy.console.api.context.ScriptContext import org.cid15.aem.groovy.console.api.impl.ResourceScriptContext +import org.cid15.aem.groovy.console.configuration.ConfigurationService import org.jetbrains.annotations.NotNull import org.osgi.service.component.annotations.Component import org.osgi.service.component.annotations.Reference @@ -30,13 +31,17 @@ public class ReplicatedScriptListener implements ResourceChangeListener { @Reference private ResourceResolverFactory resourceResolverFactory; + @Reference + private ConfigurationService configurationService; + @Override public void onChange(@NotNull List list) { - // TODO: only run on publish - list.each { change -> - resourceResolverFactory.getServiceResourceResolver(null).withCloseable { resourceResolver -> - LOG.info("Detected replicated script on path '{}'", change.path) - consoleService.runScript(getScriptContext(resourceResolver, change.path)) + if (!configurationService.isAuthor() && configurationService.isDistributedReplicationEnabled()) { + list.each { change -> + resourceResolverFactory.getServiceResourceResolver(null).withCloseable { resourceResolver -> + LOG.debug("Detected replicated script on path '{}'", change.path) + consoleService.runScript(getScriptContext(resourceResolver, change.path)) + } } } } diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy index 4700eea1..3c25abe7 100644 --- a/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy @@ -39,12 +39,12 @@ class ReplicateScriptServlet extends AbstractJsonResponseServlet { @Override protected void doPost(@NotNull SlingHttpServletRequest request, @NotNull SlingHttpServletResponse response) throws ServletException, IOException { - if (configurationService.hasPermission(request)) { + if (configurationService.hasPermission(request) && configurationService.isDistributedReplicationEnabled()) { def script = request.getRequestParameter(SCRIPT)?.getString(Charsets.UTF_8.name()) if (script) { def resourceResolver = request.resourceResolver def scriptName = createScriptResource(script) - LOG.info("Replicate script '{}'", scriptName) + LOG.debug("Replicate script '{}'", scriptName) def session = resourceResolver.adaptTo(Session) replicator.replicate(session, ReplicationActionType.ACTIVATE, "${PATH_REPLICATION_FOLDER}/${scriptName}") // TODO: provide response code diff --git a/bundle/src/main/java/org/cid15/aem/groovy/console/configuration/impl/ConfigurationServiceProperties.java b/bundle/src/main/java/org/cid15/aem/groovy/console/configuration/impl/ConfigurationServiceProperties.java index f54e5412..29340eb4 100644 --- a/bundle/src/main/java/org/cid15/aem/groovy/console/configuration/impl/ConfigurationServiceProperties.java +++ b/bundle/src/main/java/org/cid15/aem/groovy/console/configuration/impl/ConfigurationServiceProperties.java @@ -32,10 +32,15 @@ boolean auditDisabled() default false; @AttributeDefinition(name = "Display All Audit Records?", - description = "If enabled, all audit records (including records for other users) will be displayed in the console history.") + description = "If enabled, all audit records (including records for other users) will be displayed in the console history.") boolean auditDisplayAll() default false; @AttributeDefinition(name = "Thread Timeout", - description = "Time in seconds that scripts are allowed to execute before being interrupted. If 0, no timeout is enforced.") + description = "Time in seconds that scripts are allowed to execute before being interrupted. If 0, no timeout is enforced.") long threadTimeout() default 0; -} \ No newline at end of file + + @AttributeDefinition(name = "Distributed execution enabled?", + description = "If enabled, a script will be able to be replicated from an author and executed on all default replication agents." + ) + boolean distributedExecutionEnabled() default false; +} From 3c1a877361131b2bf8b9afbbce9c9a711a7f60bf Mon Sep 17 00:00:00 2001 From: Barry d'Hoine Date: Thu, 15 Dec 2022 18:17:10 +0100 Subject: [PATCH 16/47] Fix typo in javadoc --- .../groovy/console/configuration/ConfigurationService.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/configuration/ConfigurationService.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/configuration/ConfigurationService.groovy index 8406a653..e7696d51 100644 --- a/bundle/src/main/groovy/org/cid15/aem/groovy/console/configuration/ConfigurationService.groovy +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/configuration/ConfigurationService.groovy @@ -62,7 +62,7 @@ interface ConfigurationService { /** * Check if distributed replication is enabled. In this way scripts can be replicated and auto executed on replication. * - * @retyrn true is distributed replication is enabled + * @return true is distributed replication is enabled */ boolean isDistributedReplicationEnabled() From 1fc6a79feec198370afb303c47802948e96f36fc Mon Sep 17 00:00:00 2001 From: Barry d'Hoine Date: Fri, 16 Dec 2022 23:42:57 +0100 Subject: [PATCH 17/47] Add UI elements for distributed execution --- .../groovy/console/components/Toolbar.groovy | 16 + .../configuration/ConfigurationService.groovy | 6 +- .../impl/DefaultConfigurationService.groovy | 2 +- .../ReplicatedScriptListener.groovy | 2 +- .../response/ReplicateScriptResponse.groovy | 10 + .../DefaultReplicateScriptResponse.groovy | 9 + .../servlets/ReplicateScriptServlet.groovy | 8 +- .../groovyconsole/clientlibs/js/console.js | 985 +++++++++--------- .../components/console/toolbar.html | 14 +- 9 files changed, 570 insertions(+), 482 deletions(-) create mode 100644 bundle/src/main/groovy/org/cid15/aem/groovy/console/components/Toolbar.groovy create mode 100644 bundle/src/main/groovy/org/cid15/aem/groovy/console/response/ReplicateScriptResponse.groovy create mode 100644 bundle/src/main/groovy/org/cid15/aem/groovy/console/response/impl/DefaultReplicateScriptResponse.groovy diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/components/Toolbar.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/components/Toolbar.groovy new file mode 100644 index 00000000..08b63281 --- /dev/null +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/components/Toolbar.groovy @@ -0,0 +1,16 @@ +package org.cid15.aem.groovy.console.components + +import org.apache.sling.api.SlingHttpServletRequest +import org.apache.sling.models.annotations.Model +import org.apache.sling.models.annotations.injectorspecific.OSGiService +import org.cid15.aem.groovy.console.configuration.ConfigurationService + +@Model(adaptables = SlingHttpServletRequest) +class Toolbar { + @OSGiService + private ConfigurationService configurationService + + boolean isDistributedExecutionEnabled() { + configurationService.distributedExecutionEnabled + } +} diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/configuration/ConfigurationService.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/configuration/ConfigurationService.groovy index e7696d51..df723ef8 100644 --- a/bundle/src/main/groovy/org/cid15/aem/groovy/console/configuration/ConfigurationService.groovy +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/configuration/ConfigurationService.groovy @@ -60,11 +60,11 @@ interface ConfigurationService { long getThreadTimeout() /** - * Check if distributed replication is enabled. In this way scripts can be replicated and auto executed on replication. + * Check if distributed execution is enabled. In this way scripts can be replicated and auto executed on replication. * - * @return true is distributed replication is enabled + * @return true is distributed execution is enabled */ - boolean isDistributedReplicationEnabled() + boolean isDistributedExecutionEnabled() /** * Check if the service is running on an author instance diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/configuration/impl/DefaultConfigurationService.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/configuration/impl/DefaultConfigurationService.groovy index 89cdb857..eb0007f4 100755 --- a/bundle/src/main/groovy/org/cid15/aem/groovy/console/configuration/impl/DefaultConfigurationService.groovy +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/configuration/impl/DefaultConfigurationService.groovy @@ -76,7 +76,7 @@ class DefaultConfigurationService implements ConfigurationService { } @Override - boolean isDistributedReplicationEnabled() { + boolean isDistributedExecutionEnabled() { distributedExecutionEnabled } diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy index 34ae733d..90bbc46e 100644 --- a/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/replication/ReplicatedScriptListener.groovy @@ -36,7 +36,7 @@ public class ReplicatedScriptListener implements ResourceChangeListener { @Override public void onChange(@NotNull List list) { - if (!configurationService.isAuthor() && configurationService.isDistributedReplicationEnabled()) { + if (!configurationService.isAuthor() && configurationService.isDistributedExecutionEnabled()) { list.each { change -> resourceResolverFactory.getServiceResourceResolver(null).withCloseable { resourceResolver -> LOG.debug("Detected replicated script on path '{}'", change.path) diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/response/ReplicateScriptResponse.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/response/ReplicateScriptResponse.groovy new file mode 100644 index 00000000..990614e9 --- /dev/null +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/response/ReplicateScriptResponse.groovy @@ -0,0 +1,10 @@ +package org.cid15.aem.groovy.console.response + +/** + * Response for replicated scripts. + */ +interface ReplicateScriptResponse { + + String getResult() + +} diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/response/impl/DefaultReplicateScriptResponse.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/response/impl/DefaultReplicateScriptResponse.groovy new file mode 100644 index 00000000..7f817f3d --- /dev/null +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/response/impl/DefaultReplicateScriptResponse.groovy @@ -0,0 +1,9 @@ +package org.cid15.aem.groovy.console.response.impl + +import groovy.transform.TupleConstructor +import org.cid15.aem.groovy.console.response.ReplicateScriptResponse + +@TupleConstructor +class DefaultReplicateScriptResponse implements ReplicateScriptResponse { + String result +} diff --git a/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy b/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy index 3c25abe7..b58f53ed 100644 --- a/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy +++ b/bundle/src/main/groovy/org/cid15/aem/groovy/console/servlets/ReplicateScriptServlet.groovy @@ -11,6 +11,7 @@ import org.apache.sling.api.SlingHttpServletRequest import org.apache.sling.api.SlingHttpServletResponse import org.apache.sling.api.resource.ResourceResolverFactory import org.cid15.aem.groovy.console.configuration.ConfigurationService +import org.cid15.aem.groovy.console.response.impl.DefaultReplicateScriptResponse import org.jetbrains.annotations.NotNull import org.osgi.service.component.annotations.Component import org.osgi.service.component.annotations.Reference @@ -39,15 +40,16 @@ class ReplicateScriptServlet extends AbstractJsonResponseServlet { @Override protected void doPost(@NotNull SlingHttpServletRequest request, @NotNull SlingHttpServletResponse response) throws ServletException, IOException { - if (configurationService.hasPermission(request) && configurationService.isDistributedReplicationEnabled()) { + if (configurationService.hasPermission(request) && configurationService.isDistributedExecutionEnabled()) { def script = request.getRequestParameter(SCRIPT)?.getString(Charsets.UTF_8.name()) if (script) { def resourceResolver = request.resourceResolver def scriptName = createScriptResource(script) LOG.debug("Replicate script '{}'", scriptName) def session = resourceResolver.adaptTo(Session) - replicator.replicate(session, ReplicationActionType.ACTIVATE, "${PATH_REPLICATION_FOLDER}/${scriptName}") - // TODO: provide response code + def scriptPath = "${PATH_REPLICATION_FOLDER}/${scriptName}" + replicator.replicate(session, ReplicationActionType.ACTIVATE, "${scriptPath}") + writeJsonResponse(response, new DefaultReplicateScriptResponse("Replicated script on path '${scriptPath}'")) } else { LOG.warn("Script should not be empty") response.status = SC_BAD_REQUEST diff --git a/ui.apps/src/main/content/jcr_root/apps/groovyconsole/clientlibs/js/console.js b/ui.apps/src/main/content/jcr_root/apps/groovyconsole/clientlibs/js/console.js index 924229ee..8f4fa141 100644 --- a/ui.apps/src/main/content/jcr_root/apps/groovyconsole/clientlibs/js/console.js +++ b/ui.apps/src/main/content/jcr_root/apps/groovyconsole/clientlibs/js/console.js @@ -1,559 +1,600 @@ var GroovyConsole = function () { - var resultDataTable; + var resultDataTable; - return { - initializeEditors: function () { - // script editor - window.scriptEditor = ace.edit('script-editor'); + return { + initializeEditors: function () { + // script editor + window.scriptEditor = ace.edit('script-editor'); - scriptEditor.getSession().setMode('ace/mode/groovy'); - scriptEditor.setShowPrintMargin(false); - scriptEditor.on('change', function () { - GroovyConsole.localStorage.saveScriptEditorContent(scriptEditor.getSession().getDocument().getValue()); - }); - scriptEditor.setOptions({ + scriptEditor.getSession().setMode('ace/mode/groovy'); + scriptEditor.setShowPrintMargin(false); + scriptEditor.on('change', function () { + GroovyConsole.localStorage.saveScriptEditorContent(scriptEditor.getSession().getDocument().getValue()); + }); + scriptEditor.setOptions({ - enableBasicAutocompletion: true - }); + enableBasicAutocompletion: true + }); - var $scriptEditor = $('#script-editor'); + var $scriptEditor = $('#script-editor'); - $scriptEditor.resizable({ - resize: function () { - scriptEditor.resize(true); + $scriptEditor.resizable({ + resize: function () { + scriptEditor.resize(true); - GroovyConsole.localStorage.saveScriptEditorHeight($scriptEditor.height()); - }, - handles: 's' - }); + GroovyConsole.localStorage.saveScriptEditorHeight($scriptEditor.height()); + }, + handles: 's' + }); - $scriptEditor.css('height', GroovyConsole.localStorage.getScriptEditorHeight()); + $scriptEditor.css('height', GroovyConsole.localStorage.getScriptEditorHeight()); - // data/JSON editor - window.dataEditor = ace.edit('data-editor'); + // data/JSON editor + window.dataEditor = ace.edit('data-editor'); - dataEditor.getSession().setOption('useWorker', false); - dataEditor.getSession().setMode('ace/mode/json'); - dataEditor.setShowPrintMargin(false); - dataEditor.on('change', function () { - GroovyConsole.localStorage.saveDataEditorContent(dataEditor.getSession().getDocument().getValue()); - }); + dataEditor.getSession().setOption('useWorker', false); + dataEditor.getSession().setMode('ace/mode/json'); + dataEditor.setShowPrintMargin(false); + dataEditor.on('change', function () { + GroovyConsole.localStorage.saveDataEditorContent(dataEditor.getSession().getDocument().getValue()); + }); - var $dataEditor = $('#data-editor'); + var $dataEditor = $('#data-editor'); - $dataEditor.resizable({ - resize: function () { - dataEditor.resize(true); + $dataEditor.resizable({ + resize: function () { + dataEditor.resize(true); - GroovyConsole.localStorage.saveDataEditorHeight($dataEditor.height()); - }, - handles: 's' - }); + GroovyConsole.localStorage.saveDataEditorHeight($dataEditor.height()); + }, + handles: 's' + }); - $dataEditor.css('height', GroovyConsole.localStorage.getDataEditorHeight()); + $dataEditor.css('height', GroovyConsole.localStorage.getDataEditorHeight()); - // load editor content - var auditRecord = window.auditRecord; + // load editor content + var auditRecord = window.auditRecord; - if (auditRecord) { - scriptEditor.getSession().setValue(auditRecord.script); - dataEditor.getSession().setValue(auditRecord.data); + if (auditRecord) { + scriptEditor.getSession().setValue(auditRecord.script); + dataEditor.getSession().setValue(auditRecord.data); - GroovyConsole.showResult(auditRecord); - } else { - scriptEditor.getSession().setValue(GroovyConsole.localStorage.getScriptEditorContent()); - dataEditor.getSession().setValue(GroovyConsole.localStorage.getDataEditorContent()); - } + GroovyConsole.showResult(auditRecord); + } else { + scriptEditor.getSession().setValue(GroovyConsole.localStorage.getScriptEditorContent()); + dataEditor.getSession().setValue(GroovyConsole.localStorage.getDataEditorContent()); + } - if (dataEditor.getSession().getDocument().getValue().length) { - GroovyConsole.showData(); - } - }, + if (dataEditor.getSession().getDocument().getValue().length) { + GroovyConsole.showData(); + } + }, - initializeThemeMenu: function () { - var theme = GroovyConsole.localStorage.getTheme(); + initializeThemeMenu: function () { + var theme = GroovyConsole.localStorage.getTheme(); - scriptEditor.setTheme(theme); - dataEditor.setTheme(theme); + scriptEditor.setTheme(theme); + dataEditor.setTheme(theme); - var themes = $('#dropdown-themes li'); + var themes = $('#dropdown-themes li'); - var selectedElement = $.grep(themes, function (element) { - return $(element).find('a').data('target') === theme; - }); + var selectedElement = $.grep(themes, function (element) { + return $(element).find('a').data('target') === theme; + }); - if (selectedElement.length) { - $(selectedElement).addClass('active'); - } + if (selectedElement.length) { + $(selectedElement).addClass('active'); + } - themes.click(function () { - var theme = $(this).find('a').data('target'); + themes.click(function () { + var theme = $(this).find('a').data('target'); - scriptEditor.setTheme(theme); - dataEditor.setTheme(theme); + scriptEditor.setTheme(theme); + dataEditor.setTheme(theme); - themes.removeClass('active'); - $(this).addClass('active'); + themes.removeClass('active'); + $(this).addClass('active'); - GroovyConsole.localStorage.saveTheme(theme); - }); - }, + GroovyConsole.localStorage.saveTheme(theme); + }); + }, - initializeButtons: function () { - $('#new-script').click(function () { - if ($(this).hasClass('disabled')) { - return; - } - - GroovyConsole.localStorage.clearScriptName(); - GroovyConsole.reset(); - GroovyConsole.clearScheduler(); - - scriptEditor.getSession().setValue(''); - dataEditor.getSession().setValue(''); - - GroovyConsole.hideData(); - GroovyConsole.hideScheduler(); - }); - - $('#open-script').click(function () { - if ($(this).hasClass('disabled')) { - return; - } - - GroovyConsole.disableButtons(); - GroovyConsole.showOpenDialog(); - }); - - $('#save-script').click(function () { - if ($(this).hasClass('disabled')) { - return; - } - - var script = scriptEditor.getSession().getValue(); - - if (script.length) { - GroovyConsole.disableButtons(); - GroovyConsole.showSaveDialog(); - } else { - GroovyConsole.showError('Script is empty.'); - } - }); - - $('#schedule-job').click(function () { - if ($('#schedule-job').hasClass('disabled')) { - return; - } - - GroovyConsole.reset(); - - var jobTitle = $('input[name="jobTitle"]').val(); - var cronExpression = $('input[name="cronExpression"]').val(); - - if (jobTitle.length === 0) { - GroovyConsole.showError('Job Title is required.'); - return; - } - - if (!$('input[name="immediate"]').prop('checked') && cronExpression.length === 0) { - GroovyConsole.showError('Cron Expression is required if job is not immediate.'); - return; - } - - var script = scriptEditor.getSession().getValue(); - - if (script.length) { - scriptEditor.setReadOnly(true); - dataEditor.setReadOnly(true); - - GroovyConsole.showLoader(); - GroovyConsole.disableButtons(); - - $('#schedule-job-text').text('Scheduling...'); - - $.post(CQ.shared.HTTP.getContextPath() + '/bin/groovyconsole/jobs.json', { - script: script, - data: dataEditor.getSession().getValue(), - jobTitle: jobTitle, - jobDescription: $('input[name="jobDescription"]').val(), - cronExpression: cronExpression, - mediaType: $('select[name="mediaType"]').val(), - emailTo: $('input[name="emailTo"]').val(), - scheduledJobId: $('input[name="scheduledJobId"]').val() - }).done(function () { - GroovyConsole.showSuccess('Job scheduled successfully.'); - GroovyConsole.clearScheduler(); - GroovyConsole.hideScheduler(); - - $('#scheduled-jobs').collapse('show'); - }).fail(function (jqXHR) { - if (jqXHR.status === 400) { - GroovyConsole.showError('Invalid Cron expression.'); - } else if (jqXHR.status === 403) { - GroovyConsole.showError('You do not have permission to schedule jobs in the Groovy Console.'); - } else { - GroovyConsole.showError('Job scheduling failed. Check error.log file.'); - } - }).always(function () { - scriptEditor.setReadOnly(false); - dataEditor.setReadOnly(false); - - GroovyConsole.hideLoader(); - GroovyConsole.enableButtons(); - GroovyConsole.ScheduledJobs.refreshScheduledJobs(); - - $('#schedule-job-text').text('Schedule Job'); - }); - } else { - GroovyConsole.showError('Script is empty.'); - } - }); - - $('#run-script').click(function () { - if ($('#run-script').hasClass('disabled')) { - return; - } - - GroovyConsole.reset(); - GroovyConsole.clearScheduler(); - - var script = scriptEditor.getSession().getValue(); - - if (script.length) { - scriptEditor.setReadOnly(true); - dataEditor.setReadOnly(true); - - GroovyConsole.showLoader(); - GroovyConsole.disableButtons(); - - $('#run-script-text').text('Running...'); - - $.post(CQ.shared.HTTP.getContextPath() + '/bin/groovyconsole/post.json', { - script: script, - data: dataEditor.getSession().getValue() - }).done(function (response) { - GroovyConsole.showResult(response); - }).fail(function (jqXHR) { - if (jqXHR.status === 403) { - GroovyConsole.showError('You do not have permission to run scripts in the Groovy Console.'); - } else { - GroovyConsole.showError('Script execution failed. Check error.log file.'); - } - }).always(function () { - scriptEditor.setReadOnly(false); - dataEditor.setReadOnly(false); - - GroovyConsole.hideLoader(); - GroovyConsole.enableButtons(); - GroovyConsole.Audit.refreshAuditRecords(); - - $('#run-script-text').text('Run Script'); - }); - } else { - GroovyConsole.showError('Script is empty.'); - } - }); - - $('body').keydown(function (e) { - if (e.ctrlKey) { - if (e.keyCode === 13) { - $('#run-script').click(); - } else if (e.keyCode === 78) { - $('#new-script').click(); - } - } - }); - - $('.copy-link').click(function (e) { - e.preventDefault(); - - var $copyLink = $(this); - var $temp = $('