1 7 package org.jboss.web.tomcat.tc5; 8 9 import java.io.File ; 10 import java.io.FileOutputStream ; 11 import java.io.IOException ; 12 import java.io.InputStream ; 13 import java.net.URL ; 14 import java.util.Iterator ; 15 import java.util.HashMap ; 16 import java.util.HashSet ; 17 import java.util.Set ; 18 import java.util.zip.ZipEntry ; 19 import java.util.zip.ZipFile ; 20 import java.security.CodeSource ; 21 import java.security.cert.Certificate ; 22 23 import javax.management.Attribute ; 24 import javax.management.ObjectInstance ; 25 import javax.management.ObjectName ; 26 27 import org.apache.catalina.Loader; 28 import org.apache.catalina.session.StandardManager; 29 import org.jboss.deployment.DeploymentException; 30 import org.jboss.deployment.DeploymentInfo; 31 import org.jboss.metadata.WebMetaData; 32 import org.jboss.web.AbstractWebContainer; 33 import org.jboss.web.AbstractWebDeployer; 34 import org.jboss.web.WebApplication; 35 import org.jboss.web.tomcat.security.JaccContextValve; 36 import org.jboss.web.tomcat.security.SecurityAssociationValve; 37 import org.jboss.web.tomcat.security.CustomPrincipalValve; 38 import org.jboss.web.tomcat.tc5.session.ClusteredSessionValve; 39 import org.jboss.web.tomcat.tc5.session.ClusteringNotSupportedException; 40 import org.jboss.web.tomcat.tc5.session.InstantSnapshotManager; 41 import org.jboss.web.tomcat.tc5.session.IntervalSnapshotManager; 42 import org.jboss.web.tomcat.tc5.session.AbstractJBossManager; 43 import org.jboss.web.tomcat.tc5.session.SnapshotManager; 44 45 52 public class TomcatDeployer extends AbstractWebDeployer 53 { 54 57 private static final String CONTEXT_CONFIG_FILE = "WEB-INF/context.xml"; 58 59 private DeployerConfig config; 60 private String [] javaVMs = 61 {" jboss.management.local:J2EEServer=Local,j2eeType=JVM,name=localhost"}; 62 private String serverName = "jboss"; 63 private HashMap vhostToHostNames = new HashMap (); 64 65 public void init(Object containerConfig) throws Exception 66 { 67 this.config = (DeployerConfig) containerConfig; 68 super.setJava2ClassLoadingCompliance(config.isJava2ClassLoadingCompliance()); 69 super.setUnpackWars(config.isUnpackWars()); 70 super.setLenientEjbLink(config.isLenientEjbLink()); 71 super.setDefaultSecurityDomain(config.getDefaultSecurityDomain()); 72 } 73 74 77 protected void performDeploy(WebApplication appInfo, String warUrl, 78 AbstractWebContainer.WebDescriptorParser webAppParser) 79 throws Exception 80 { 81 WebMetaData metaData = appInfo.getMetaData(); 82 String hostName = null; 83 Iterator vhostNames = metaData.getVirtualHosts(); 85 Iterator hostNames = mapVirtualHosts(vhostNames); 87 if (hostNames.hasNext()) 88 { 89 hostName = hostNames.next().toString(); 90 } 91 performDeployInternal(hostName, appInfo, warUrl, webAppParser); 92 while (hostNames.hasNext()) 93 { 94 String additionalHostName = hostNames.next().toString(); 95 performDeployInternal(additionalHostName, appInfo, warUrl, webAppParser); 96 } 97 } 98 99 protected void performDeployInternal(String hostName, 100 WebApplication appInfo, String warUrl, 101 AbstractWebContainer.WebDescriptorParser webAppParser) 102 throws Exception 103 { 104 105 WebMetaData metaData = appInfo.getMetaData(); 106 String ctxPath = metaData.getContextRoot(); 107 if (ctxPath.equals("/") || ctxPath.equals("/ROOT") || ctxPath.equals("")) 108 { 109 log.debug("deploy root context=" + ctxPath); 110 ctxPath = "/"; 111 metaData.setContextRoot(ctxPath); 112 } 113 log.info("deploy, ctxPath=" + ctxPath + ", warUrl=" + warUrl); 114 115 URL url = new URL (warUrl); 116 117 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 118 123 Loader webLoader = null; 124 if (config.isUseJBossWebLoader()) 125 { 126 WebCtxLoader jbossLoader = new WebCtxLoader(loader); 127 jbossLoader.setWarURL(url); 128 webLoader = jbossLoader; 129 } 130 else 131 { 132 String [] pkgs = config.getFilteredPackages(); 133 WebAppLoader jbossLoader = new WebAppLoader(loader, pkgs); 134 webLoader = jbossLoader; 135 } 136 137 if (appInfo.getAppData() == null) 143 webAppParser.parseWebAppDescriptors(loader, appInfo.getMetaData()); 144 145 appInfo.setName(url.getPath()); 146 appInfo.setClassLoader(loader); 147 appInfo.setURL(url); 148 149 String objectNameS = config.getCatalinaDomain() 150 + ":j2eeType=WebModule,name=//" + 151 ((hostName == null) ? "localhost" : hostName) 152 + ctxPath + ",J2EEApplication=none,J2EEServer=none"; 153 154 ObjectName objectName = new ObjectName (objectNameS); 155 156 if (server.isRegistered(objectName)) 157 { 158 log.debug("Already exists, destroying " + objectName); 159 server.invoke(objectName, "destroy", new Object []{}, 160 new String []{}); 161 } 162 163 server.createMBean("org.apache.commons.modeler.BaseModelMBean", 164 objectName, new Object []{config.getContextClassName()}, 165 new String []{"java.lang.String"}); 166 167 String ctxConfig = null; 170 try 171 { 172 ctxConfig = findConfig(url); 173 } 174 catch (IOException e) 175 { 176 log.debug("No " + CONTEXT_CONFIG_FILE + " in " + url, e); 177 } 178 179 server.setAttribute(objectName, new Attribute ("docBase", url.getFile())); 180 181 server.setAttribute(objectName, new Attribute ("configFile", ctxConfig)); 182 183 server.setAttribute(objectName, new Attribute 184 ("defaultContextXml", "context.xml")); 185 server.setAttribute(objectName, new Attribute 186 ("defaultWebXml", "conf/web.xml")); 187 188 server.setAttribute(objectName, new Attribute ("javaVMs", javaVMs)); 189 190 server.setAttribute(objectName, new Attribute ("server", serverName)); 191 192 server.setAttribute(objectName, new Attribute 193 ("saveConfig", Boolean.FALSE)); 194 195 if (webLoader != null) 196 { 197 server.setAttribute(objectName, new Attribute 198 ("loader", webLoader)); 199 } 200 else 201 { 202 server.setAttribute(objectName, new Attribute 203 ("parentClassLoader", loader)); 204 } 205 206 server.setAttribute(objectName, new Attribute 207 ("delegate", new Boolean (getJava2ClassLoadingCompliance()))); 208 209 String [] jspCP = getCompileClasspath(loader); 210 StringBuffer classpath = new StringBuffer (); 211 for (int u = 0; u < jspCP.length; u++) 212 { 213 String repository = jspCP[u]; 214 if (repository == null) 215 continue; 216 if (repository.startsWith("file://")) 217 repository = repository.substring(7); 218 else if (repository.startsWith("file:")) 219 repository = repository.substring(5); 220 else 221 continue; 222 if (repository == null) 223 continue; 224 File fp = new File (repository); 226 if (!fp.isDirectory()) 227 { 228 try 230 { 231 ZipFile zip = new ZipFile (fp); 232 zip.close(); 233 } 234 catch (IOException e) 235 { 236 continue; 237 } 238 239 } 240 if (u > 0) 241 classpath.append(File.pathSeparator); 242 classpath.append(repository); 243 } 244 245 server.setAttribute(objectName, new Attribute 246 ("compilerClasspath", classpath.toString())); 247 248 switch (metaData.getSessionCookies()) 250 { 251 case WebMetaData.SESSION_COOKIES_ENABLED: 252 server.setAttribute(objectName, new Attribute 253 ("cookies", new Boolean (true))); 254 log.debug("Enabling session cookies"); 255 break; 256 case WebMetaData.SESSION_COOKIES_DISABLED: 257 server.setAttribute(objectName, new Attribute 258 ("cookies", new Boolean (false))); 259 log.debug("Disabling session cookies"); 260 break; 261 default: 262 log.debug("Using session cookies default setting"); 263 } 264 265 Certificate [] certs = null; 267 CodeSource cs = new CodeSource (url, certs); 268 JaccContextValve jaccValve = new JaccContextValve(metaData.getJaccContextID(), cs); 269 server.invoke(objectName, "addValve", 270 new Object []{jaccValve}, 271 new String []{"org.apache.catalina.Valve"}); 272 273 server.invoke(objectName, "init", new Object []{}, new String []{}); 275 276 if (metaData.getDistributable()) 277 { 278 try 280 { 281 AbstractJBossManager manager = null; 282 String managerClassName = config.getManagerClass(); 283 Class managerClass = Thread.currentThread().getContextClassLoader().loadClass(managerClassName); 284 manager = (AbstractJBossManager) managerClass.newInstance(); 285 String name = "//" + ((hostName == null) ? "localhost" : hostName) + ctxPath; 286 manager.init(name, metaData, config.isUseJK(), config.isUseLocalCache()); 287 server.setAttribute(objectName, new Attribute ("manager", manager)); 288 289 if (manager instanceof AbstractJBossManager) 290 { 291 SnapshotManager snap = null; 293 String snapshotMode = config.getSnapshotMode(); 294 int snapshotInterval = config.getSnapshotInterval(); 295 if (snapshotMode.equals("instant")) 296 { 297 snap = new InstantSnapshotManager(manager, ctxPath); 298 } 299 else if (snapshotMode.equals("interval")) 300 { 301 snap = new IntervalSnapshotManager(manager, ctxPath, snapshotInterval); 302 } 303 else 304 { 305 log.error("Snapshot mode must be 'instant' or 'interval' - using 'instant'"); 306 snap = new InstantSnapshotManager(manager, ctxPath); 307 } 308 Object valve = new ClusteredSessionValve(snap); 310 server.invoke(objectName, "addValve", 311 new Object []{valve}, 312 new String []{"org.apache.catalina.Valve"}); 313 } 314 else 315 { 316 throw new ClusteringNotSupportedException("managerClass " + managerClassName + " not known"); 317 } 318 319 log.debug("Enabled clustering support for ctxPath=" + ctxPath); 320 } 321 catch (ClusteringNotSupportedException e) 322 { 323 log.error("Failed to setup clustering, clustering disabled"); 324 } 325 } 326 327 331 SecurityAssociationValve valve = new SecurityAssociationValve(metaData, 332 config.getSecurityManagerService()); 333 valve.setSubjectAttributeName(config.getSubjectAttributeName()); 334 server.invoke(objectName, "addValve", 335 new Object []{valve}, 336 new String []{"org.apache.catalina.Valve"}); 337 338 341 CustomPrincipalValve cpvalve = new CustomPrincipalValve(); 342 server.invoke(objectName, "addValve", 343 new Object []{cpvalve}, 344 new String []{"org.apache.catalina.Valve"}); 345 346 Integer state = (Integer ) server.getAttribute(objectName, "state"); 348 if (state.intValue() != 1) 349 { 350 throw new DeploymentException("URL " + warUrl + " deployment failed"); 351 } 352 353 Loader ctxLoader = (Loader) server.getAttribute(objectName, "loader"); 356 metaData.setContextLoader(ctxLoader.getClassLoader()); 357 358 appInfo.setAppData(objectName); 359 360 DeploymentInfo di = webAppParser.getDeploymentInfo(); 362 di.deployedObject = objectName; 363 ObjectName servletQuery = new ObjectName 364 (config.getCatalinaDomain() + ":j2eeType=Servlet,WebModule=" 365 + objectName.getKeyProperty("name") + ",*"); 366 Iterator iterator = server.queryMBeans(servletQuery, null).iterator(); 367 while (iterator.hasNext()) 368 { 369 di.mbeans.add(((ObjectInstance ) iterator.next()).getObjectName()); 370 } 371 372 log.debug("Initialized: " + appInfo + " " + objectName); 373 374 } 375 376 377 381 protected void performUndeploy(String warUrl, WebApplication appInfo) 382 throws Exception 383 { 384 if (appInfo == null) 385 { 386 log.debug("performUndeploy, no WebApplication found for URL " 387 + warUrl); 388 return; 389 } 390 391 log.info("undeploy, ctxPath=" + appInfo.getMetaData().getContextRoot() 392 + ", warUrl=" + warUrl); 393 394 WebMetaData metaData = appInfo.getMetaData(); 395 String hostName = null; 396 Iterator hostNames = metaData.getVirtualHosts(); 397 if (hostNames.hasNext()) 398 { 399 hostName = hostNames.next().toString(); 400 } 401 performUndeployInternal(hostName, warUrl, appInfo); 402 while (hostNames.hasNext()) 403 { 404 String additionalHostName = hostNames.next().toString(); 405 performUndeployInternal(additionalHostName, warUrl, appInfo); 406 } 407 408 } 409 410 protected void performUndeployInternal(String hostName, String warUrl, 411 WebApplication appInfo) 412 throws Exception 413 { 414 415 WebMetaData metaData = appInfo.getMetaData(); 416 String ctxPath = metaData.getContextRoot(); 417 418 if (server == null) 420 return; 421 422 ObjectName objectName = new ObjectName (config.getCatalinaDomain() 423 + ":j2eeType=WebModule,name=//" + 424 ((hostName == null) ? "localhost" : hostName) 425 + ctxPath + ",J2EEApplication=none,J2EEServer=none"); 426 427 if (server.isRegistered(objectName)) 428 { 429 server.invoke(objectName, "destroy", new Object []{}, 431 new String []{}); 432 } 433 434 } 435 436 442 protected synchronized Iterator mapVirtualHosts(Iterator vhostNames) 443 throws Exception 444 { 445 if( vhostToHostNames.size() == 0 ) 446 { 447 String hostQuery = config.getCatalinaDomain() + ":type=Host,*"; 449 ObjectName query = new ObjectName (hostQuery); 450 Set hosts = server.queryNames(query, null); 451 Iterator iter = hosts.iterator(); 452 while( iter.hasNext() ) 453 { 454 ObjectName host = (ObjectName ) iter.next(); 455 String name = host.getKeyProperty("host"); 456 if( name != null ) 457 { 458 vhostToHostNames.put(name, name); 459 String [] aliases = (String []) 460 server.invoke(host, "findAliases", null, null); 461 int count = aliases != null ? aliases.length : 0; 462 for(int n = 0;n < count; n ++) 463 { 464 vhostToHostNames.put(aliases[n], name); 465 } 466 } 467 } 468 } 469 470 HashSet hosts = new HashSet (); 472 while( vhostNames.hasNext() ) 473 { 474 String vhost = (String ) vhostNames.next(); 475 String host = (String ) vhostToHostNames.get(vhost); 476 if( host == null ) 477 { 478 log.warn("Failed to map vhost: "+vhost); 479 host = vhost; 481 } 482 hosts.add(host); 483 } 484 return hosts.iterator(); 485 } 486 487 private String findConfig(URL warURL) throws IOException 488 { 489 String result = null; 490 File warFile = new File (warURL.getFile()); 492 if (warURL.getProtocol().equals("file") && warFile.isDirectory() == true) 493 { 494 File webDD = new File (warFile, CONTEXT_CONFIG_FILE); 495 if (webDD.exists() == true) result = webDD.getAbsolutePath(); 496 } 497 else 498 { 499 ZipFile zipFile = new ZipFile (warFile); 500 ZipEntry entry = zipFile.getEntry(CONTEXT_CONFIG_FILE); 501 if (entry != null) 502 { 503 InputStream zipIS = zipFile.getInputStream(entry); 504 byte[] buffer = new byte[512]; 505 int bytes; 506 result = warFile.getAbsolutePath() + "-context.xml"; 507 FileOutputStream fos = new FileOutputStream (result); 508 while ((bytes = zipIS.read(buffer)) > 0) 509 { 510 fos.write(buffer, 0, bytes); 511 } 512 zipIS.close(); 513 fos.close(); 514 } 515 zipFile.close(); 516 } 517 return result; 518 } 519 520 } 521 | Popular Tags |