|  | /* | 
|  | * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved. | 
|  | * | 
|  | * This program and the accompanying materials are made available under the | 
|  | * terms of the Eclipse Public License v. 2.0, which is available at | 
|  | * http://www.eclipse.org/legal/epl-2.0. | 
|  | * | 
|  | * This Source Code may also be made available under the following Secondary | 
|  | * Licenses when the conditions for such availability set forth in the | 
|  | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, | 
|  | * version 2 with the GNU Classpath Exception, which is available at | 
|  | * https://www.gnu.org/software/classpath/license.html. | 
|  | * | 
|  | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | 
|  | */ | 
|  |  | 
|  | 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; | 
|  | } | 
|  | } | 
|  |  |