Remove runner servlet
authorMathieu Baudier <mbaudier@argeo.org>
Sun, 12 May 2019 08:43:04 +0000 (10:43 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Sun, 12 May 2019 08:43:04 +0000 (10:43 +0200)
org.argeo.slc.core/src/org/argeo/slc/core/execution/http/RunnerHttpContext.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/http/RunnerServlet.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/http/RunnerServletContextHelper.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/http/ServiceChannel.java [deleted file]
org.argeo.slc.core/src/org/argeo/slc/core/execution/http/WebServiceTask.java [deleted file]

diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/http/RunnerHttpContext.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/http/RunnerHttpContext.java
deleted file mode 100644 (file)
index 6a67168..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-package org.argeo.slc.core.execution.http;
-
-import java.io.IOException;
-import java.net.URL;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.cms.auth.HttpRequestCallbackHandler;
-import org.argeo.node.NodeConstants;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.service.http.HttpContext;
-
-class RunnerHttpContext implements HttpContext {
-       final static String HEADER_WWW_AUTHENTICATE = "WWW-Authenticate";
-       private final static Log log = LogFactory.getLog(RunnerHttpContext.class);
-
-       private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
-
-       private final String httpAuthRealm;
-
-       public RunnerHttpContext(String httpAuthrealm) {
-               this.httpAuthRealm = httpAuthrealm;
-       }
-
-       @Override
-       public boolean handleSecurity(final HttpServletRequest request, HttpServletResponse response) throws IOException {
-               LoginContext lc;
-               try {
-                       lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, new HttpRequestCallbackHandler(request, response));
-                       lc.login();
-               } catch (LoginException e) {
-                       lc = processUnauthorized(request, response);
-                       if (lc == null)
-                               return false;
-               }
-               Subject.doAs(lc.getSubject(), new PrivilegedAction<Void>() {
-
-                       @Override
-                       public Void run() {
-                               request.setAttribute(REMOTE_USER, AccessController.getContext());
-                               return null;
-                       }
-
-               });
-
-               return true;
-       }
-
-       @Override
-       public URL getResource(String name) {
-               return bc.getBundle().getResource(name);
-       }
-
-       @Override
-       public String getMimeType(String name) {
-               return null;
-       }
-
-       protected LoginContext processUnauthorized(HttpServletRequest request, HttpServletResponse response) {
-               askForWwwAuth(request, response);
-               return null;
-       }
-
-       protected void askForWwwAuth(HttpServletRequest request, HttpServletResponse response) {
-               response.setStatus(401);
-               // if (org.argeo.cms.internal.kernel.Activator.getAcceptorCredentials()
-               // != null && !forceBasic)// SPNEGO
-               // response.setHeader(HttpUtils.HEADER_WWW_AUTHENTICATE, "Negotiate");
-               // else
-               response.setHeader(HEADER_WWW_AUTHENTICATE, "Basic realm=\"" + httpAuthRealm + "\"");
-
-       }
-
-}
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
deleted file mode 100644 (file)
index eb9b435..0000000
+++ /dev/null
@@ -1,313 +0,0 @@
-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.Future;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-import javax.security.auth.Subject;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-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.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.http.HttpContext;
-import org.osgi.service.http.HttpService;
-import org.osgi.util.tracker.ServiceTracker;
-
-public class RunnerServlet extends HttpServlet {
-       private final static Log log = LogFactory.getLog(RunnerServlet.class);
-
-       private static final long serialVersionUID = -317016687309065291L;
-
-       private Path baseDir;
-       private BundleContext bc;
-       private ExecutorService executor;
-       private boolean persistProcesses = true;
-
-       public RunnerServlet(BundleContext bc, Path baseDir, ExecutorService executor) {
-               this.bc = bc;
-               this.baseDir = baseDir;
-               this.executor = executor;
-       }
-
-       protected void setPersistProcesses(boolean persistProcesses) {
-               this.persistProcesses = persistProcesses;
-       }
-
-       @Override
-       protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-               super.service(req, resp);
-       }
-
-       @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<String, String[]> 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();
-               }
-
-               String path = req.getPathInfo();
-               // InputStream in = req.getInputStream();
-               OutputStream out = resp.getOutputStream();
-
-               String tokens[] = path.split("/");
-               // first token alway empty
-               String workgroup = tokens[1];
-
-               CmsSession cmsSession = getByLocalId(req.getSession().getId());
-               // 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;
-                       }
-               }
-               // LdapName userDn = cmsSession.getUserDn();
-               AccessControlContext acc = (AccessControlContext) req.getAttribute(HttpContext.REMOTE_USER);
-               Subject subject = Subject.getSubject(acc);
-               // flow path
-               StringBuilder sb = new StringBuilder("");
-               for (int i = 2; i < tokens.length; i++) {
-                       if (i != 2)
-                               sb.append('/');
-                       sb.append(tokens[i]);
-               }
-               String flowName = sb.toString();
-               String ext = FilenameUtils.getExtension(flowName.toString());
-
-               Session session = null;
-               Node realizedFlowNode = null;
-               if (persistProcesses) {
-                       // JCR
-                       Repository repository;
-                       try {
-                               ServiceReference<Repository> sr = bc.getServiceReferences(Repository.class, "(cn=home)").iterator()
-                                               .next();
-                               repository = bc.getService(sr);
-
-                       } catch (InvalidSyntaxException e2) {
-                               throw new SlcException("Cannot find home repository", e2);
-                       }
-                       session = Subject.doAs(subject, new PrivilegedAction<Session>() {
-
-                               @Override
-                               public Session run() {
-                                       try {
-                                               return repository.login();
-                                       } catch (RepositoryException e) {
-                                               throw new RuntimeException("Cannot login", e);
-                                       }
-                               }
-
-                       });
-                       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);
-               }
-
-               boolean isFailed = false;
-               try (ServiceChannel serviceChannel = new ServiceChannel(Channels.newChannel(in), Channels.newChannel(out),
-                               executor)) {
-                       resp.setHeader("Content-Type", "application/json");
-
-                       Callable<Integer> task;
-                       if (ext.equals("api")) {
-                               String uri = Files.readAllLines(baseDir.resolve(flowName)).get(0);
-                               task = new WebServiceTask(serviceChannel, uri);
-                       } else {
-                               task = createTask(serviceChannel, flowName);
-                       }
-
-                       if (task == null)
-                               throw new SlcException("No task found for " + flowName);
-
-                       // execute
-                       Future<Integer> f = executor.submit(task);
-                       int written = f.get();
-
-                       if (written < 0) {// error
-                               isFailed = true;
-                       }
-
-                       if (log.isTraceEnabled())
-                               log.trace("Written " + written + " bytes");
-                       if (persistProcesses)
-                               try {
-                                       Node processNode = realizedFlowNode.getParent();
-                                       processNode.setProperty(SlcNames.SLC_STATUS,
-                                                       isFailed ? ExecutionProcess.ERROR : 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) {
-                       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);
-                       isFailed = true;
-               } finally {
-                       JcrUtils.logoutQuietly(session);
-               }
-
-               if (isFailed) {
-                       resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
-               }
-       }
-
-       protected Callable<Integer> createTask(ServiceChannel serviceChannel, String flowName) {
-               return null;
-       }
-
-       protected Path getBaseDir() {
-               return baseDir;
-       }
-
-       protected HttpContext getHttpContext(String httpAuthrealm) {
-               return null;
-       }
-
-       public static void register(BundleContext bc, String alias, RunnerServlet runnerServlet, String httpAuthrealm) {
-               try {
-                       ServiceTracker<HttpService, HttpService> serviceTracker = new ServiceTracker<HttpService, HttpService>(bc,
-                                       HttpService.class, null) {
-
-                               @Override
-                               public HttpService addingService(ServiceReference<HttpService> reference) {
-                                       // TODO Auto-generated method stub
-                                       HttpService httpService = super.addingService(reference);
-                                       try {
-                                               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);
-                                       }
-                                       return httpService;
-                               }
-
-                       };
-                       // ServiceReference<HttpService> ref =
-                       // bc.getServiceReference(HttpService.class);
-                       // HttpService httpService = bc.getService(ref);
-                       // httpService.registerServlet(alias, runnerServlet, null, null);
-                       // bc.ungetService(ref);
-                       serviceTracker.open();
-               } catch (Exception e) {
-                       throw new SlcException("Cannot register servlet", e);
-               }
-       }
-
-       public static void unregister(BundleContext bc, String alias) {
-               try {
-                       ServiceReference<HttpService> ref = bc.getServiceReference(HttpService.class);
-                       if (ref == null)
-                               return;
-                       HttpService httpService = bc.getService(ref);
-                       httpService.unregister(alias);
-                       bc.ungetService(ref);
-               } catch (Exception e) {
-                       throw new SlcException("Cannot unregister servlet", e);
-               }
-       }
-
-       CmsSession getByLocalId(String localId) {
-               // BundleContext bc =
-               // FrameworkUtil.getBundle(RunnerServlet.class).getBundleContext();
-               Collection<ServiceReference<CmsSession>> sr;
-               try {
-                       sr = bc.getServiceReferences(CmsSession.class, "(" + CmsSession.SESSION_LOCAL_ID + "=" + localId + ")");
-               } catch (InvalidSyntaxException e) {
-                       throw new SlcException("Cannot get CMS session for id " + localId, e);
-               }
-               ServiceReference<CmsSession> cmsSessionRef;
-               if (sr.size() == 1) {
-                       cmsSessionRef = sr.iterator().next();
-                       return (CmsSession) bc.getService(cmsSessionRef);
-               } else if (sr.size() == 0) {
-                       return null;
-               } else
-                       throw new SlcException(sr.size() + " CMS sessions registered for " + localId);
-
-       }
-
-       protected ExecutorService getExecutor() {
-               return executor;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/http/RunnerServletContextHelper.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/http/RunnerServletContextHelper.java
deleted file mode 100644 (file)
index 3af5e73..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-package org.argeo.slc.core.execution.http;
-
-import java.io.IOException;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.argeo.cms.auth.HttpRequestCallbackHandler;
-import org.argeo.node.NodeConstants;
-import org.osgi.service.http.context.ServletContextHelper;
-
-public class RunnerServletContextHelper extends ServletContextHelper {
-       final static String HEADER_WWW_AUTHENTICATE = "WWW-Authenticate";
-       private final String httpAuthRealm = "Runner";
-
-       @Override
-       public boolean handleSecurity(final HttpServletRequest request, HttpServletResponse response) throws IOException {
-               LoginContext lc;
-               try {
-                       lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, new HttpRequestCallbackHandler(request, response));
-                       lc.login();
-               } catch (LoginException e) {
-                       // for CORS
-                       // TODO: make it more robust
-                       if ("OPTIONS".equals(request.getMethod()))
-                               return true;
-                       lc = processUnauthorized(request, response);
-                       if (lc == null)
-                               return false;
-               }
-               Subject.doAs(lc.getSubject(), new PrivilegedAction<Void>() {
-
-                       @Override
-                       public Void run() {
-                               request.setAttribute(REMOTE_USER, AccessController.getContext());
-                               return null;
-                       }
-
-               });
-
-               return true;
-       }
-
-       protected LoginContext processUnauthorized(HttpServletRequest request, HttpServletResponse response) {
-               askForWwwAuth(request, response);
-               return null;
-       }
-
-       protected void askForWwwAuth(HttpServletRequest request, HttpServletResponse response) {
-               response.setStatus(401);
-               response.setHeader(HEADER_WWW_AUTHENTICATE, "Basic realm=\"" + httpAuthRealm + "\"");
-
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/http/ServiceChannel.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/http/ServiceChannel.java
deleted file mode 100644 (file)
index ef8febd..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.argeo.slc.core.execution.http;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.channels.AsynchronousByteChannel;
-import java.nio.channels.CompletionHandler;
-import java.nio.channels.ReadableByteChannel;
-import java.nio.channels.WritableByteChannel;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-
-public class ServiceChannel implements AsynchronousByteChannel {
-       private final ReadableByteChannel in;
-       private final WritableByteChannel out;
-
-       private boolean open = true;
-
-       private ExecutorService executor;
-
-       public ServiceChannel(ReadableByteChannel in, WritableByteChannel out, ExecutorService executor) {
-               this.in = in;
-               this.out = out;
-               this.executor = executor;
-       }
-
-       @Override
-       public Future<Integer> read(ByteBuffer dst) {
-               return executor.submit(() -> in.read(dst));
-       }
-
-       @Override
-       public <A> void read(ByteBuffer dst, A attachment, CompletionHandler<Integer, ? super A> handler) {
-               try {
-                       Future<Integer> res = read(dst);
-                       handler.completed(res.get(), attachment);
-               } catch (Exception e) {
-                       handler.failed(e, attachment);
-               }
-       }
-
-       @Override
-       public Future<Integer> write(ByteBuffer src) {
-               return executor.submit(() -> out.write(src));
-       }
-
-       @Override
-       public <A> void write(ByteBuffer src, A attachment, CompletionHandler<Integer, ? super A> handler) {
-               try {
-                       Future<Integer> res = write(src);
-                       handler.completed(res.get(), attachment);
-               } catch (Exception e) {
-                       handler.failed(e, attachment);
-               }
-       }
-
-       @Override
-       public synchronized void close() throws IOException {
-               try {
-                       in.close();
-               } catch (Exception e) {
-                       e.printStackTrace();
-               }
-               try {
-                       out.close();
-               } catch (Exception e) {
-                       e.printStackTrace();
-               }
-               open = false;
-               notifyAll();
-       }
-
-       @Override
-       public synchronized boolean isOpen() {
-               return open;
-       }
-
-}
diff --git a/org.argeo.slc.core/src/org/argeo/slc/core/execution/http/WebServiceTask.java b/org.argeo.slc.core/src/org/argeo/slc/core/execution/http/WebServiceTask.java
deleted file mode 100644 (file)
index b942232..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-package org.argeo.slc.core.execution.http;
-
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.nio.channels.AsynchronousByteChannel;
-import java.nio.channels.Channels;
-import java.nio.channels.ReadableByteChannel;
-import java.util.concurrent.Callable;
-import java.util.concurrent.Future;
-
-import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
-import org.apache.commons.httpclient.methods.PostMethod;
-import org.apache.commons.httpclient.methods.RequestEntity;
-
-public class WebServiceTask implements Callable<Integer> {
-       private String url;
-       private String requContentType;
-       private String respContentType;
-
-       private AsynchronousByteChannel channel;
-
-       public WebServiceTask(AsynchronousByteChannel channel, String url) {
-               this(url, "application/json", "application/json", channel);
-       }
-
-       public WebServiceTask(String url, String requContentType, String respContentType, AsynchronousByteChannel channel) {
-               this.url = url;
-               this.requContentType = requContentType;
-               this.respContentType = respContentType;
-               this.channel = channel;
-       }
-
-       @Override
-       public Integer call() throws Exception {
-               // Webservice
-               HttpClient httpClient = new HttpClient();
-               PostMethod postMethod = new PostMethod(url);
-               InputStream in = Channels.newInputStream(channel);
-               RequestEntity requestEntity = new InputStreamRequestEntity(in, requContentType);
-               // StringRequestEntity requestEntity = new
-               // StringRequestEntity(payloadStr, "application/json", "UTF-8");
-               postMethod.setRequestEntity(requestEntity);
-               httpClient.executeMethod(postMethod);
-               InputStream answerIn = postMethod.getResponseBodyAsStream();
-               ReadableByteChannel answer = Channels.newChannel(answerIn);
-               ByteBuffer buffer = ByteBuffer.allocate(8 * 1024);
-               int read = 0;
-               Integer writeRes = 0;
-               while (read != -1) {
-                       read = answer.read(buffer);
-                       if (read <= 0)
-                               break;
-                       buffer.flip();
-                       Future<Integer> f = channel.write(buffer);
-                       writeRes = writeRes + f.get();
-                       buffer.clear();
-               }
-               return writeRes;
-       }
-
-       public String getUrl() {
-               return url;
-       }
-
-       public String getRequContentType() {
-               return requContentType;
-       }
-
-       public String getRespContentType() {
-               return respContentType;
-       }
-
-}