001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.geronimo.tomcat.deployment;
017:
018: import java.io.File;
019: import java.io.IOException;
020: import java.net.MalformedURLException;
021: import java.net.URI;
022: import java.net.URL;
023: import java.security.PermissionCollection;
024: import java.security.Permissions;
025: import java.util.Collection;
026: import java.util.Collections;
027: import java.util.HashMap;
028: import java.util.Iterator;
029: import java.util.Map;
030: import java.util.Set;
031:
032: import org.apache.commons.io.FileUtils;
033: import org.apache.geronimo.common.DeploymentException;
034: import org.apache.geronimo.connector.outbound.connectiontracking.ConnectionTrackingCoordinatorGBean;
035: import org.apache.geronimo.deployment.ModuleIDBuilder;
036: import org.apache.geronimo.deployment.service.GBeanBuilder;
037: import org.apache.geronimo.deployment.util.UnpackedJarFile;
038: import org.apache.geronimo.gbean.AbstractName;
039: import org.apache.geronimo.gbean.AbstractNameQuery;
040: import org.apache.geronimo.gbean.GBeanData;
041: import org.apache.geronimo.gbean.GBeanInfo;
042: import org.apache.geronimo.gbean.GBeanInfoBuilder;
043: import org.apache.geronimo.j2ee.deployment.EARContext;
044: import org.apache.geronimo.j2ee.deployment.Module;
045: import org.apache.geronimo.j2ee.deployment.NamingBuilderCollection;
046: import org.apache.geronimo.j2ee.deployment.WebServiceBuilder;
047: import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
048: import org.apache.geronimo.j2ee.management.impl.J2EEServerImpl;
049: import org.apache.geronimo.kernel.Jsr77Naming;
050: import org.apache.geronimo.kernel.Kernel;
051: import org.apache.geronimo.kernel.KernelFactory;
052: import org.apache.geronimo.kernel.Naming;
053: import org.apache.geronimo.kernel.mock.MockConfigStore;
054: import org.apache.geronimo.kernel.config.Configuration;
055: import org.apache.geronimo.kernel.config.ConfigurationData;
056: import org.apache.geronimo.kernel.config.ConfigurationManager;
057: import org.apache.geronimo.kernel.config.ConfigurationModuleType;
058: import org.apache.geronimo.kernel.config.ConfigurationStore;
059: import org.apache.geronimo.kernel.config.ConfigurationUtil;
060: import org.apache.geronimo.kernel.config.EditableKernelConfigurationManager;
061: import org.apache.geronimo.kernel.config.InvalidConfigException;
062: import org.apache.geronimo.kernel.config.NoSuchConfigException;
063: import org.apache.geronimo.kernel.config.NullConfigurationStore;
064: import org.apache.geronimo.kernel.management.State;
065: import org.apache.geronimo.kernel.repository.Artifact;
066: import org.apache.geronimo.kernel.repository.ArtifactManager;
067: import org.apache.geronimo.kernel.repository.ArtifactResolver;
068: import org.apache.geronimo.kernel.repository.DefaultArtifactManager;
069: import org.apache.geronimo.kernel.repository.DefaultArtifactResolver;
070: import org.apache.geronimo.kernel.repository.Environment;
071: import org.apache.geronimo.kernel.repository.ImportType;
072: import org.apache.geronimo.kernel.repository.Repository;
073: import org.apache.geronimo.security.SecurityServiceImpl;
074: import org.apache.geronimo.security.credentialstore.DirectConfigurationCredentialStoreImpl;
075: import org.apache.geronimo.security.deployment.GeronimoSecurityBuilderImpl;
076: import org.apache.geronimo.security.jacc.ApplicationPolicyConfigurationManager;
077: import org.apache.geronimo.security.jacc.ComponentPermissions;
078: import org.apache.geronimo.security.jacc.mappingprovider.GeronimoPolicyConfigurationFactory;
079: import org.apache.geronimo.security.jacc.mappingprovider.GeronimoPolicy;
080: import org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal;
081: import org.apache.geronimo.system.serverinfo.BasicServerInfo;
082: import org.apache.geronimo.testsupport.TestSupport;
083: import org.apache.geronimo.tomcat.EngineGBean;
084: import org.apache.geronimo.tomcat.HostGBean;
085: import org.apache.geronimo.tomcat.RealmGBean;
086: import org.apache.geronimo.tomcat.TomcatContainer;
087: import org.apache.geronimo.tomcat.connector.Http11ConnectorGBean;
088: import org.apache.geronimo.transaction.manager.GeronimoTransactionManagerGBean;
089:
090: /**
091: * @version $Rev:385232 $ $Date: 2008-01-18 00:00:10 -0800 (Fri, 18 Jan 2008) $
092: */
093: public class TomcatModuleBuilderTest extends TestSupport {
094: private static Naming naming = new Jsr77Naming();
095: private Artifact baseId = new Artifact("test", "base", "1", "car");
096: private final AbstractName serverName = naming.createRootName(
097: baseId, "Server", "J2EEServer");
098:
099: protected Kernel kernel;
100: private AbstractName tmName;
101: private AbstractName ctcName;
102: private ClassLoader cl;
103: private TomcatModuleBuilder builder;
104: private Artifact webModuleArtifact = new Artifact("foo", "bar",
105: "1", "car");
106: private Environment defaultEnvironment = new Environment();
107: private ConfigurationManager configurationManager;
108: private ConfigurationStore configStore;
109:
110: public void testDeployWar4() throws Exception {
111: verifyStartable("war4");
112: }
113:
114: public void testDeployWar5() throws Exception {
115: verifyStartable("war5");
116: }
117:
118: public void testDeployWar6() throws Exception {
119: verifyStartable("war6-jee5");
120: }
121:
122: public void testContextRootWithSpaces() throws Exception {
123: WebModuleInfo info = deployWar("war-spaces-in-context");
124: String contextRoot = (String) kernel.getAttribute(
125: info.moduleName, "contextPath");
126: assertNotNull(contextRoot);
127: assertEquals(contextRoot, contextRoot.trim());
128: undeployWar(info.configuration);
129: }
130:
131: private void verifyStartable(String warName) throws Exception {
132: WebModuleInfo info = deployWar(warName);
133: assertEquals(State.RUNNING_INDEX, kernel
134: .getGBeanState(info.moduleName));
135: Set names = info.configuration
136: .findGBeans(new AbstractNameQuery(info.moduleName
137: .getArtifact(), Collections.EMPTY_MAP));
138: log.debug("names: " + names);
139: for (Iterator iterator = names.iterator(); iterator.hasNext();) {
140: AbstractName objectName = (AbstractName) iterator.next();
141: assertEquals(State.RUNNING_INDEX, kernel
142: .getGBeanState(objectName));
143: }
144: undeployWar(info.configuration);
145: }
146:
147: private WebModuleInfo deployWar(String warName) throws Exception {
148: File outputPath = new File(BASEDIR,
149: "target/test-resources/deployables/" + warName);
150: recursiveDelete(outputPath);
151: outputPath.mkdirs();
152: File path = new File(BASEDIR, "src/test/resources/deployables/"
153: + warName);
154: //File dest = new File(BASEDIR, "target/test-resources/deployables/" + warName + "/war");
155: File dest = new File(BASEDIR,
156: "target/test-resources/deployables/" + warName);
157: recursiveCopy(path, dest);
158: UnpackedJarFile jarFile = new UnpackedJarFile(path);
159: Module module = builder.createModule(null, jarFile, kernel
160: .getNaming(), new ModuleIDBuilder());
161: Repository repository = null;
162:
163: AbstractName moduleName = module.getModuleName();
164: EARContext earContext = createEARContext(outputPath,
165: defaultEnvironment, repository, configStore, moduleName);
166: AbstractName jaccBeanName = kernel.getNaming().createChildName(
167: moduleName, "foo", NameFactory.JACC_MANAGER);
168: GBeanData jaccBeanData = new GBeanData(jaccBeanName,
169: ApplicationPolicyConfigurationManager.GBEAN_INFO);
170: PermissionCollection excludedPermissions = new Permissions();
171: PermissionCollection uncheckedPermissions = new Permissions();
172: ComponentPermissions componentPermissions = new ComponentPermissions(
173: excludedPermissions, uncheckedPermissions,
174: new HashMap());
175: Map contextIDToPermissionsMap = new HashMap();
176: contextIDToPermissionsMap
177: .put(
178: "test_J2EEApplication=null_J2EEServer=bar_j2eeType=WebModule_name=geronimo/test/1.0/war",
179: componentPermissions);
180: jaccBeanData.setAttribute("contextIdToPermissionsMap",
181: contextIDToPermissionsMap);
182: // jaccBeanData.setAttribute("principalRoleMap", new HashMap());
183: jaccBeanData.setAttribute("roleDesignates", new HashMap());
184: earContext.addGBean(jaccBeanData);
185: earContext.setJaccManagerName(jaccBeanName);
186: module.setEarContext(earContext);
187: module.setRootEarContext(earContext);
188: builder.initContext(earContext, module, cl);
189: builder.addGBeans(earContext, module, cl, null);
190: ConfigurationData configurationData = earContext
191: .getConfigurationData();
192: earContext.close();
193: module.close();
194:
195: Artifact configurationId = configurationData.getId();
196: configurationManager.loadConfiguration(configurationData);
197: Configuration configuration = configurationManager
198: .getConfiguration(configurationId);
199: configurationManager.startConfiguration(configurationId);
200:
201: return new WebModuleInfo(moduleName, configuration);
202: }
203:
204: private void undeployWar(Configuration configuration)
205: throws Exception {
206: configurationManager.stopConfiguration(configuration.getId());
207: configurationManager.unloadConfiguration(configuration.getId());
208: }
209:
210: private EARContext createEARContext(File outputPath,
211: Environment environment, Repository repository,
212: ConfigurationStore configStore, AbstractName moduleName)
213: throws DeploymentException {
214: Set repositories = repository == null ? Collections.EMPTY_SET
215: : Collections.singleton(repository);
216: ArtifactManager artifactManager = new DefaultArtifactManager();
217: ArtifactResolver artifactResolver = new DefaultArtifactResolver(
218: artifactManager, repositories, null);
219: return new EARContext(outputPath, null, environment,
220: ConfigurationModuleType.WAR, naming,
221: configurationManager, repositories,
222: new AbstractNameQuery(serverName), moduleName,
223: new AbstractNameQuery(tmName), new AbstractNameQuery(
224: ctcName), null, null, null);
225: }
226:
227: private void recursiveDelete(File path) {
228: //does not delete top level dir passed in
229: File[] listing = path.listFiles();
230: if (listing != null) {
231: for (int i = 0; i < listing.length; i++) {
232: File file = listing[i];
233: if (file.isDirectory()) {
234: recursiveDelete(file);
235: }
236: file.delete();
237: }
238: }
239: }
240:
241: public void recursiveCopy(File src, File dest) throws IOException {
242: Collection files = FileUtils.listFiles(src, null, true);
243: Iterator iterator = files.iterator();
244: while (iterator.hasNext()) {
245: File file = (File) iterator.next();
246: if (file.getAbsolutePath().indexOf(".svn") < 0) {
247: String pathToFile = file.getPath();
248: String relativePath = pathToFile.substring(src
249: .getPath().length(), pathToFile.length()
250: - (file.getName().length()));
251: FileUtils.copyFileToDirectory(file, new File(dest
252: .getPath()
253: + relativePath));
254: }
255: }
256: }
257:
258: protected void setUp() throws Exception {
259: super .setUp();
260: cl = this .getClass().getClassLoader();
261: kernel = KernelFactory.newInstance().createKernel("test");
262: kernel.boot();
263:
264: ConfigurationData bootstrap = new ConfigurationData(baseId,
265: naming);
266:
267: GBeanData serverInfo = bootstrap.addGBean("ServerInfo",
268: BasicServerInfo.GBEAN_INFO);
269: serverInfo.setAttribute("baseDirectory", ".");
270:
271: AbstractName configStoreName = bootstrap.addGBean(
272: "MockConfigurationStore", MockConfigStore.GBEAN_INFO)
273: .getAbstractName();
274:
275: GBeanData artifactManagerData = bootstrap.addGBean(
276: "ArtifactManager", DefaultArtifactManager.GBEAN_INFO);
277:
278: GBeanData artifactResolverData = bootstrap.addGBean(
279: "ArtifactResolver", DefaultArtifactResolver.GBEAN_INFO);
280: artifactResolverData.setReferencePattern("ArtifactManager",
281: artifactManagerData.getAbstractName());
282:
283: GBeanData configurationManagerData = bootstrap.addGBean(
284: "ConfigurationManager",
285: EditableKernelConfigurationManager.GBEAN_INFO);
286: configurationManagerData.setReferencePattern("ArtifactManager",
287: artifactManagerData.getAbstractName());
288: configurationManagerData.setReferencePattern(
289: "ArtifactResolver", artifactResolverData
290: .getAbstractName());
291: configurationManagerData.setReferencePattern("Stores",
292: configStoreName);
293: bootstrap.addGBean(configurationManagerData);
294:
295: GBeanData serverData = new GBeanData(serverName,
296: J2EEServerImpl.GBEAN_INFO);
297: bootstrap.addGBean(serverData);
298:
299: GBeanData securityService = bootstrap.addGBean(
300: "SecurityService", SecurityServiceImpl.GBEAN_INFO);
301: securityService.setAttribute("policyConfigurationFactory",
302: GeronimoPolicyConfigurationFactory.class.getName());
303: securityService.setAttribute("policyProvider",
304: GeronimoPolicy.class.getName());
305: securityService.setReferencePattern("ServerInfo", serverInfo
306: .getAbstractName());
307:
308: // Default Realm
309: Map initParams = new HashMap();
310:
311: initParams
312: .put("userClassNames",
313: "org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal");
314: initParams
315: .put("roleClassNames",
316: "org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal");
317: GBeanData realm = bootstrap.addGBean("tomcatRealm",
318: RealmGBean.GBEAN_INFO);
319: realm.setAttribute("className",
320: "org.apache.geronimo.tomcat.realm.TomcatJAASRealm");
321: realm.setAttribute("initParams", initParams);
322:
323: // Default Host
324: initParams = new HashMap();
325: initParams.put("workDir", "work");
326: initParams.put("name", "localhost");
327: initParams.put("appBase", "");
328: GBeanData host = bootstrap.addGBean("tomcatHost",
329: HostGBean.GBEAN_INFO);
330: host.setAttribute("className",
331: "org.apache.catalina.core.StandardHost");
332: host.setAttribute("initParams", initParams);
333:
334: // Default Engine
335: initParams = new HashMap();
336: initParams.put("name", "Geronimo");
337: GBeanData engine = bootstrap.addGBean("tomcatEngine",
338: EngineGBean.GBEAN_INFO);
339: engine.setAttribute("className",
340: "org.apache.geronimo.tomcat.TomcatEngine");
341: engine.setAttribute("initParams", initParams);
342: engine.setReferencePattern("DefaultHost", host
343: .getAbstractName());
344: engine.setReferencePattern("RealmGBean", realm
345: .getAbstractName());
346: engine.setReferencePattern("Hosts", host.getAbstractName());
347:
348: WebServiceBuilder webServiceBuilder = new MockWebServiceBuilder();
349:
350: GBeanData containerData = bootstrap.addGBean("TomcatContainer",
351: TomcatContainer.GBEAN_INFO);
352: containerData.setAttribute("catalinaHome", new File(BASEDIR,
353: "target/var/catalina").toString());
354: containerData.setReferencePattern("EngineGBean", engine
355: .getAbstractName());
356: containerData.setReferencePattern("ServerInfo", serverInfo
357: .getAbstractName());
358: AbstractName containerName = containerData.getAbstractName();
359:
360: GBeanData connector = bootstrap.addGBean("TomcatConnector",
361: Http11ConnectorGBean.GBEAN_INFO);
362: connector.setAttribute("name", "HTTP");
363: connector.setAttribute("port", new Integer(8181));
364: connector.setReferencePattern("TomcatContainer", containerName);
365: connector.setReferencePattern("ServerInfo", serverInfo
366: .getAbstractName());
367:
368: GBeanData tm = bootstrap.addGBean("TransactionManager",
369: GeronimoTransactionManagerGBean.GBEAN_INFO);
370: tmName = tm.getAbstractName();
371: tm.setAttribute("defaultTransactionTimeoutSeconds",
372: new Integer(10));
373:
374: GBeanData ctc = bootstrap.addGBean(
375: "ConnectionTrackingCoordinator",
376: ConnectionTrackingCoordinatorGBean.GBEAN_INFO);
377: ctcName = ctc.getAbstractName();
378: ctc.setReferencePattern("TransactionManager", tmName);
379:
380: GBeanData cs = bootstrap.addGBean("CredentialStore",
381: DirectConfigurationCredentialStoreImpl.GBEAN_INFO);
382: Map<String, Map<String, Map<String, String>>> csd = new HashMap<String, Map<String, Map<String, String>>>();
383: Map<String, Map<String, String>> r = new HashMap<String, Map<String, String>>();
384: csd.put("foo", r);
385: Map<String, String> creds = new HashMap<String, String>();
386: r.put("metro", creds);
387: creds.put(GeronimoUserPrincipal.class.getName(), "metro");
388: cs.setAttribute("credentialStore", csd);
389:
390: ConfigurationUtil.loadBootstrapConfiguration(kernel, bootstrap,
391: getClass().getClassLoader());
392:
393: configurationManager = ConfigurationUtil
394: .getEditableConfigurationManager(kernel);
395: configStore = (ConfigurationStore) kernel
396: .getGBean(configStoreName);
397: configStore.install(bootstrap);
398:
399: defaultEnvironment.addDependency(baseId, ImportType.ALL);
400: defaultEnvironment.setConfigId(webModuleArtifact);
401: builder = new TomcatModuleBuilder(defaultEnvironment,
402: new AbstractNameQuery(containerName), Collections
403: .singleton(webServiceBuilder),
404: Collections.singleton(new GeronimoSecurityBuilderImpl(
405: new AbstractNameQuery(URI
406: .create("?name=CredentialStore")))),
407: Collections.singleton(new GBeanBuilder(null, null)),
408: new NamingBuilderCollection(null, null),
409: Collections.EMPTY_LIST, null,
410: new MockResourceEnvironmentSetter(), null);
411: builder.doStart();
412: }
413:
414: protected void tearDown() throws Exception {
415: builder.doStop();
416: kernel.shutdown();
417: super .tearDown();
418: }
419:
420: private static class WebModuleInfo {
421: AbstractName moduleName;
422: Configuration configuration;
423:
424: public WebModuleInfo(AbstractName moduleName,
425: Configuration configuration) {
426: this.moduleName = moduleName;
427: this.configuration = configuration;
428: }
429: }
430:
431: }
|