1
2
3
4
5
6
7
8
9
10
11 package psiprobe.controllers.deploy;
12
13 import jakarta.servlet.http.HttpServletRequest;
14 import jakarta.servlet.http.HttpServletResponse;
15
16 import java.io.File;
17 import java.io.IOException;
18 import java.nio.charset.StandardCharsets;
19 import java.nio.file.Files;
20 import java.util.List;
21
22 import org.apache.catalina.Context;
23 import org.apache.commons.io.FileUtils;
24 import org.apache.commons.io.FilenameUtils;
25 import org.apache.tomcat.util.http.fileupload.FileItem;
26 import org.apache.tomcat.util.http.fileupload.FileItemFactory;
27 import org.apache.tomcat.util.http.fileupload.FileUpload;
28 import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
29 import org.apache.tomcat.util.http.fileupload.servlet.ServletRequestContext;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32 import org.springframework.beans.factory.annotation.Value;
33 import org.springframework.security.core.Authentication;
34 import org.springframework.security.core.context.SecurityContextHolder;
35 import org.springframework.stereotype.Controller;
36 import org.springframework.web.bind.annotation.RequestMapping;
37 import org.springframework.web.servlet.ModelAndView;
38 import org.springframework.web.servlet.view.InternalResourceView;
39
40 import psiprobe.controllers.AbstractTomcatContainerController;
41 import psiprobe.controllers.jsp.DisplayJspController;
42 import psiprobe.model.jsp.Summary;
43
44
45
46
47 @Controller
48 public class UploadWarController extends AbstractTomcatContainerController {
49
50
51 private static final Logger logger = LoggerFactory.getLogger(UploadWarController.class);
52 private static final int MAXSECONDS_WAITFOR_CONTEXT = 10;
53
54 @RequestMapping(path = "/adm/war.htm")
55 @Override
56 public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
57 throws Exception {
58 return super.handleRequest(request, response);
59 }
60
61 @Override
62 protected ModelAndView handleRequestInternal(HttpServletRequest request,
63 HttpServletResponse response) throws Exception {
64
65
66 if (!this.isMultipartContent(request)) {
67 return new ModelAndView(new InternalResourceView(getViewName()));
68 }
69
70 File tmpWar = null;
71 String contextName = null;
72 boolean update = false;
73 boolean compile = false;
74 boolean discard = false;
75
76
77 FileItemFactory factory =
78 new DiskFileItemFactory(1048000, new File(System.getProperty("java.io.tmpdir")));
79 FileUpload upload = new FileUpload();
80 upload.setFileItemFactory(factory);
81 upload.setSizeMax(-1);
82 upload.setHeaderEncoding(StandardCharsets.UTF_8.name());
83 try {
84 List<FileItem> fileItems = upload.parseRequest(new ServletRequestContext(request));
85 for (FileItem fi : fileItems) {
86 if (!fi.isFormField()) {
87 if (fi.getName() != null && fi.getName().length() > 0) {
88 tmpWar =
89 new File(System.getProperty("java.io.tmpdir"), FilenameUtils.getName(fi.getName()));
90 fi.write(tmpWar);
91 }
92 } else if ("context".equals(fi.getFieldName())) {
93 contextName = fi.getString();
94 } else if ("update".equals(fi.getFieldName()) && "yes".equals(fi.getString())) {
95 update = true;
96 } else if ("compile".equals(fi.getFieldName()) && "yes".equals(fi.getString())) {
97 compile = true;
98 } else if ("discard".equals(fi.getFieldName()) && "yes".equals(fi.getString())) {
99 discard = true;
100 }
101 }
102 } catch (Exception e) {
103 logger.error("Could not process file upload", e);
104 request.setAttribute("errorMessage", getMessageSourceAccessor()
105 .getMessage("probe.src.deploy.war.uploadfailure", new Object[] {e.getMessage()}));
106 if (tmpWar != null) {
107 Files.delete(tmpWar.toPath());
108 tmpWar = null;
109 }
110 }
111
112 String errMsg = null;
113
114 if (tmpWar == null) {
115 return new ModelAndView(new InternalResourceView(getViewName()));
116 }
117
118 try {
119 if (tmpWar.getName().endsWith(".war")) {
120
121 if (contextName == null || contextName.length() == 0) {
122 String warFileName = tmpWar.getName().replaceAll("\\.war$", "");
123 contextName = "/" + warFileName;
124 }
125
126 contextName = getContainerWrapper().getTomcatContainer().formatContextName(contextName);
127
128
129
130
131
132 String visibleContextName = contextName.isEmpty() ? "/" : contextName;
133 request.setAttribute("contextName", visibleContextName);
134
135 if (update && getContainerWrapper().getTomcatContainer().findContext(contextName) != null) {
136 logger.debug("updating {}: removing the old copy", contextName);
137 getContainerWrapper().getTomcatContainer().remove(contextName);
138 }
139
140 if (getContainerWrapper().getTomcatContainer().findContext(contextName) == null) {
141
142 String destWarFilename =
143 getContainerWrapper().getTomcatContainer().formatContextFilename(contextName);
144 File destWar = new File(getContainerWrapper().getTomcatContainer().getAppBase(),
145 destWarFilename + ".war");
146
147 FileUtils.moveFile(tmpWar, destWar);
148
149
150 getContainerWrapper().getTomcatContainer().installWar(contextName);
151
152 File destContext =
153 new File(getContainerWrapper().getTomcatContainer().getAppBase(), destWarFilename);
154
155 FileUtils.waitFor(destContext, MAXSECONDS_WAITFOR_CONTEXT);
156
157 Context ctx = getContainerWrapper().getTomcatContainer().findContext(contextName);
158 if (ctx == null) {
159 errMsg = getMessageSourceAccessor().getMessage("probe.src.deploy.war.notinstalled",
160 new Object[] {visibleContextName});
161 } else {
162 request.setAttribute("success", Boolean.TRUE);
163
164 Authentication auth = SecurityContextHolder.getContext().getAuthentication();
165
166 String name = auth.getName();
167 logger.info(getMessageSourceAccessor().getMessage("probe.src.log.deploywar"), name,
168 contextName);
169 if (discard) {
170 getContainerWrapper().getTomcatContainer().discardWorkDir(ctx);
171 logger.info(getMessageSourceAccessor().getMessage("probe.src.log.discardwork"), name,
172 contextName);
173 }
174 if (compile) {
175 Summary summary = new Summary();
176 summary.setName(ctx.getName());
177 getContainerWrapper().getTomcatContainer().listContextJsps(ctx, summary, true);
178 request.getSession(false).setAttribute(DisplayJspController.SUMMARY_ATTRIBUTE,
179 summary);
180 request.setAttribute("compileSuccess", Boolean.TRUE);
181 }
182 }
183 } else {
184 errMsg = getMessageSourceAccessor().getMessage("probe.src.deploy.war.alreadyExists",
185 new Object[] {visibleContextName});
186 }
187 } else {
188 errMsg = getMessageSourceAccessor().getMessage("probe.src.deploy.war.notWar.failure");
189 }
190 } catch (IOException e) {
191 errMsg = getMessageSourceAccessor().getMessage("probe.src.deploy.war.failure",
192 new Object[] {e.getMessage()});
193 logger.error("Tomcat threw an exception when trying to deploy", e);
194 } finally {
195 if (errMsg != null) {
196 request.setAttribute("errorMessage", errMsg);
197 }
198
199 if (tmpWar.exists()) {
200 Files.delete(tmpWar.toPath());
201 }
202 }
203 return new ModelAndView(new InternalResourceView(getViewName()));
204 }
205
206 @Value("/adm/deploy.htm")
207 @Override
208 public void setViewName(String viewName) {
209 super.setViewName(viewName);
210 }
211
212 }