001 package org.kuali.common.deploy.appserver.spring;
002
003 import java.io.File;
004 import java.util.ArrayList;
005 import java.util.List;
006
007 import org.kuali.common.deploy.DeployContext;
008 import org.kuali.common.deploy.Deployable;
009 import org.kuali.common.deploy.appserver.ApplicationServer;
010 import org.kuali.common.deploy.appserver.TomcatApplicationServer;
011 import org.kuali.common.deploy.channel.spring.DefaultSecureChannelConfig;
012 import org.kuali.common.deploy.spring.DefaultDeployContextConfig;
013 import org.kuali.common.http.model.HttpContext;
014 import org.kuali.common.http.service.HttpService;
015 import org.kuali.common.http.service.HttpWaitExecutable;
016 import org.kuali.common.http.spring.DefaultHttpServiceConfig;
017 import org.kuali.common.http.spring.HttpServiceConfig;
018 import org.kuali.common.util.file.CanonicalFile;
019 import org.kuali.common.util.maven.LocalRepositoryService;
020 import org.kuali.common.util.maven.RepositoryUtils;
021 import org.kuali.common.util.maven.model.Artifact;
022 import org.kuali.common.util.maven.spring.MavenServiceConfig;
023 import org.kuali.common.util.secure.channel.SecureChannel;
024 import org.kuali.common.util.spring.PropertySourceUtils;
025 import org.kuali.common.util.spring.env.EnvironmentService;
026 import org.kuali.common.util.spring.service.SpringServiceConfig;
027 import org.springframework.beans.factory.annotation.Autowired;
028 import org.springframework.context.annotation.Bean;
029 import org.springframework.context.annotation.Configuration;
030 import org.springframework.context.annotation.Import;
031 import org.springframework.core.env.ConfigurableEnvironment;
032
033 import com.google.common.base.Optional;
034
035 @Configuration
036 @Import({ SpringServiceConfig.class, DefaultDeployContextConfig.class, MavenServiceConfig.class, DefaultSecureChannelConfig.class, DefaultHttpServiceConfig.class })
037 public class TomcatConfig implements ApplicationServerConfig {
038
039 @Autowired
040 EnvironmentService env;
041
042 @Autowired
043 ConfigurableEnvironment configurableEnvironment;
044
045 @Autowired
046 SecureChannel channel;
047
048 @Autowired
049 LocalRepositoryService localRepositoryService;
050
051 @Autowired
052 DeployContext context;
053
054 @Autowired
055 HttpServiceConfig httpServiceConfig;
056
057 @Override
058 @Bean
059 public ApplicationServer applicationServer() {
060 return getApplicationServer();
061 }
062
063 protected Deployable getSetEnv() {
064 String permissions = env.getString("tomcat.setenv.perms", "755");
065 String local = env.getString("tomcat.setenv.local");
066 String remote = env.getString("tomcat.setenv");
067 return new Deployable.Builder(local, remote).permissions(permissions).filter(true).build();
068 }
069
070 protected List<Deployable> getJsps() {
071 String envLocal = env.getString("tomcat.jsp.env.local");
072 String envRemote = env.getString("tomcat.jsp.env");
073 Deployable envJsp = new Deployable.Builder(envLocal, envRemote).build();
074
075 String tailLocal = env.getString("tomcat.jsp.tail.local");
076 String tailRemote = env.getString("tomcat.jsp.tail");
077 Deployable tailJsp = new Deployable.Builder(tailLocal, tailRemote).build();
078
079 List<Deployable> jsps = new ArrayList<Deployable>();
080 jsps.add(envJsp);
081 jsps.add(tailJsp);
082 return jsps;
083 }
084
085 protected List<String> getTomcatDeletes() {
086 // /usr/local/tomcat/lib
087 String lib = env.getString("tomcat.lib");
088
089 // rm -rf gets invoked on all of these
090 List<String> pathsToDelete = new ArrayList<String>();
091 pathsToDelete.add(lib + "/mysql*.jar");
092 pathsToDelete.add(lib + "/ojdbc*.jar");
093 pathsToDelete.add(lib + "/classes12*.jar");
094 pathsToDelete.add(lib + "/orai18n*.jar");
095 pathsToDelete.add(lib + "/spring*.jar"); // Rice requires a Spring jar file in Tomcat lib now.
096 pathsToDelete.add(env.getString("tomcat.setenv"));
097 pathsToDelete.add(env.getString("tomcat.conf.catalina"));
098 pathsToDelete.add(env.getString("tomcat.logs"));
099 pathsToDelete.add(env.getString("tomcat.webapps"));
100 pathsToDelete.add(env.getString("tomcat.work"));
101 pathsToDelete.add(env.getString("tomcat.temp"));
102 pathsToDelete.add(env.getString("tomcat.home") + "/kuali"); // /home/tomcat/kuali
103 pathsToDelete.add(env.getString("tomcat.home") + "/.kuali"); // /home/tomcat/.kuali
104 return pathsToDelete;
105 }
106
107 protected List<String> getTomcatCreates() {
108 // mkdir -p gets invoked on all of these
109 List<String> dirsToCreate = new ArrayList<String>();
110 dirsToCreate.add(env.getString("tomcat.logs"));
111 dirsToCreate.add(env.getString("tomcat.webapps"));
112 dirsToCreate.add(env.getString("tomcat.conf.catalina"));
113 dirsToCreate.add(env.getString("tomcat.temp"));
114 return dirsToCreate;
115 }
116
117 protected List<String> getTomcatChowns() {
118 // chown -L -R gets invoked on all of these
119 List<String> pathsToChown = new ArrayList<String>();
120 pathsToChown.add(env.getString("tomcat.base")); // Default value is /usr/local/tomcat
121 pathsToChown.add(env.getString("tomcat.home")); // Default value is /home/tomcat
122 return pathsToChown;
123 }
124
125 protected String getJdbcDriverPath(Artifact jdbcDriver) {
126 File file = localRepositoryService.getFile(jdbcDriver);
127 return new CanonicalFile(file).getPath();
128 }
129
130 protected Optional<Deployable> getJdbcDriver() {
131 Optional<Artifact> jdbcDriver = context.getJdbcDriver();
132 if (!jdbcDriver.isPresent()) {
133 return Optional.absent();
134 }
135 String lib = env.getString("tomcat.lib");
136 String local = getJdbcDriverPath(jdbcDriver.get());
137 String remote = lib + "/" + RepositoryUtils.getFilename(jdbcDriver.get());
138 Deployable deployable = new Deployable.Builder(local, remote).build();
139 return Optional.of(deployable);
140 }
141
142 protected List<Deployable> getTomcatDeployables() {
143 // Tomcat related files that get deployed
144 List<Deployable> deployables = new ArrayList<Deployable>();
145 deployables.add(getSetEnv());
146 deployables.addAll(getJsps());
147 deployables.addAll(context.getConfigFiles());
148 Optional<Deployable> jdbcDriver = getJdbcDriver();
149 if (jdbcDriver.isPresent()) {
150 deployables.add(jdbcDriver.get());
151 }
152 return deployables;
153 }
154
155 protected ApplicationServer getApplicationServer() {
156 // rm -rf gets invoked on all of these
157 List<String> pathsToDelete = getTomcatDeletes();
158
159 // mkdir -p gets invoked on all of these
160 List<String> dirsToCreate = getTomcatCreates();
161
162 // chown -L -R gets invoked on all of these
163 List<String> pathsToChown = getTomcatChowns();
164
165 // Tomcat related files that get deployed
166 List<Deployable> deployables = getTomcatDeployables();
167
168 // The war files can be quite large ~100mb's
169 // This flag provides a simple way to skip the overhead of uploading a war file
170 boolean skipWar = env.getBoolean("tomcat.war.skip", false);
171 if (!skipWar) {
172 deployables.add(getApplication());
173 }
174
175 // If true, skip transferring all tomcat related files to the remote machine
176 boolean skipFiles = env.getBoolean("tomcat.files.skip", false);
177
178 // Setup Tomcat with what it needs to stop/prepare/start correctly
179 TomcatApplicationServer tomcat = new TomcatApplicationServer();
180 tomcat.setChannel(channel);
181 tomcat.setUsername(env.getString("tomcat.user"));
182 tomcat.setGroup(env.getString("tomcat.group"));
183 tomcat.setShutdown(env.getString("tomcat.shutdown"));
184 tomcat.setStartup(env.getString("tomcat.startup"));
185 tomcat.setPathsToDelete(pathsToDelete);
186 tomcat.setDirsToCreate(dirsToCreate);
187 tomcat.setDeployables(deployables);
188 tomcat.setPathsToChown(pathsToChown);
189 tomcat.setSkipFiles(skipFiles);
190 tomcat.setFilterProperties(PropertySourceUtils.getAllEnumerableProperties(configurableEnvironment));
191 tomcat.setHttpWait(getHttpWaitExecutable());
192 return tomcat;
193 }
194
195 protected HttpWaitExecutable getHttpWaitExecutable() {
196 // Extract HttpContext properties from the environment
197 String overallTimeout = env.getString("http.overallTimeout", "30m");
198 String requestTimeout = env.getString("http.requestTimeout", "15s");
199 String url = env.getString("http.url");
200 String logMsgPrefix = env.getString("http.logMsgPrefix", "[tomcat:starting]");
201
202 // Setup the HttpContext
203 HttpContext context = new HttpContext.Builder(url).overallTimeout(overallTimeout).requestTimeout(requestTimeout).logMsgPrefix(logMsgPrefix).build();
204
205 // Get HttpWaitExecutable configuration
206 boolean skip = env.getBoolean("http.wait.skip", false);
207 HttpService service = httpServiceConfig.httpService();
208
209 // Setup the executable
210 return new HttpWaitExecutable(service, context, skip);
211 }
212
213 protected String getApplicationPath() {
214 Artifact app = context.getApplication();
215 File file = localRepositoryService.getFile(app);
216 return new CanonicalFile(file).getAbsolutePath();
217 }
218
219 protected Deployable getApplication() {
220 String local = getApplicationPath();
221 String remote = env.getString("tomcat.root.war");
222 return new Deployable.Builder(local, remote).build();
223 }
224
225 }