]> git.argeo.org Git - gpl/argeo-slc.git/blobdiff - runtime/org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedExecutionServerImpl.java
Allow to refresh a comma separated list of bundles
[gpl/argeo-slc.git] / runtime / org.argeo.slc.detached / src / main / java / org / argeo / slc / detached / DetachedExecutionServerImpl.java
index 35b9d63d537ffb6d5ce15e792b04907a9588fa78..0cfd3113e6edfa21ab71090b1f9cae983b594d4e 100644 (file)
@@ -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