/** * * Copyright 2003-2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.geronimo.tomcat; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Properties; import java.util.ArrayList; import java.util.Set; import javax.management.ObjectName; import junit.framework.TestCase; import sun.misc.BASE64Encoder; import org.apache.geronimo.gbean.GBeanData; import org.apache.geronimo.j2ee.j2eeobjectnames.J2eeContext; import org.apache.geronimo.j2ee.j2eeobjectnames.J2eeContextImpl; import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; import org.apache.geronimo.kernel.Kernel; import org.apache.geronimo.kernel.KernelFactory; import org.apache.geronimo.kernel.management.State; import org.apache.geronimo.security.SecurityServiceImpl; import org.apache.geronimo.security.deploy.PrincipalInfo; import org.apache.geronimo.security.jaas.GeronimoLoginConfiguration; import org.apache.geronimo.security.jaas.JaasLoginModuleUse; import org.apache.geronimo.security.jaas.LoginModuleGBean; import org.apache.geronimo.security.jaas.server.JaasLoginService; import org.apache.geronimo.security.realm.GenericSecurityRealm; import org.apache.geronimo.system.serverinfo.BasicServerInfo; import org.apache.geronimo.tomcat.app.MockWebServiceContainer; import org.apache.geronimo.webservices.WebServiceContainer; import org.apache.geronimo.gbean.ReferenceCollection; import org.apache.geronimo.gbean.ReferenceCollectionEvent; import org.apache.geronimo.gbean.ReferenceCollectionListener; /** * @version $Rev$ $Date$ */ public class ContainerTest extends TestCase { private ClassLoader cl = this.getClass().getClassLoader(); private Kernel kernel; private GBeanData container; private ObjectName containerName; private Set containerPatterns; private ObjectName connectorName; private GBeanData connector; private ObjectName engineName; private GBeanData engine; private ObjectName hostName; private GBeanData host; private J2eeContext moduleContext = new J2eeContextImpl("tomcat.test", "test", "null", NameFactory.WEB_MODULE, "tomcatTest", null, null); private ObjectName serverInfoName; private GBeanData serverInfoGBean; private GBeanData securityServiceGBean; private ObjectName securityServiceName; private ObjectName loginServiceName; private GBeanData loginServiceGBean; private GBeanData loginConfigurationGBean; private ObjectName loginConfigurationName; private GBeanData propertiesLMGBean; private ObjectName propertiesLMName; private ObjectName propertiesRealmName; private GBeanData propertiesRealmGBean; public void testWebServiceHandler() throws Exception { setUpWeb(); assertEquals(State.RUNNING_INDEX, kernel.getGBeanState(connectorName)); assertEquals(State.RUNNING_INDEX, kernel.getGBeanState(containerName)); String contextPath = "/foo/webservice.ws"; MockWebServiceContainer webServiceInvoker = new MockWebServiceContainer(); kernel.invoke(containerName, "addWebService", new Object[]{contextPath, null, webServiceInvoker, null, null, null, null, cl}, new String[]{String.class.getName(), String[].class.getName(), WebServiceContainer.class.getName(), String.class.getName(), String.class.getName(), String.class.getName(), String.class.getName(), ClassLoader.class.getName()}); HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:8181" + contextPath).openConnection(); try { BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); assertEquals("Hello World", reader.readLine()); } finally { connection.disconnect(); } kernel.invoke(containerName, "removeWebService", new Object[]{contextPath}, new String[]{String.class.getName()}); connection = (HttpURLConnection) new URL("http://localhost:8181" + contextPath).openConnection(); try { connection.getInputStream(); fail(); } catch (Exception e) { // see if we removed the ws. assertEquals(HttpURLConnection.HTTP_NOT_FOUND, connection.getResponseCode()); connection.disconnect(); } tearDownWeb(); } public void testSecureWebServiceHandler() throws Exception { setUpWeb(); assertEquals(State.RUNNING_INDEX, kernel.getGBeanState(connectorName)); assertEquals(State.RUNNING_INDEX, kernel.getGBeanState(containerName)); setUpSecurity(); String contextPath = "/foo/webservice.ws"; MockWebServiceContainer webServiceInvoker = new MockWebServiceContainer(); kernel.invoke(containerName, "addWebService", new Object[]{contextPath, null, webServiceInvoker, "Geronimo", "Geronimo", "NONE", "BASIC", cl}, new String[]{String.class.getName(), String[].class.getName(), WebServiceContainer.class.getName(), String.class.getName(), String.class.getName(), String.class.getName(), String.class.getName(), ClassLoader.class.getName()}); //Veryify its secured HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:8181" + contextPath).openConnection(); try { connection.getInputStream(); fail(); } catch (Exception e) { assertEquals(HttpURLConnection.HTTP_UNAUTHORIZED, connection.getResponseCode()); } finally { connection.disconnect(); } //Authenticate connection = (HttpURLConnection) new URL("http://localhost:8181" + contextPath).openConnection(); String authentication = (new BASE64Encoder()).encode(("alan:starcraft").getBytes()); connection.setRequestProperty("Authorization", "Basic " + authentication); try { BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); assertEquals("Hello World", reader.readLine()); } finally { connection.disconnect(); } kernel.invoke(containerName, "removeWebService", new Object[]{contextPath}, new String[]{String.class.getName()}); connection = (HttpURLConnection) new URL("http://localhost:8181" + contextPath).openConnection(); try { connection.getInputStream(); fail(); } catch (Exception e) { // see if we removed the ws. assertEquals(HttpURLConnection.HTTP_NOT_FOUND, connection.getResponseCode()); connection.disconnect(); } tearDownSecurity(); tearDownWeb(); } private void start(GBeanData instance) throws Exception { kernel.loadGBean(instance, cl); kernel.startGBean(instance.getName()); } private void stop(ObjectName name) throws Exception { kernel.stopGBean(name); kernel.unloadGBean(name); } protected void setUpSecurity() throws Exception { loginConfigurationName = new ObjectName("geronimo.security:type=LoginConfiguration"); loginConfigurationGBean = new GBeanData(loginConfigurationName, GeronimoLoginConfiguration.getGBeanInfo()); Set configurations = new HashSet(); configurations.add(new ObjectName("geronimo.server:j2eeType=SecurityRealm,*")); configurations.add(new ObjectName("geronimo.server:j2eeType=ConfigurationEntry,*")); loginConfigurationGBean.setReferencePatterns("Configurations", configurations); securityServiceName = new ObjectName("geronimo.server:j2eeType=SecurityService"); securityServiceGBean = new GBeanData(securityServiceName, SecurityServiceImpl.GBEAN_INFO); securityServiceGBean.setReferencePattern("ServerInfo", serverInfoName); securityServiceGBean.setAttribute("policyConfigurationFactory", "org.apache.geronimo.security.jacc.GeronimoPolicyConfigurationFactory"); securityServiceGBean.setAttribute("policyProvider", "org.apache.geronimo.security.jacc.GeronimoPolicy"); loginServiceName = new ObjectName("test:name=TestLoginService"); loginServiceGBean = new GBeanData(loginServiceName, JaasLoginService.GBEAN_INFO); loginServiceGBean.setReferencePattern("Realms", new ObjectName("geronimo.server:j2eeType=SecurityRealm,*")); loginServiceGBean.setAttribute("algorithm", "HmacSHA1"); loginServiceGBean.setAttribute("password", "secret"); propertiesLMName = new ObjectName("geronimo.security:type=LoginModule,name=Geronimo"); propertiesLMGBean = new GBeanData(propertiesLMName, LoginModuleGBean.GBEAN_INFO); propertiesLMGBean.setAttribute("loginModuleClass", "org.apache.geronimo.security.realm.providers.PropertiesFileLoginModule"); propertiesLMGBean.setAttribute("serverSide", Boolean.TRUE); Properties options = new Properties(); options.setProperty("usersURI", "src/test-resources/data/users.properties"); options.setProperty("groupsURI", "src/test-resources/data/groups.properties"); propertiesLMGBean.setAttribute("options", options); propertiesLMGBean.setAttribute("loginDomainName", "geronimo-properties-realm"); ObjectName testUseName = new ObjectName("geronimo.security:type=LoginModuleUse,name=properties"); GBeanData lmUseGBean = new GBeanData(testUseName, JaasLoginModuleUse.getGBeanInfo()); lmUseGBean.setAttribute("controlFlag", "REQUIRED"); lmUseGBean.setReferencePattern("LoginModule", propertiesLMName); propertiesRealmName = new ObjectName("geronimo.server:j2eeType=SecurityRealm,name=geronimo-properties-realm"); propertiesRealmGBean = new GBeanData(propertiesRealmName, GenericSecurityRealm.GBEAN_INFO); propertiesRealmGBean.setReferencePattern("ServerInfo", serverInfoName); propertiesRealmGBean.setAttribute("realmName", "Geronimo"); propertiesRealmGBean.setReferencePattern("LoginModuleConfiguration", testUseName); propertiesRealmGBean.setReferencePattern("LoginService", loginServiceName); PrincipalInfo.PrincipalEditor principalEditor = new PrincipalInfo.PrincipalEditor(); principalEditor.setAsText("metro,org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal,false"); propertiesRealmGBean.setAttribute("defaultPrincipal", principalEditor.getValue()); start(loginConfigurationGBean); start(securityServiceGBean); start(loginServiceGBean); start(propertiesLMGBean); start(lmUseGBean); start(propertiesRealmGBean); } protected void tearDownSecurity() throws Exception { stop(propertiesRealmName); stop(propertiesLMName); stop(loginServiceName); stop(securityServiceName); stop(loginConfigurationName); } private void setUpWeb() throws Exception { containerName = NameFactory.getWebComponentName(null, null, null, null, "tomcatContainer", "WebResource", moduleContext); connectorName = NameFactory.getWebComponentName(null, null, null, null, "tomcatConnector", "WebResource", moduleContext); containerPatterns = new HashSet(); containerPatterns.add(containerName); connectorName = new ObjectName("geronimo.tomcat:role=Connector"); connectorName = NameFactory.getWebComponentName(null, null, null, null, "tomcatConnector", "WebResource", moduleContext); engineName = NameFactory.getWebComponentName(null, null, null, null, "tomcatEngine", "WebResource", moduleContext); hostName = NameFactory.getWebComponentName(null, null, null, null, "tomcatHost", "WebResource", moduleContext); kernel = KernelFactory.newInstance().createKernel("test.kernel"); kernel.boot(); //ServerInfo serverInfoName = new ObjectName("geronimo.system:role=ServerInfo"); serverInfoGBean = new GBeanData(serverInfoName, BasicServerInfo.GBEAN_INFO); serverInfoGBean.setAttribute("baseDirectory", "."); start(serverInfoGBean); Map initParams = new HashMap(); //Default Host initParams.clear(); initParams.put("workDir", "work"); initParams.put("name", "localhost"); initParams.put("appBase", ""); host = new GBeanData(hostName, HostGBean.GBEAN_INFO); host.setAttribute("className", "org.apache.catalina.core.StandardHost"); host.setAttribute("initParams", initParams); start(host); //Default Engine ReferenceCollection hosts = new TestReferenceCollection(); hosts.add(host); initParams.clear(); initParams.put("name", "Geronimo"); engine = new GBeanData(engineName, EngineGBean.GBEAN_INFO); engine.setAttribute("className", "org.apache.geronimo.tomcat.TomcatEngine"); engine.setReferencePattern("DefaultHost", hostName); engine.setAttribute("initParams", initParams); engine.setReferencePattern("Hosts", hostName); start(engine); container = new GBeanData(containerName, TomcatContainer.GBEAN_INFO); container.setAttribute("classLoader", cl); container.setAttribute("catalinaHome", "target/var/catalina"); container.setReferencePattern("EngineGBean", engineName); container.setReferencePattern("ServerInfo", serverInfoName); start(container); connector = new GBeanData(connectorName, ConnectorGBean.GBEAN_INFO); connector.setAttribute("name", "HTTP"); connector.setAttribute("port", new Integer(8181)); connector.setReferencePattern("TomcatContainer", containerName); start(connector); } private void tearDownWeb() throws Exception { stop(connectorName); stop(containerName); stop(hostName); stop(engineName); stop(serverInfoName); kernel.shutdown(); } private class TestReferenceCollection extends ArrayList implements ReferenceCollection { ReferenceCollectionListener referenceCollectionListener; public void addReferenceCollectionListener(ReferenceCollectionListener listener) { this.referenceCollectionListener = listener; } public void removeReferenceCollectionListener(ReferenceCollectionListener listener) { this.referenceCollectionListener = null; } public boolean add(Object o) { boolean result = super.add(o); if (referenceCollectionListener != null) { referenceCollectionListener.memberAdded(new ReferenceCollectionEvent(null, o)); } return result; } public boolean remove(Object o) { boolean result = super.remove(o); if (referenceCollectionListener != null) { referenceCollectionListener.memberRemoved(new ReferenceCollectionEvent(null, o)); } return result; } public ObjectName[] getMemberObjectNames() { ObjectName names[] = new ObjectName[this.size()]; for(int i=0; i < this.size(); i++){ GBeanData data = (GBeanData)this.get(i); names[i] = data.getName(); } return names; } } }