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    }