2 * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org
.argeo
.slc
.web
.mvc
.controllers
;
19 import java
.io
.BufferedReader
;
20 import java
.text
.SimpleDateFormat
;
21 import java
.util
.Comparator
;
22 import java
.util
.List
;
23 import java
.util
.SortedSet
;
24 import java
.util
.TreeSet
;
25 import java
.util
.UUID
;
27 import javax
.servlet
.http
.HttpServletRequest
;
28 import javax
.servlet
.http
.HttpServletResponse
;
30 import org
.apache
.commons
.logging
.Log
;
31 import org
.apache
.commons
.logging
.LogFactory
;
32 import org
.argeo
.slc
.SlcException
;
33 import org
.argeo
.slc
.core
.attachment
.AttachmentsStorage
;
34 import org
.argeo
.slc
.dao
.process
.SlcExecutionDao
;
35 import org
.argeo
.slc
.execution
.ExecutionModuleDescriptor
;
36 import org
.argeo
.slc
.msg
.ExecutionAnswer
;
37 import org
.argeo
.slc
.msg
.MsgConstants
;
38 import org
.argeo
.slc
.msg
.ObjectList
;
39 import org
.argeo
.slc
.process
.SlcExecution
;
40 import org
.argeo
.slc
.process
.SlcExecutionStep
;
41 import org
.argeo
.slc
.runtime
.SlcAgent
;
42 import org
.argeo
.slc
.runtime
.SlcAgentFactory
;
43 import org
.argeo
.slc
.services
.SlcExecutionService
;
44 import org
.springframework
.oxm
.Marshaller
;
45 import org
.springframework
.oxm
.Unmarshaller
;
46 import org
.springframework
.stereotype
.Controller
;
47 import org
.springframework
.ui
.Model
;
48 import org
.springframework
.util
.Assert
;
49 import org
.springframework
.web
.bind
.annotation
.RequestMapping
;
50 import org
.springframework
.web
.bind
.annotation
.RequestParam
;
51 import org
.springframework
.xml
.transform
.StringSource
;
54 public class ProcessController
{
56 public final static String KEY_ANSWER
= "__answer";
57 private final static Log log
= LogFactory
.getLog(ProcessController
.class);
59 private SlcExecutionDao slcExecutionDao
;
60 private SlcAgentFactory agentFactory
;
61 private Unmarshaller unmarshaller
;
62 private Marshaller marshaller
;
63 private SlcExecutionService slcExecutionService
;
64 private AttachmentsStorage attachmentsStorage
;
66 private SlcExecutionManager slcExecutionManager
;
68 @RequestMapping("/listSlcExecutions.service")
69 protected ObjectList
listSlcExecutions() {
70 List
<SlcExecution
> list
= slcExecutionDao
.listSlcExecutions();
71 return new ObjectList(list
);
74 @RequestMapping("/getExecutionDescriptor.service")
75 protected ExecutionModuleDescriptor
getExecutionDescriptor(
76 @RequestParam String agentId
, @RequestParam String moduleName
,
77 @RequestParam String version
) {
79 SlcAgent slcAgent
= agentFactory
.getAgent(agentId
);
81 ExecutionModuleDescriptor md
= slcAgent
.getExecutionModuleDescriptor(
86 @RequestMapping("/listModulesDescriptors.service")
87 protected ObjectList
listModulesDescriptors(@RequestParam String agentId
) {
88 // TODO: use centralized agentId property (from MsgConstants)?
89 SlcAgent slcAgent
= agentFactory
.getAgent(agentId
);
91 List
<ExecutionModuleDescriptor
> descriptors
= slcAgent
92 .listExecutionModuleDescriptors();
93 SortedSet
<ExecutionModuleDescriptor
> set
= new TreeSet
<ExecutionModuleDescriptor
>(
94 new Comparator
<ExecutionModuleDescriptor
>() {
96 public int compare(ExecutionModuleDescriptor md1
,
97 ExecutionModuleDescriptor md2
) {
98 String str1
= md1
.getLabel() != null ? md1
.getLabel()
100 String str2
= md2
.getLabel() != null ? md2
.getLabel()
102 return str1
.compareTo(str2
);
105 set
.addAll(descriptors
);
106 return new ObjectList(set
);
109 @RequestMapping("/getSlcExecution.service")
110 protected SlcExecution
getSlcExecution(@RequestParam String uuid
) {
111 SlcExecution slcExecution
= slcExecutionDao
.getSlcExecution(uuid
);
113 slcExecutionManager
.retrieveRealizedFlows(slcExecution
);
117 @RequestMapping("/newSlcExecution.service")
118 protected ExecutionAnswer
newSlcExecution(HttpServletRequest request
,
119 Model model
) throws Exception
{
121 String agentId
= request
122 .getParameter(MsgConstants
.PROPERTY_SLC_AGENT_ID
);
123 Assert
.notNull(agentId
, "agent id");
125 String answer
= request
.getParameter("body");
126 if (answer
== null) {
127 // lets read the message body instead
128 BufferedReader reader
= request
.getReader();
129 StringBuffer buffer
= new StringBuffer();
131 while (((line
= reader
.readLine()) != null)) {
134 answer
= buffer
.toString();
137 if (log
.isTraceEnabled())
138 log
.debug("Received message:\n" + answer
);
140 StringSource source
= new StringSource(answer
);
141 SlcExecution slcExecution
= (SlcExecution
) unmarshaller
144 // Workaround for https://www.argeo.org/bugzilla/show_bug.cgi?id=86
145 if (slcExecution
.getUuid() == null
146 || slcExecution
.getUuid().length() < 8)
147 slcExecution
.setUuid(UUID
.randomUUID().toString());
149 slcExecution
.setStatus(SlcExecution
.STATUS_SCHEDULED
);
150 slcExecution
.getSteps().add(
151 new SlcExecutionStep(SlcExecutionStep
.START
,
152 "Process started from the Web UI"));
155 slcExecutionManager
.storeRealizedFlows(slcExecution
);
156 slcExecutionService
.newExecution(slcExecution
);
157 SlcAgent agent
= agentFactory
.getAgent(agentId
);
158 agent
.runSlcExecution(slcExecution
);
160 return ExecutionAnswer
.ok("Execution completed properly");
163 @RequestMapping("/tailSlcExecutionStepsCount.service")
164 protected ObjectList
tailSlcExecutionSteps(@RequestParam String uuid
,
165 @RequestParam Integer stepCount
) {
166 List
<SlcExecutionStep
> list
= slcExecutionDao
167 .tailSteps(uuid
, stepCount
);
168 return new ObjectList(list
);
171 @RequestMapping("/tailSlcExecutionStepsOffset.service")
172 protected ObjectList
tailSlcExecutionSteps(@RequestParam String uuid
,
173 @RequestParam String stepOffsetUuid
) {
174 List
<SlcExecutionStep
> list
= slcExecutionDao
.tailSteps(uuid
,
176 return new ObjectList(list
);
179 @RequestMapping("/downloadSlcExecution.service")
180 protected void downloadSlcExecution(@RequestParam String uuid
,
181 @RequestParam String ext
, HttpServletResponse response
)
184 // cf. http://en.wikipedia.org/wikServicei/Internet_media_type
185 if ("csv".equals(ext
))
186 contentType
= "text/csv";
187 else if ("pdf".equals(ext
))
188 contentType
= "application/pdf";
189 else if ("zip".equals(ext
))
190 contentType
= "application/zip";
191 else if ("html".equals(ext
))
192 contentType
= "application/html";
193 else if ("txt".equals(ext
) || "log".equals(ext
))
194 contentType
= "text/plain";
195 else if ("doc".equals(ext
) || "docx".equals(ext
))
196 contentType
= "application/msword";
197 else if ("xls".equals(ext
) || "xlsx".equals(ext
))
198 contentType
= "application/vnd.ms-excel";
199 else if ("xml".equals(ext
))
200 contentType
= "text/xml";
202 contentType
= "Content-Type: application/force-download";
204 String name
= "Process-" + uuid
+ "." + ext
;
206 SlcExecution process
= slcExecutionDao
.getSlcExecution(uuid
);
208 SimpleDateFormat df
= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
210 // TODO: put it in a separate view
211 if ("log".equals(ext
)) {
212 StringBuffer buf
= new StringBuffer("");
213 buf
.append("#\n# PROCESS " + process
.getUuid() + "\n#\n\n");
215 .append("Started at " + df
.format(process
.getStartDate())
217 buf
.append("Ended at " + df
.format(process
.getEndDate()) + "\n");
218 buf
.append("On host " + process
.getHost() + "\n");
219 buf
.append("\n# LOG\n\n");
220 for (SlcExecutionStep step
: process
.getSteps()) {
221 buf
.append(df
.format(step
.getTimestamp()));
223 for (int i
= 0; i
< step
.getLogLines().size(); i
++) {
226 buf
.append(step
.getLogLines().get(i
));
229 buf
.append(step
.getType());
231 buf
.append('[').append(step
.getThread()).append(']');
234 prepareDownloadResponse(name
, contentType
, response
);
235 response
.getWriter().print(buf
);
237 throw new SlcException("Unsupported content type " + contentType
);
241 protected void prepareDownloadResponse(String name
, String contentType
,
242 HttpServletResponse response
) {
243 response
.setHeader("Content-Disposition", "attachment; filename=\""
245 response
.setContentType(contentType
+ ";name=\"" + name
+ "\"");
246 response
.setHeader("Expires", "0");
247 response
.setHeader("Cache-Control", "no-cache, must-revalidate");
248 response
.setHeader("Pragma", "no-cache");
251 private void initializeSEM() {
252 slcExecutionManager
= new SlcExecutionManager(unmarshaller
, marshaller
,
256 public void setSlcExecutionDao(SlcExecutionDao slcExecutionDao
) {
257 this.slcExecutionDao
= slcExecutionDao
;
260 public void setSlcExecutionService(SlcExecutionService slcExecutionService
) {
261 this.slcExecutionService
= slcExecutionService
;
264 public void setUnmarshaller(Unmarshaller unmarshaller
) {
265 this.unmarshaller
= unmarshaller
;
268 public void setMarshaller(Marshaller marshaller
) {
269 this.marshaller
= marshaller
;
272 public void setAttachmentsStorage(AttachmentsStorage attachmentsStorage
) {
273 this.attachmentsStorage
= attachmentsStorage
;
276 public void setAgentFactory(SlcAgentFactory agentFactory
) {
277 this.agentFactory
= agentFactory
;