package org.infinispan.server.infinispan.task; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; import org.infinispan.commons.CacheException; import org.infinispan.commons.marshall.Marshaller; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.security.AuthorizationManager; import org.infinispan.security.AuthorizationPermission; import org.infinispan.security.impl.AuthorizationHelper; import org.infinispan.tasks.Task; import org.infinispan.tasks.TaskContext; import org.infinispan.tasks.spi.TaskEngine; /** * Author: Michal Szynkiewicz, michal.l.szynkiewicz@gmail.com * Date: 1/20/16 * Time: 12:32 PM */ public class ServerTaskEngine implements TaskEngine { private final AuthorizationHelper globalAuthzHelper; private final ServerTaskRegistry registry; private final ServerTaskRunnerFactory runnerFactory = new ServerTaskRunnerFactory(); public ServerTaskEngine(ServerTaskRegistry manager, EmbeddedCacheManager cacheManager) { this.registry = manager; this.globalAuthzHelper = cacheManager.getGlobalComponentRegistry().getComponent(AuthorizationHelper.class); } @Override public String getName() { return "Deployed"; } @Override public List<Task> getTasks() { return registry.getTasks(); } @Override public <T> CompletableFuture<T> runTask(String taskName, TaskContext context) { ServerTaskWrapper<T> task = registry.<T>getTask(taskName); if (task == null) { throw new IllegalArgumentException("Task not found: " + taskName); } checkPermissions(context, task); return invokeTask(context, task); } private <T> CompletableFuture<T> invokeTask(TaskContext context, ServerTaskWrapper<T> task) { ServerTaskRunner runner = runnerFactory.getRunner(task.getExecutionMode()); launderParameters(context); return runner.execute(task.getName(), context).thenApply(r -> (T) context.getMarshaller().map(m -> toBytes(r, m)).orElse(r)); } private static Object toBytes(Object obj, Marshaller marshaller) { try { return marshaller.objectToByteBuffer(obj); } catch (Exception e) { throw new CacheException(e); } } private void launderParameters(TaskContext context) { if (context.getParameters().isPresent() && context.getMarshaller().isPresent()) { Map<String, ?> params = context.getParameters().get(); Marshaller m = context.getMarshaller().get(); for (Map.Entry<String, ?> e : params.entrySet()) { Object v = e.getValue(); Object entryValue = v instanceof byte[] ? fromBytes(v, m) : v; context.addParameter(e.getKey(), entryValue); } } } private static Object fromBytes(Object obj, Marshaller marshaller) { try { return marshaller.objectFromByteBuffer((byte[]) obj); } catch (Exception e) { throw new CacheException(e); } } private <T> void checkPermissions(TaskContext context, ServerTaskWrapper<T> task) { String role = task.getRole().orElse(null); if (globalAuthzHelper != null) { if (context.getCache().isPresent()) { AuthorizationManager authorizationManager = context.getCache().get().getAdvancedCache().getAuthorizationManager(); if (authorizationManager != null) { authorizationManager.checkPermission(AuthorizationPermission.EXEC, role); return; } } globalAuthzHelper.checkPermission(null, AuthorizationPermission.EXEC, role); } } @Override public boolean handles(String taskName) { return registry.handles(taskName); } }