Skip to content

Commit

Permalink
Merge branch 'release/15.1.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark Daugherty committed May 5, 2020
2 parents 630db56 + 5ab57e9 commit 21dfab0
Show file tree
Hide file tree
Showing 20 changed files with 198 additions and 32 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,12 @@ Property | Description | Default Value
------------ | ------------- | ----------
Email Enabled? | Check to enable email notification on completion of script execution. | `false`
Email Recipients | Email addresses to receive notification. | `[]`
Allowed Groups | List of group names that are authorized to use the console. By default, only the `admin` user has permission to execute scripts.
Script Execution Allowed Groups | List of group names that are authorized to use the console. By default, only the 'admin' user has permission to execute scripts. | `[]`
Scheduled Jobs Allowed Groups | List of group names that are authorized to schedule jobs. By default, only the 'admin' user has permission to schedule jobs. | `[]`
Vanity Path Enabled? | Enables `/groovyconsole` vanity path. | `false`
Audit Disabled? | Disables auditing of script execution history. | `false`
Display All Audit Records? | If enabled, all audit records (including records for other users) will be displayed in the console history. | `false`
Thread Timeout | Time in seconds that scripts are allowed to execute before being interrupted. If 0, no timeout is enforced. | 0

## Batch Script Execution

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<groupId>com.icfolson.aem.groovy.console</groupId>
<artifactId>aem-groovy-console</artifactId>
<packaging>jar</packaging>
<version>15.0.1</version>
<version>15.1.0</version>
<name>AEM Groovy Console</name>
<description>
The AEM Groovy Console provides an interface for running Groovy scripts in the AEM container. Scripts can be
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ GroovyConsole.Audit = function () {
data: 'date',
searchable: false
},
{
data: 'jobTitle'
},
{
data: 'script',
orderable: false
Expand All @@ -46,7 +49,7 @@ GroovyConsole.Audit = function () {
order: [[2, 'desc']],
language: {
emptyTable: 'No audit records found.',
search: 'Script Contains: ',
search: 'Contains: ',
zeroRecords: 'No matching audit records found.',
info: 'Showing _START_ to _END_ of _TOTAL_ records',
infoEmpty: '',
Expand All @@ -58,8 +61,8 @@ GroovyConsole.Audit = function () {
}

$('td:eq(2)', row).html('<a href="' + data.link + '">' + data.date + '</a>');
$('td:eq(3)', row).html('<code>' + data.scriptPreview + '</code><div class="hidden">' + data.script + '</div>');
$('td:eq(3)', row).popover({
$('td:eq(4)', row).html('<code>' + data.scriptPreview + '</code><div class="hidden">' + data.script + '</div>');
$('td:eq(4)', row).popover({
container: 'body',
content: '<pre>' + data.script + '</pre>',
html: true,
Expand All @@ -68,7 +71,7 @@ GroovyConsole.Audit = function () {
});

if (data.exception.length) {
$('td:eq(4)', row).html('<span class="label label-danger">' + data.exception + '</span>');
$('td:eq(5)', row).html('<span class="label label-danger">' + data.exception + '</span>');
}
}
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<div class="panel panel-default" data-sly-use.panel="com.icfolson.aem.groovy.console.components.ActiveJobsPanel">
<div class="panel-heading">
<h4 class="panel-title">Active Jobs</h4>
</div>
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Start Time</th>
<th>Title</th>
<th>Description</th>
<th>Script</th>
</tr>
</thead>
<tbody>
<tr data-sly-repeat.job="${panel.activeJobs}">
<td>${job.id}</td>
<td>${job.formattedStartTime}</td>
<td>${job.title}</td>
<td>${job.description}</td>
<td>${job.script}</td>
</tr>
</tbody>
</table>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,11 @@ <h6>Running Time</h6>
<pre></pre>
</div>

<sly data-sly-include="active-jobs.html" data-sly-test="${body.hasActiveJobs}"></sly>

<div class="panel-group" id="info">
<sly data-sly-include="history.html" data-sly-test="${body.auditEnabled}"></sly>
<sly data-sly-include="scheduled-jobs.html" data-sly-test="${body.hasScheduledJobPermission}"></sly>
<sly data-sly-include="history.html" data-sly-test="${body.auditEnabled}"></sly>
<sly data-sly-include="bindings.html"></sly>
<sly data-sly-include="imports.html"></sly>
<sly data-sly-include="methods.html"></sly>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ <h4 class="panel-title">
<th></th>
<th></th>
<th>Date</th>
<th>Job Title</th>
<th>Script</th>
<th></th>
<th></th>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="panel panel-default" data-sly-use.history="com.icfolson.aem.groovy.console.components.HistoryPanel">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#info" href="#scheduled-jobs">Scheduled Jobs</a>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.icfolson.aem.groovy.console

import com.icfolson.aem.groovy.console.api.ActiveJob
import com.icfolson.aem.groovy.console.api.JobProperties
import com.icfolson.aem.groovy.console.api.context.ScriptContext
import com.icfolson.aem.groovy.console.api.context.ScriptData
Expand Down Expand Up @@ -34,4 +35,11 @@ interface GroovyConsoleService {
* @return true if job was successfully added
*/
boolean addScheduledJob(JobProperties jobProperties)

/**
* Get a list of all active jobs.
*
* @return list of active jobs
*/
List<ActiveJob> getActiveJobs()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.icfolson.aem.groovy.console.api

import com.icfolson.aem.groovy.console.constants.GroovyConsoleConstants
import com.icfolson.aem.groovy.console.utils.GroovyScriptUtils
import groovy.transform.Memoized
import groovy.transform.TupleConstructor
import org.apache.sling.event.jobs.Job

@TupleConstructor
class ActiveJob {

Job job

String getFormattedStartTime() {
job.processingStarted.format(GroovyConsoleConstants.DATE_FORMAT_DISPLAY)
}

String getId() {
job.id
}

String getTitle() {
jobProperties.jobTitle
}

String getDescription() {
jobProperties.jobDescription
}

String getScript() {
GroovyScriptUtils.getScriptPreview(jobProperties.script)
}

@Memoized
JobProperties getJobProperties() {
JobProperties.fromJob(job)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,13 @@ interface AuditService {
* @return list of audit records in the given date range
*/
List<AuditRecord> getAuditRecords(String userId, Calendar startDate, Calendar endDate)

/**
* Get a list of scheduled job audit records for the given date range.
*
* @param startDate start date
* @param endDate end date
* @return list of scheduled job audit records in the given date range
*/
List<AuditRecord> getScheduledJobAuditRecords(Calendar startDate, Calendar endDate)
}
Original file line number Diff line number Diff line change
Expand Up @@ -164,16 +164,12 @@ class DefaultAuditService implements AuditService {

@Override
List<AuditRecord> getAuditRecords(String userId, Calendar startDate, Calendar endDate) {
getAllAuditRecords(userId).findAll { auditRecord ->
def auditRecordDate = auditRecord.date

auditRecordDate.set(Calendar.HOUR_OF_DAY, 0)
auditRecordDate.set(Calendar.MINUTE, 0)
auditRecordDate.set(Calendar.SECOND, 0)
auditRecordDate.set(Calendar.MILLISECOND, 0)
getAuditRecordsForDateRange(getAllAuditRecords(userId), startDate, endDate)
}

!auditRecordDate.before(startDate) && !auditRecordDate.after(endDate)
}
@Override
List<AuditRecord> getScheduledJobAuditRecords(Calendar startDate, Calendar endDate) {
getAuditRecordsForDateRange(allScheduledJobAuditRecords, startDate, endDate)
}

@Activate
Expand Down Expand Up @@ -280,6 +276,19 @@ class DefaultAuditService implements AuditService {
auditRecords
}

private List<AuditRecord> getAuditRecordsForDateRange(List<AuditRecord> auditRecords, Calendar startDate, Calendar endDate) {
auditRecords.findAll { auditRecord ->
def auditRecordDate = auditRecord.date

auditRecordDate.set(Calendar.HOUR_OF_DAY, 0)
auditRecordDate.set(Calendar.MINUTE, 0)
auditRecordDate.set(Calendar.SECOND, 0)
auditRecordDate.set(Calendar.MILLISECOND, 0)

!auditRecordDate.before(startDate) && !auditRecordDate.after(endDate)
}
}

private <T> T withResourceResolver(Closure<T> closure) {
resourceResolverFactory.getServiceResourceResolver(null).withCloseable(closure)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.icfolson.aem.groovy.console.components

import com.icfolson.aem.groovy.console.GroovyConsoleService
import com.icfolson.aem.groovy.console.api.ActiveJob
import org.apache.sling.api.SlingHttpServletRequest
import org.apache.sling.models.annotations.Model
import org.apache.sling.models.annotations.injectorspecific.OSGiService

@Model(adaptables = SlingHttpServletRequest)
class ActiveJobsPanel {

@OSGiService
private GroovyConsoleService groovyConsoleService

List<ActiveJob> getActiveJobs() {
groovyConsoleService.activeJobs
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package com.icfolson.aem.groovy.console.components

import com.icfolson.aem.groovy.console.GroovyConsoleService
import com.icfolson.aem.groovy.console.audit.AuditRecord
import com.icfolson.aem.groovy.console.audit.AuditService
import com.icfolson.aem.groovy.console.configuration.ConfigurationService
import groovy.json.JsonBuilder
import org.apache.sling.api.SlingHttpServletRequest
import org.apache.sling.models.annotations.Model
import org.apache.sling.models.annotations.injectorspecific.OSGiService
import org.apache.sling.models.annotations.injectorspecific.Self

import javax.annotation.PostConstruct
import javax.inject.Inject

import static com.icfolson.aem.groovy.console.constants.GroovyConsoleConstants.SCRIPT
import static com.icfolson.aem.groovy.console.constants.GroovyConsoleConstants.USER_ID
Expand All @@ -20,12 +21,15 @@ class Body {
@OSGiService
private AuditService auditService

@Inject
private SlingHttpServletRequest request

@OSGiService
private ConfigurationService configurationService

@OSGiService
private GroovyConsoleService groovyConsoleService

@Self
private SlingHttpServletRequest request

private AuditRecord auditRecord

@PostConstruct
Expand All @@ -46,6 +50,10 @@ class Body {
configurationService.hasScheduledJobPermission(request)
}

boolean isHasActiveJobs() {
groovyConsoleService.activeJobs
}

boolean isAuditEnabled() {
!configurationService.auditDisabled
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@ import com.icfolson.aem.groovy.console.audit.AuditService
import org.apache.sling.api.SlingHttpServletRequest
import org.apache.sling.models.annotations.Model
import org.apache.sling.models.annotations.injectorspecific.OSGiService

import javax.inject.Inject
import org.apache.sling.models.annotations.injectorspecific.Self

@Model(adaptables = SlingHttpServletRequest)
class HistoryPanel {

@OSGiService
private AuditService auditService

@Inject
@Self
private SlingHttpServletRequest request

Boolean isHasAuditRecords() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,11 @@ interface ConfigurationService {
* @return if true, display all audit records
*/
boolean isDisplayAllAuditRecords()

/**
* Get the thread timeout value in seconds. Scripts will be interrupted when the timeout value is reached. If zero, no timeout will be enforced.
*
* @return thread timeout
*/
long getThreadTimeout()
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ class DefaultConfigurationService implements ConfigurationService {

private boolean displayAllAuditRecords

private long threadTimeout

@Override
boolean hasPermission(SlingHttpServletRequest request) {
isAdminOrAllowedGroupMember(request, allowedGroups)
Expand Down Expand Up @@ -74,6 +76,11 @@ class DefaultConfigurationService implements ConfigurationService {
displayAllAuditRecords
}

@Override
long getThreadTimeout() {
threadTimeout
}

@Activate
@Modified
@Synchronized
Expand All @@ -85,6 +92,7 @@ class DefaultConfigurationService implements ConfigurationService {
vanityPathEnabled = properties.vanityPathEnabled()
auditDisabled = properties.auditDisabled()
displayAllAuditRecords = properties.auditDisplayAll()
threadTimeout = properties.threadTimeout()
}

private boolean isAdminOrAllowedGroupMember(SlingHttpServletRequest request, Set<String> groupIds) {
Expand Down
Loading

0 comments on commit 21dfab0

Please sign in to comment.