X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=runtime%2Forg.argeo.slc.detached%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fslc%2Fdetached%2FDetachedExecutionServerImpl.java;h=0cfd3113e6edfa21ab71090b1f9cae983b594d4e;hb=d34a6b8b9904f130f7928cea61f7e500094a58b1;hp=35b9d63d537ffb6d5ce15e792b04907a9588fa78;hpb=8279efc2b92ba454b24ad4d06e7878b00836c07d;p=gpl%2Fargeo-slc.git diff --git a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedExecutionServerImpl.java b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedExecutionServerImpl.java index 35b9d63d5..0cfd3113e 100644 --- a/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedExecutionServerImpl.java +++ b/runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedExecutionServerImpl.java @@ -1,8 +1,11 @@ package org.argeo.slc.detached; +import java.io.PrintWriter; +import java.io.StringWriter; import java.util.List; import java.util.Vector; +import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.slc.detached.admin.CloseSession; @@ -12,6 +15,7 @@ import org.osgi.framework.ServiceReference; import org.springframework.context.ApplicationContext; import org.springframework.osgi.context.BundleContextAware; +/** Default implementation of a detached server. */ public class DetachedExecutionServerImpl implements DetachedExecutionServer, BundleContextAware { private final static Log log = LogFactory @@ -31,6 +35,8 @@ public class DetachedExecutionServerImpl implements DetachedExecutionServer, } public synchronized DetachedAnswer executeRequest(DetachedRequest request) { + log.info("Received request " + request); + DetachedAnswer answer = null; try { // Find action @@ -73,18 +79,38 @@ public class DetachedExecutionServerImpl implements DetachedExecutionServer, } catch (Exception e) { answer = new DetachedAnswer(request); answer.setStatus(DetachedAnswer.ERROR); - answer.setLog(e.getMessage()); + StringWriter writer = new StringWriter(); + e.printStackTrace(new PrintWriter(writer)); + answer.setLog(writer.toString()); + IOUtils.closeQuietly(writer); + } + + // Case where current session is unexpectly null + if (getCurrentSession() == null) { + log + .error("CURRENT SESSION IS NULL." + + " Detached status is inconsistent dumping sessions history:"); + log.error(dumpSessionsHistory(request, answer)); + if (answer != null) { + answer.setStatus(DetachedAnswer.ERROR); + answer + .addToLog("CURRENT SESSION IS NULL." + + " Detached status is inconsistent, see detached log for more details."); + return answer; + } else { + throw new DetachedException( + "Answer is null. Cannot return it. See log for more details."); + } + } + getCurrentSession().getRequests().add(request); getCurrentSession().getAnswers().add(answer); - if (log.isDebugEnabled()) - log.debug("Processed '" + request.getRef() + "' (status=" - + answer.getStatusAsString() + ", path=" - + request.getPath() + ")"); + log.info("Sent answer " + answer); return answer; } - protected DetachedAnswer processStep(DetachedStep obj, + protected synchronized DetachedAnswer processStep(DetachedStep obj, DetachedRequest request) { DetachedAnswer answer; if (getCurrentSession() == null) @@ -135,6 +161,7 @@ public class DetachedExecutionServerImpl implements DetachedExecutionServer, if (execute) { DetachedStep step = (DetachedStep) obj; + // Actually execute the step answer = step.execute(detachedContext, request); } else { answer = new DetachedAnswer(request); @@ -144,14 +171,23 @@ public class DetachedExecutionServerImpl implements DetachedExecutionServer, return answer; } - protected DetachedAnswer processAdminCommand(DetachedAdminCommand obj, - DetachedRequest request) { + protected synchronized DetachedAnswer processAdminCommand( + DetachedAdminCommand obj, DetachedRequest request) { DetachedAnswer answer; if (obj instanceof OpenSession) { - if (getCurrentSession() != null) - throw new DetachedException( - "There is already an open session #" - + getCurrentSession().getUuid()); + if (getCurrentSession() != null) { + // TODO: better understand why there is sometimes two open + // sessions sent. + log.warn("There is already an open session #" + + getCurrentSession().getUuid() + ". Closing it..."); + DetachedAnswer answerT = new DetachedAnswer( + request, + "Session #" + + getCurrentSession().getUuid() + + " forcibly closed. THIS ANSWER WAS NOT SENT BACK."); + answerT.setStatus(DetachedAnswer.CLOSED_SESSION); + getCurrentSession().getAnswers().add(answerT); + } sessions.add(((OpenSession) obj).execute(request, bundleContext)); answer = new DetachedAnswer(request, "Session #" + getCurrentSession().getUuid() + " open."); @@ -167,7 +203,13 @@ public class DetachedExecutionServerImpl implements DetachedExecutionServer, return answer; } - protected final DetachedSession getCurrentSession() { + /** + * Returns the current session based on the list of previous sessions. + * + * @return the current session or null if there is no session yet defined or + * if the last registered session is null or in error. + */ + protected synchronized final DetachedSession getCurrentSession() { if (sessions.size() == 0) { return null; } else { @@ -185,7 +227,41 @@ public class DetachedExecutionServerImpl implements DetachedExecutionServer, } } - protected final DetachedSession getPreviousSession() { + protected synchronized String dumpSessionsHistory( + DetachedRequest requestCurrent, DetachedAnswer answerCurrent) { + StringBuffer buf = new StringBuffer("## SESSIONS HISTORY DUMP\n"); + buf.append("# CURRENT\n"); + buf.append("Current session: ").append(getCurrentSession()) + .append('\n'); + buf.append("Current request: ").append(requestCurrent).append('\n'); + buf.append("Current answer: ").append(answerCurrent).append('\n'); + buf.append("Skip count: ").append(skipCount).append('\n'); + + buf.append("# SESSIONS\n"); + for (int i = 0; i < sessions.size(); i++) { + DetachedSession session = (DetachedSession) sessions.get(i); + buf.append(i).append(". ").append(session).append('\n'); + List requests = session.getRequests(); + List answers = session.getAnswers(); + for (int j = 0; j < requests.size(); j++) { + DetachedRequest request = (DetachedRequest) requests.get(j); + buf.append('\t').append(j).append(". ").append(request).append( + '\n'); + if (answers.size() > j) { + DetachedAnswer answer = (DetachedAnswer) answers.get(j); + buf.append('\t').append(j).append(". ").append(answer) + .append('\n'); + } + } + } + + buf.append("# DETACHED CONTEXT\n"); + buf.append(detachedContext).append('\n'); + + return buf.toString(); + } + + protected synchronized final DetachedSession getPreviousSession() { if (sessions.size() < 2) return null; else