/******************************************************************************* * Copyright (c) 2006-2010 eBay Inc. All Rights Reserved. * 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 *******************************************************************************/ package org.ebayopensource.turmeric.runtime.tests.common.jetty; import static org.hamcrest.Matchers.*; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.net.URL; import java.net.URLClassLoader; import java.util.List; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.SystemUtils; import org.ebayopensource.turmeric.junit.rules.TestingDir; import org.ebayopensource.turmeric.junit.utils.MavenTestingUtils; import org.ebayopensource.turmeric.runtime.sif.service.Service; import org.ebayopensource.turmeric.runtime.sif.service.ServiceFactory; import org.ebayopensource.turmeric.runtime.tests.common.AbstractTurmericTestCase; import org.jaxen.XPath; import org.jaxen.jdom.JDOMXPath; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import org.jdom.output.XMLOutputter; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Rule; import com.ebay.kernel.logger.Logger; public abstract class AbstractWithSlowProxyServerTest extends AbstractTurmericTestCase { protected static SimpleJettyServer jetty; protected static SimpleJettyProxyServer proxyServer; protected static URI serverUri; protected static URI proxyUri; protected Logger logger = Logger.getInstance("AbstractWithSlowProxyServerTest"); @Rule public TestingDir testingdir = new TestingDir(); @BeforeClass public static void startServers() throws Exception { // Setup Real Server. jetty = new SimpleJettyServer(); jetty.start(); serverUri = jetty.getSPFURI(); // Setup Transparent Proxy Server to Real Server. proxyServer = new SimpleJettyProxyServer(jetty.getServerURI()); IntentionalDelayHandler slowserver = new IntentionalDelayHandler(); slowserver.setDelay(3000); proxyServer.wrapHandlers(slowserver); proxyServer.start(); proxyUri = proxyServer.getServerURI(); } @AfterClass public static void stopServer() throws Exception { jetty.stop(); proxyServer.stop(); } private Document parseXml(URL url) throws IOException, JDOMException { InputStream in = null; try { in = url.openStream(); SAXBuilder builder = new SAXBuilder(false); return builder.build(in); } finally { IOUtils.closeQuietly(in); } } private void writeXml(File file, Document doc) throws IOException { FileWriter writer = null; try { writer = new FileWriter(file); XMLOutputter serializer = new XMLOutputter(); serializer.getFormat().setIndent(" "); serializer.getFormat().setLineSeparator(SystemUtils.LINE_SEPARATOR); serializer.output(doc, writer); } finally { IOUtils.closeQuietly(writer); } } /** * Create a proxied service that uses the embedded jetty proxy server + embedded jetty SPF server. * <p> * The process here is: * <p> * <ol> * <li>Read the raw ClientConfig.xml as specified by the clientName parameter</li> * <li>Updates the <code>PROXY_HOST</code> and <code>PROXY_PORT</code> values present in the raw ClientConfig.xml</li> * <li>Write the modified ClientConfig.xml back out to a test specific directory ( * <code>target/tests/{testClassName}/{testMethodName}/res/</code>) using the path * <code>META-INF/soa/client/config/{clientName}_modified/ClientConfig.xml</code></li> * <li>Using a test local classloader, and the {@link ServiceFactory#create(String, String, URL)} method to load the * modified ClientConfig.xml to create a {@link Service} suitable for talking to the embedded jetty proxy server.</li> * </ol> * * @param serviceAdminName * the service admin name. * @param clientName * the client name. * @return */ protected Service createProxiedService(String serviceAdminName, String clientName) throws Exception { // Read/Parse baseline ClientConfig.xml String rawConfigPath = String.format( "META-INF/soa/client/config/%s/ClientConfig.xml", clientName); URL rawConfigUrl = ClassLoader.getSystemResource(rawConfigPath); Assert.assertThat("Unable to find config resource: " + rawConfigPath, rawConfigUrl, notNullValue()); Document doc = parseXml(rawConfigUrl); // Modify the PROXY_HOST and PROXY_PORT to point to embedded jetty server XPath expression = new JDOMXPath( "//e:default-options/e:other-options/e:option"); expression.addNamespace("e", "http://www.ebayopensource.org/turmeric/common/config"); // Navigator navigator = expression.getNavigator(); @SuppressWarnings("unchecked") List<Element> nodes = expression.selectNodes(doc); for (Element elem : nodes) { String optName = elem.getAttributeValue("name").trim(); if ("PROXY_HOST".equals(optName)) { elem.setText(proxyUri.getHost()); } else if ("PROXY_PORT".equals(optName)) { elem.setText(String.valueOf(proxyUri.getPort())); } } // Write modified document out to target directory File testingResourceDir = new File(testingdir.getDir(), "res"); MavenTestingUtils.ensureEmpty(testingResourceDir); String modifiedConfigPath = String.format( "META-INF/soa/client/config/%s_modified/ClientConfig.xml", clientName); File outputFile = new File(testingResourceDir, modifiedConfigPath); MavenTestingUtils.ensureDirExists(outputFile.getParentFile()); System.out.println("Writing modified ClientConfig to " + outputFile.getAbsolutePath()); writeXml(outputFile, doc); // Let ServiceFactory create service from modified ClientConfig.xml URL urls[] = new URL[] { testingResourceDir.toURI().toURL() }; URLClassLoader testingSpecificCL = new URLClassLoader(urls, this .getClass().getClassLoader()); ClassLoader original = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(testingSpecificCL); return ServiceFactory.create(serviceAdminName, clientName + "_modified", null); } finally { Thread.currentThread().setContextClassLoader(original); } } }