X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.slc.core%2Fsrc%2Forg%2Fargeo%2Fslc%2Fcore%2Fexecution%2Fhttp%2FRunnerServlet.java;h=32d59d9e4ac1b4cae6580c55e607805f47d8186f;hb=429aade2313250c4ce929e6f037ba5e6a40bad5d;hp=4147bad179e8311349e8275969c7b6aa3b29b01d;hpb=722918f252478534eee153bf20bb2c1267bbe896;p=gpl%2Fargeo-slc.git diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/http/RunnerServlet.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/http/RunnerServlet.java index 4147bad17..32d59d9e4 100644 --- a/org.argeo.slc.core/src/org/argeo/slc/core/execution/http/RunnerServlet.java +++ b/org.argeo.slc.core/src/org/argeo/slc/core/execution/http/RunnerServlet.java @@ -1,19 +1,21 @@ package org.argeo.slc.core.execution.http; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.channels.Channels; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.security.AccessControlContext; import java.security.PrivilegedAction; import java.util.Collection; import java.util.GregorianCalendar; +import java.util.Map; import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.Future; import javax.jcr.Node; @@ -22,7 +24,6 @@ import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.nodetype.NodeType; -import javax.naming.ldap.LdapName; import javax.security.auth.Subject; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; @@ -36,9 +37,9 @@ import org.argeo.cms.auth.CmsSession; import org.argeo.jcr.JcrUtils; import org.argeo.node.NodeUtils; import org.argeo.slc.SlcException; +import org.argeo.slc.SlcNames; +import org.argeo.slc.SlcTypes; import org.argeo.slc.execution.ExecutionProcess; -import org.argeo.slc.jcr.SlcNames; -import org.argeo.slc.jcr.SlcTypes; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; @@ -54,11 +55,16 @@ public class RunnerServlet extends HttpServlet { private Path baseDir; private BundleContext bc; private ExecutorService executor; + private boolean persistProcesses = true; - public RunnerServlet(BundleContext bc, Path baseDir) { + public RunnerServlet(BundleContext bc, Path baseDir, ExecutorService executor) { this.bc = bc; this.baseDir = baseDir; - this.executor = Executors.newFixedThreadPool(20); + this.executor = executor; + } + + protected void setPersistProcesses(boolean persistProcesses) { + this.persistProcesses = persistProcesses; } @Override @@ -68,6 +74,17 @@ public class RunnerServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + InputStream in; + // Deal with x-www-form-urlencoded + // FIXME make it more robust an generic + Map params = req.getParameterMap(); + if (params.size() != 0) { + String json = params.keySet().iterator().next(); + in = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8)); + } else { + in = req.getInputStream(); + } + // InputStream in = req.getInputStream(); // Gson gson = new Gson(); // JsonParser jsonParser = new JsonParser(); @@ -75,8 +92,13 @@ public class RunnerServlet extends HttpServlet { // Charset.forName("UTF-8"))); // JsonElement payload = jsonParser.parse(reader); // String payloadStr = gson.toJson(payload); + // + // log.debug(payloadStr); + // if (true) + // return; + String path = req.getPathInfo(); - InputStream in = req.getInputStream(); + // InputStream in = req.getInputStream(); OutputStream out = resp.getOutputStream(); String tokens[] = path.split("/"); @@ -84,19 +106,21 @@ public class RunnerServlet extends HttpServlet { String workgroup = tokens[1]; CmsSession cmsSession = getByLocalId(req.getSession().getId()); - - boolean authorized = false; - for (String role : cmsSession.getAuthorization().getRoles()) { - if (role.startsWith("cn=" + workgroup)) { - authorized = true; - break; + // FIXME make it more robust + if (cmsSession != null) {// multiuser + boolean authorized = false; + for (String role : cmsSession.getAuthorization().getRoles()) { + if (role.startsWith("cn=" + workgroup) || role.startsWith("uid=" + workgroup)) { + authorized = true; + break; + } + } + if (!authorized) { + resp.setStatus(403); + return; } } - if (!authorized) { - resp.setStatus(403); - return; - } - LdapName userDn = cmsSession.getUserDn(); + // LdapName userDn = cmsSession.getUserDn(); AccessControlContext acc = (AccessControlContext) req.getAttribute(HttpContext.REMOTE_USER); Subject subject = Subject.getSubject(acc); // flow path @@ -109,48 +133,61 @@ public class RunnerServlet extends HttpServlet { String flowName = sb.toString(); String ext = FilenameUtils.getExtension(flowName.toString()); - // JCR - Repository repository = bc.getService(bc.getServiceReference(Repository.class)); - Session session = Subject.doAs(subject, new PrivilegedAction() { + Session session = null; + Node realizedFlowNode = null; + if (persistProcesses) { + // JCR + Repository repository; + try { + ServiceReference sr = bc.getServiceReferences(Repository.class, "(cn=home)").iterator() + .next(); + repository = bc.getService(sr); - @Override - public Session run() { - try { - return repository.login(); - } catch (RepositoryException e) { - throw new RuntimeException("Cannot login", e); - } + } catch (InvalidSyntaxException e2) { + throw new SlcException("Cannot find home repository", e2); } + session = Subject.doAs(subject, new PrivilegedAction() { - }); - UUID processUuid = UUID.randomUUID(); - GregorianCalendar started = new GregorianCalendar(); - Node groupHome = NodeUtils.getGroupHome(session, workgroup); - String processPath = SlcNames.SLC_SYSTEM + "/" + SlcNames.SLC_PROCESSES + "/" - + JcrUtils.dateAsPath(started, true) + processUuid; - Node processNode = JcrUtils.mkdirs(groupHome, processPath, SlcTypes.SLC_PROCESS); - Node realizedFlowNode; - try { - processNode.setProperty(SlcNames.SLC_UUID, processUuid.toString()); - processNode.setProperty(SlcNames.SLC_STATUS, ExecutionProcess.RUNNING); - realizedFlowNode = processNode.addNode(SlcNames.SLC_FLOW); - realizedFlowNode.addMixin(SlcTypes.SLC_REALIZED_FLOW); - realizedFlowNode.setProperty(SlcNames.SLC_STARTED, started); - realizedFlowNode.setProperty(SlcNames.SLC_NAME, flowName); - Node addressNode = realizedFlowNode.addNode(SlcNames.SLC_ADDRESS, NodeType.NT_ADDRESS); - addressNode.setProperty(Property.JCR_PATH, flowName); - processNode.getSession().save(); - } catch (RepositoryException e1) { - throw new SlcException("Cannot register SLC process", e1); - } + @Override + public Session run() { + try { + return repository.login(); + } catch (RepositoryException e) { + throw new RuntimeException("Cannot login", e); + } + } - if (log.isDebugEnabled()) - log.debug(userDn + " " + workgroup + " " + flowName); + }); + UUID processUuid = UUID.randomUUID(); + GregorianCalendar started = new GregorianCalendar(); + Node groupHome = NodeUtils.getGroupHome(session, workgroup); + if (groupHome == null) { + groupHome = NodeUtils.getUserHome(session); + } + String processPath = SlcNames.SLC_SYSTEM + "/" + SlcNames.SLC_PROCESSES + "/" + + JcrUtils.dateAsPath(started, true) + processUuid; + Node processNode = JcrUtils.mkdirs(groupHome, processPath, SlcTypes.SLC_PROCESS); + try { + processNode.setProperty(SlcNames.SLC_UUID, processUuid.toString()); + processNode.setProperty(SlcNames.SLC_STATUS, ExecutionProcess.RUNNING); + realizedFlowNode = processNode.addNode(SlcNames.SLC_FLOW); + realizedFlowNode.addMixin(SlcTypes.SLC_REALIZED_FLOW); + realizedFlowNode.setProperty(SlcNames.SLC_STARTED, started); + realizedFlowNode.setProperty(SlcNames.SLC_NAME, flowName); + Node addressNode = realizedFlowNode.addNode(SlcNames.SLC_ADDRESS, NodeType.NT_ADDRESS); + addressNode.setProperty(Property.JCR_PATH, flowName); + processNode.getSession().save(); + } catch (RepositoryException e1) { + throw new SlcException("Cannot register SLC process", e1); + } + if (log.isTraceEnabled()) + log.trace(session.getUserID() + " " + workgroup + " " + flowName); + } - try { + try (ServiceChannel serviceChannel = new ServiceChannel(Channels.newChannel(in), Channels.newChannel(out), + executor)) { resp.setHeader("Content-Type", "application/json"); - ServiceChannel serviceChannel = new ServiceChannel(Channels.newChannel(in), Channels.newChannel(out), - executor); + Callable task; if (ext.equals("api")) { String uri = Files.readAllLines(baseDir.resolve(flowName)).get(0); @@ -167,21 +204,25 @@ public class RunnerServlet extends HttpServlet { int written = f.get(); if (log.isTraceEnabled()) log.trace("Written " + written + " bytes"); - try { - processNode.setProperty(SlcNames.SLC_STATUS, ExecutionProcess.COMPLETED); - realizedFlowNode.setProperty(SlcNames.SLC_COMPLETED, new GregorianCalendar()); - processNode.getSession().save(); - } catch (RepositoryException e1) { - throw new SlcException("Cannot update SLC process status", e1); - } + if (persistProcesses) + try { + Node processNode = realizedFlowNode.getParent(); + processNode.setProperty(SlcNames.SLC_STATUS, ExecutionProcess.COMPLETED); + realizedFlowNode.setProperty(SlcNames.SLC_COMPLETED, new GregorianCalendar()); + processNode.getSession().save(); + } catch (RepositoryException e1) { + throw new SlcException("Cannot update SLC process status", e1); + } } catch (Exception e) { - try { - processNode.setProperty(SlcNames.SLC_STATUS, ExecutionProcess.ERROR); - realizedFlowNode.setProperty(SlcNames.SLC_COMPLETED, new GregorianCalendar()); - processNode.getSession().save(); - } catch (RepositoryException e1) { - throw new SlcException("Cannot update SLC process status", e1); - } + if (persistProcesses) + try { + Node processNode = realizedFlowNode.getParent(); + processNode.setProperty(SlcNames.SLC_STATUS, ExecutionProcess.ERROR); + realizedFlowNode.setProperty(SlcNames.SLC_COMPLETED, new GregorianCalendar()); + processNode.getSession().save(); + } catch (RepositoryException e1) { + throw new SlcException("Cannot update SLC process status", e1); + } throw new SlcException("Task " + flowName + " failed", e); } finally { JcrUtils.logoutQuietly(session); @@ -203,6 +244,10 @@ public class RunnerServlet extends HttpServlet { return baseDir; } + protected HttpContext getHttpContext(String httpAuthrealm) { + return null; + } + public static void register(BundleContext bc, String alias, RunnerServlet runnerServlet, String httpAuthrealm) { try { ServiceTracker serviceTracker = new ServiceTracker(bc, @@ -213,7 +258,10 @@ public class RunnerServlet extends HttpServlet { // TODO Auto-generated method stub HttpService httpService = super.addingService(reference); try { - httpService.registerServlet(alias, runnerServlet, null, new RunnerHttpContext(httpAuthrealm)); + HttpContext httpContext = runnerServlet.getHttpContext(httpAuthrealm); + if (httpContext == null) + httpContext = new RunnerHttpContext(httpAuthrealm); + httpService.registerServlet(alias, runnerServlet, null, httpContext); } catch (Exception e) { throw new SlcException("Cannot register servlet", e); }