]> git.argeo.org Git - gpl/argeo-slc.git/blob - org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/DetachedExecutionServerImpl.java
Ignore target
[gpl/argeo-slc.git] / org.argeo.slc.detached / src / main / java / org / argeo / slc / detached / DetachedExecutionServerImpl.java
1 package org.argeo.slc.detached;
2
3 import java.util.List;
4 import java.util.Vector;
5
6 import org.apache.commons.logging.Log;
7 import org.apache.commons.logging.LogFactory;
8 import org.argeo.slc.detached.admin.CloseSession;
9 import org.argeo.slc.detached.admin.OpenSession;
10 import org.osgi.framework.BundleContext;
11 import org.osgi.framework.ServiceReference;
12
13 public class DetachedExecutionServerImpl implements DetachedExecutionServer {
14 private final static Log log = LogFactory
15 .getLog(DetachedExecutionServerImpl.class);
16
17 private final DetachedContextImpl detachedContext;
18 private final List sessions;
19
20 private int skipCount = 1;// start skipCount at 1 since the first step is
21 // always an open session
22
23 private BundleContext bundleContext;
24
25 public DetachedExecutionServerImpl() {
26 detachedContext = new DetachedContextImpl();
27 sessions = new Vector();
28 }
29
30 public synchronized DetachedAnswer executeRequest(DetachedRequest request) {
31 DetachedAnswer answer = null;
32 try {
33 // Find action
34 ServiceReference[] refs = bundleContext.getAllServiceReferences(
35 StaticRefProvider.class.getName(), null);
36 Object obj = null;
37 for (int i = 0; i < refs.length; i++) {
38 StaticRefProvider provider = (StaticRefProvider) bundleContext
39 .getService(refs[i]);
40 obj = provider.getStaticRef(request.getRef());
41 if (obj != null) {
42 break;
43 }
44 }
45
46 if (obj == null)
47 throw new DetachedException("Could not find action with ref "
48 + request.getRef());
49
50 // Execute actions
51 if (obj instanceof DetachedStep) {
52 answer = processStep((DetachedStep) obj, request);
53
54 } else if (obj instanceof DetachedAdminCommand) {
55 answer = processAdminCommand((DetachedAdminCommand) obj,
56 request);
57 }
58
59 if (answer == null) {
60 throw new DetachedException("Unknown action type "
61 + obj.getClass() + " for action with ref "
62 + request.getRef());
63 }
64 } catch (Exception e) {
65 answer = new DetachedAnswer(request);
66 answer.setStatus(DetachedAnswer.ERROR);
67 answer.setLog(e.getMessage());
68 }
69 getCurrentSession().getRequests().add(request);
70 getCurrentSession().getAnswers().add(answer);
71 if (log.isDebugEnabled())
72 log.debug("Processed '" + request.getRef() + "' (status="
73 + answer.getStatusAsString() + ", path="
74 + request.getPath() + ")");
75 return answer;
76 }
77
78 protected DetachedAnswer processStep(DetachedStep obj,
79 DetachedRequest request) {
80 DetachedAnswer answer;
81 if (getCurrentSession() == null)
82 throw new DetachedException("No open session.");
83
84 StringBuffer skippedLog = new StringBuffer();
85 boolean execute = true;
86 if (getPreviousSession() != null && !getPreviousSession().isClosed()) {
87 if (getCurrentSession().getDoItAgainPolicy().equals(
88 DetachedSession.SKIP_UNTIL_ERROR)) {
89 // Skip execution of already successful steps
90 if (getPreviousSession().getAnswers().size() > skipCount) {
91 DetachedAnswer previousAnswer = (DetachedAnswer) getPreviousSession()
92 .getAnswers().get(skipCount);
93 DetachedRequest previousRequest = (DetachedRequest) getPreviousSession()
94 .getRequests().get(skipCount);
95 // Check paths
96 if (!previousRequest.getPath().equals(request.getPath())) {
97 String msg = "New request is not consistent with previous path. previousPath="
98 + previousRequest.getPath()
99 + ", newPath="
100 + request.getPath() + "\n";
101 skippedLog.append(msg);
102 log.warn(msg);
103 }
104
105 if (previousAnswer.getStatus() != DetachedAnswer.ERROR) {
106 execute = false;
107 String msg = "Skipped path " + request.getPath()
108 + " (skipCount=" + skipCount + ")";
109 skippedLog.append(msg);
110 log.info(msg);
111 skipCount++;
112 } else {
113 log
114 .info("Path "
115 + request.getPath()
116 + " was previously in error, executing it again."
117 + " (skipCount=" + skipCount + "). Reset skip count to 1");
118 skipCount = 1;
119 }
120 } else {
121 // went further as skip count, doing nothing.
122 }
123 }
124 }
125
126 if (execute) {
127 DetachedStep step = (DetachedStep) obj;
128 answer = step.execute(detachedContext, request);
129 } else {
130 answer = new DetachedAnswer(request);
131 answer.setStatus(DetachedAnswer.SKIPPED);
132 answer.setLog(skippedLog.toString());
133 }
134 return answer;
135 }
136
137 protected DetachedAnswer processAdminCommand(DetachedAdminCommand obj,
138 DetachedRequest request) {
139 DetachedAnswer answer;
140 if (obj instanceof OpenSession) {
141 if (getCurrentSession() != null)
142 throw new DetachedException(
143 "There is already an open session #"
144 + getCurrentSession().getUuid());
145 sessions.add(((OpenSession) obj).execute(request, bundleContext));
146 answer = new DetachedAnswer(request, "Session #"
147 + getCurrentSession().getUuid() + " open.");
148 } else if (obj instanceof CloseSession) {
149 if (getCurrentSession() == null)
150 throw new DetachedException("There is no open session to close");
151 answer = new DetachedAnswer(request, "Session #"
152 + getCurrentSession().getUuid() + " closed.");
153 answer.setStatus(DetachedAnswer.CLOSED_SESSION);
154 } else {
155 answer = null;
156 }
157 return answer;
158 }
159
160 protected final DetachedSession getCurrentSession() {
161 if (sessions.size() == 0) {
162 return null;
163 } else {
164 DetachedSession session = (DetachedSession) sessions.get(sessions
165 .size() - 1);
166 List answers = session.getAnswers();
167 if (answers.size() > 0) {
168 DetachedAnswer lastAnswer = (DetachedAnswer) answers
169 .get(answers.size() - 1);
170 if (lastAnswer.getStatus() == DetachedAnswer.ERROR
171 || lastAnswer.getStatus() == DetachedAnswer.CLOSED_SESSION)
172 return null;
173 }
174 return session;
175 }
176 }
177
178 protected final DetachedSession getPreviousSession() {
179 if (sessions.size() < 2)
180 return null;
181 else
182 return (DetachedSession) sessions.get(sessions.size() - 2);
183 }
184
185 public void init(BundleContext bundleContext) {
186 this.bundleContext = bundleContext;
187 }
188
189 }