/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2006-2010 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package test.admin; import javax.management.MBeanServerConnection; import javax.management.ObjectName; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; import java.net.MalformedURLException; import java.io.InputStream; import java.io.IOException; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.cookie.CookiePolicy; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.testng.Assert; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Parameters; import org.glassfish.external.amx.AMXGlassfish; import org.glassfish.admin.amx.core.proxy.ProxyFactory; import org.glassfish.admin.amx.base.DomainRoot; import java.io.File; /** The base class for admin console tests. Designed for extension. * @author jdlee@dev.java.net * @since GlassFish v3 Prelude */ public class BaseAdminConsoleTest { protected String adminUrl; private HttpClient client; private static final int AC_TEST_DELAY = 1000; // One second private static final int AC_TEST_ITERATIONS = 60; // One minute private String host; private int port; private volatile MBeanServerConnection mMBeanServerConnection; private volatile DomainRoot mDomainRoot; private static final String FILE_SEP = System.getProperty("file.separator"); private static final String CONSOLE_DIR_PATH = FILE_SEP + "lib" + FILE_SEP + "install" + FILE_SEP + "applications" + FILE_SEP + "__admingui"; private static final String GLASSFISH_DIR = FILE_SEP + ".." + FILE_SEP +"glassfish"; // Copied from Lloyd's AMX tests void setUpEnvironment(int port) { try { if (mMBeanServerConnection == null) { host = System.getProperty("http.host"); this.port = port; mMBeanServerConnection = _getMBeanServerConnection(); mDomainRoot = _getDomainRoot(mMBeanServerConnection); } } catch (Exception e) { throw new RuntimeException(e); } } /** * This BeforeTest method will verify that the login form is available. Once * it is found, the login form is submitted. If the login succeeds, then * the tests are allowed to continue. If the login fails, the each test will * fail. * @param url * @throws java.lang.Exception */ @BeforeTest @Parameters({"admin.console.url", "amx.rmiport"}) public void loginBeforeTest(String url, int port) throws Exception { this.adminUrl = url; setUpEnvironment(port); client = new HttpClient(); boolean formFound = false; int iteration = 0; if (!checkForAdminConsoleDirectory()) { Assert.fail("The admin console directory was not found at " + this.getDomainRoot().getInstallDir() + GLASSFISH_DIR + CONSOLE_DIR_PATH + ". Please check your installation."); } while (!formFound && iteration < AC_TEST_ITERATIONS) { iteration++; formFound = getUrlAndTestForStrings(adminUrl + "login.jsf","id=\"Login.username\""); if (!formFound) { System.err.println("***** Login page not found. Sleeping to allow app to deploy (" + iteration + " of " + AC_TEST_ITERATIONS + ")..."); Thread.sleep(AC_TEST_DELAY); } } if (!formFound) { Assert.fail("The login form was not found."); } // The login for was found, so let's now POST the form to authenticate our session. PostMethod post = new PostMethod(adminUrl + "j_security_check"); post.setRequestBody(new NameValuePair[]{ new NameValuePair("j_username", "admin"), new NameValuePair("j_password", "") }); post.getParams().setCookiePolicy(CookiePolicy.RFC_2109); int statusCode = client.executeMethod(post); if (statusCode == 302) { Header locationHeader = post.getResponseHeader("location"); if (locationHeader != null) { Assert.assertTrue(locationHeader.getValue().startsWith(this.adminUrl)); } else { Assert.fail("Failed to login: no redirect header"); } } else if (statusCode != HttpStatus.SC_OK) { Assert.fail("Login failed: " + post.getStatusLine() + ": " + statusCode); } } /** * This method uses the AMX API to get the install directory, then checks to * see if the admin console directory is present. * @return */ protected boolean checkForAdminConsoleDirectory() { // Hard-coding "../glassfish" to help cover a deficiency in IPS File directory = new File(this.getDomainRoot().getInstallDir() + GLASSFISH_DIR + CONSOLE_DIR_PATH); return directory.exists(); } @AfterTest public void shutdownClient() { client = null; } /** * This method will request the specified URL and examine the response for the * needle specified. * @param url * @param needle * @return * @throws java.lang.Exception */ protected boolean getUrlAndTestForStrings(String url, String... needles) throws IOException { String haystack = getUrl(url); boolean allFound = true; for (String needle : needles) { if (haystack.indexOf(needle) == -1) { allFound = false; } } return allFound; } /** * Request the specified URL and return the contents as a String * @param url * @return * @throws java.io.IOException */ protected String getUrl(String url) throws IOException { GetMethod get = new GetMethod(url); get.getParams().setCookiePolicy(CookiePolicy.RFC_2109); get.setFollowRedirects(true); int statusCode = client.executeMethod(get); //Also accepts SC_ACCPTED ie 202 for the case when the console is still loading. if ((statusCode != HttpStatus.SC_OK) && (statusCode != HttpStatus.SC_ACCEPTED) ) { Assert.fail("BaseAdminConsoleTest.getUrlAndTestForString() failed. HTTP Status Code: " + statusCode); } String response = getString(get.getResponseBodyAsStream()); get.releaseConnection(); return response; } /** * Read the entire contents of the InputStream and return them as a String * @param in * @return * @throws java.io.IOException */ protected String getString(InputStream in) throws IOException { StringBuilder out = new StringBuilder(); byte[] b = new byte[4096]; for (int n; (n = in.read(b)) != -1;) { out.append(new String(b, 0, n)); } in.close(); return out.toString(); } /* * These methods were all copied from Lloyd's AMX QL tests. */ protected DomainRoot getDomainRoot() { return mDomainRoot; } protected DomainRoot _getDomainRoot(final MBeanServerConnection conn) throws MalformedURLException, IOException, java.net.MalformedURLException { final ObjectName domainRootObjectName = AMXGlassfish.DEFAULT.bootAMX(conn); final DomainRoot domainRoot = ProxyFactory.getInstance(conn).getDomainRootProxy(); return domainRoot; } private MBeanServerConnection _getMBeanServerConnection() throws MalformedURLException, IOException { // service:jmx:rmi:///jndi/rmi://192.168.1.8:8686/jmxrmi // service:jmx:jmxmp://localhost:8888 // CHANGE to RMI once it's working // // final String urlStr = "service:jmx:jmxmp://" + mHost + ":" + mPort; final String urlStr = "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi"; final JMXServiceURL url = new JMXServiceURL(urlStr); final JMXConnector jmxConn = JMXConnectorFactory.connect(url); final MBeanServerConnection conn = jmxConn.getMBeanServerConnection(); conn.getDomains(); // sanity check return conn; } }