Skip to content

Commit

Permalink
#349 add support for inserting/updating/deleting scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
syjer committed Jan 2, 2018
1 parent 6d127dc commit 5dd972a
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ public List<ScriptSupport> listAll(Principal principal) {
return scriptingService.listAll();
}

/*
function getScriptMetadata() {
return {async:true, events: ['TEST']};
}
function executeScript() {
}
*/
@RequestMapping(value = "/scripting", method = RequestMethod.POST)
public void createOrUpdate(@RequestBody Script script, Principal principal) {
ensureAdmin(principal);
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/alfio/model/ScriptSupport.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
package alfio.model;

import ch.digitalfondue.npjt.ConstructorAnnotationRowMapper.Column;
import lombok.Getter;

@Getter
public class ScriptSupport {

private final String path;
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/alfio/repository/ScriptRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,17 @@ int insert(@Bind("path") String path,
@Query("update script_support set enabled = :enabled where path = :path")
int toggle(@Bind("path") String path, @Bind("enabled") boolean enabled);

@Query("insert into script_event(path, event) values " +
@Query("insert into script_event(path_fk, event) values " +
" (:path, :event)")
int insert(@Bind("path") String path, @Bind("event ") String event);
int insert(@Bind("path") String path, @Bind("event") String event);

@Query("select count(*) from script_support where path = :path")
int hasPath(@Bind("path") String path);

@Query("select script from script_support where path = :path")
String getScript(@Bind("path") String path);

@Query("delete from script_event where path = :path")
@Query("delete from script_event where path_fk = :path")
int deleteEventsForPath(@Bind("path") String path);

@Query("delete from script_support where path = :path")
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/alfio/scripting/ScriptMetadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,13 @@

package alfio.scripting;

import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.List;

@Getter
@AllArgsConstructor
public class ScriptMetadata {
boolean async;
List<String> events;
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/alfio/scripting/ScriptingExecutionService.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.springframework.stereotype.Service;

import javax.script.*;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.*;
import java.util.function.Supplier;
Expand All @@ -43,7 +44,7 @@
@Log4j2
public class ScriptingExecutionService {

private final static Compilable engine = (Compilable) new ScriptEngineManager().getEngineByName("javascript");
private final static Compilable engine = (Compilable) new ScriptEngineManager().getEngineByName("nashorn");
private final Cache<String, CompiledScript> compiledScriptCache = Caffeine.newBuilder()
.expireAfterAccess(12, TimeUnit.HOURS)
.build();
Expand Down Expand Up @@ -81,6 +82,9 @@ public static <T> T executeScript(String name, String script, Map<String, Object

private static Object executeScript(String name, CompiledScript script, Map<String, Object> params) {
try {
if(params == null) {
params = Collections.emptyMap();
}
ScriptContext newContext = new SimpleScriptContext();
Bindings engineScope = newContext.getBindings(ScriptContext.ENGINE_SCOPE);
engineScope.putAll(params);
Expand Down
18 changes: 11 additions & 7 deletions src/main/java/alfio/scripting/ScriptingService.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,16 @@
import alfio.model.ScriptSupport;
import alfio.repository.ScriptRepository;
import alfio.util.Json;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.tuple.Triple;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.script.Bindings;
import java.util.*;

@Service
@Log4j2
Expand All @@ -44,11 +43,16 @@ public class ScriptingService {
@Transactional
public void createOrUpdate(Script script) {
String hash = DigestUtils.sha256Hex(script.getScript());
ScriptMetadata scriptMetadata = ScriptingExecutionService.executeScript(
Bindings scriptMetadataBinding = ScriptingExecutionService.executeScript(
script.getName(),
script.getScript() + "\n;return getScriptMetadata();",
script.getScript() + "\n;getScriptMetadata();",
script.getConfiguration());

//extracting the object {async: boolean, events: String[]}
boolean async = (Boolean) scriptMetadataBinding.getOrDefault("async", Boolean.FALSE);
List<String> events = Arrays.asList(((ScriptObjectMirror) scriptMetadataBinding.get("events")).to(String[].class));

ScriptMetadata scriptMetadata = new ScriptMetadata(async, events);

if(scriptRepository.hasPath(script.getPath()) > 0) {
scriptRepository.deleteEventsForPath(script.getPath());
Expand Down Expand Up @@ -84,7 +88,7 @@ public <T> T executeScriptsForEvent(String event, String basePath, Map<String, O
for(Triple<String, String, String> activePath : activePaths) {
String path = activePath.getLeft();
res = scriptingExecutionService.executeScript(activePath.getLeft(), activePath.getMiddle(), activePath.getRight(),
() -> getScript(path)+"\n;return executeScript(event);", input);
() -> getScript(path)+"\n;executeScript(event);", input);
input.put("output", res);
}
return res;
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,36 @@
add/update
<div class="modal-header">
<h3>Add/Update script</h3>
</div>
<form role="form" name="script" ng-submit="$ctrl.save($ctrl.script)" data-error-sensitive novalidate data-oncancel="$ctrl.cancel()">
<div class="modal-body">
<div class="form-group" bs-form-error="$ctrl.script.path">
<label for="script-path">Path</label>
<input class="form-control" type="text" data-grab-focus id="script-path" name="path" data-ng-model="$ctrl.script.path" required>
<field-error data-form-obj="script" data-field-obj="$ctrl.script.path"></field-error>
</div>

<div class="form-group" bs-form-error="$ctrl.script.name">
<label for="script-name">Name</label>
<input class="form-control" type="text" data-grab-focus id="script-name" name="name" data-ng-model="$ctrl.script.name" required>
<field-error data-form-obj="script" data-field-obj="$ctrl.script.name"></field-error>
</div>

<div class="form-group" bs-form-error="$ctrl.script.enabled">
<label for="script-enabled">Enabled</label>
<input type="checkbox" data-grab-focus id="script-enabled" name="enabled" data-ng-model="$ctrl.script.enabled">
<field-error data-form-obj="script" data-field-obj="$ctrl.script.enabled"></field-error>
</div>

<div class="form-group" bs-form-error="$ctrl.script.script">
<label for="script-script">Script</label>
<textarea class="form-control" id="script-script" name="script" data-ng-model="$ctrl.script.script" required></textarea>
<field-error data-form-obj="script" data-field-obj="$ctrl.script.script"></field-error>
</div>
</div>
<div class="modal-footer">
<div>
<button type="submit" class="btn btn-success" data-ng-disabled="scriptForm.$waiting">Save</button>
<button type="button" class="btn btn-default" data-ng-disabled="scriptForm.$waiting" ng-click="$ctrl.dismiss()">Cancel</button>
</div>
</div>
</form>
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,34 @@

angular.module('adminApplication').component('scriptingAddUpdate', {
controller: ['$http', ScriptingAddUpdateCtrl],
templateUrl: '../resources/js/admin/feature/scripting/add-update/scripting-add-update.html'
templateUrl: '../resources/js/admin/feature/scripting/add-update/scripting-add-update.html',
bindings: {
dismiss:'&',
close:'&',
toUpdate:'<'
}
});

function ScriptingAddUpdateCtrl($http) {
var ctrl = this;

ctrl.$onInit = function() {
if(ctrl.toUpdate) {
//deep cloning
ctrl.script = JSON.parse(JSON.stringify(ctrl.toUpdate));
}
}


ctrl.save = function(script) {
$http.post('/admin/api/scripting', {
path: script.path,
name: script.name,
enabled: script.enabled,
script: script.script
}).then(function() {
ctrl.close({$script: script});
});
}
}
})();
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ <h1>Scripting</h1>
<tr>
<th>path</th>
<th>name</th>
<th>enabled</th>
<th width="10%"><span class="sr-only">actions</span></th>
</tr>
</thead>
Expand All @@ -19,9 +20,10 @@ <h1>Scripting</h1>
<tr ng-repeat="script in $ctrl.scripts">
<td>{{script.path}}</td>
<td>{{script.name}}</td>
<td>{{script.enabled}}</td>
<td class="text-center">
<button class="btn btn-small" ng-click="$ctrl.addNewOrUpdate(script)">edit</button>
<button class="btn btn-small">delete</button>
<button class="btn btn-small" ng-click="$ctrl.deleteScript(script)">delete</button>
</td>
</tr>
</tbody>
Expand Down
30 changes: 27 additions & 3 deletions src/main/webapp/resources/js/admin/feature/scripting/scripting.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,43 @@
};

this.addNewOrUpdate = addNewOrUpdate;
this.deleteScript = deleteScript;


function load() {
$http.get('/admin/api/scripting').then(function(res) {
ctrl.scripts = res.data;
})
}

function deleteScript(script) {
if(window.confirm('Delete script ' + script.name+'?')) {
$http.delete('/admin/api/scripting/' + script.path).then(function () {
load();
});
}
}


function addNewOrUpdate(script) {
$uibModal.open({
template: '<scripting-add-update></scripting-add-update>'
})
var modal = $uibModal.open({
template: '<scripting-add-update to-update="ctrl.toUpdate" close="ctrl.close($script)" dismiss="ctrl.dismiss()"></scripting-add-update>',
controller: function() {
var ctrl = this;

ctrl.toUpdate = script;

ctrl.dismiss = function() {
modal.dismiss();
}

ctrl.close = function(script) {
modal.close();
load();
}
},
controllerAs: 'ctrl'
});
}
}
})();

0 comments on commit 5dd972a

Please sign in to comment.