/* * Sakuli - Testing and Monitoring-Tool for Websites and common UIs. * * Copyright 2013 - 2015 the original author or authors. * * 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.sakuli.starter.helper; import net.sf.sahi.Proxy; import net.sf.sahi.config.Configuration; import org.apache.commons.io.Charsets; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; import org.sakuli.datamodel.properties.SahiProxyProperties; import org.sakuli.exceptions.SakuliInitException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; /** * Starts the proxy like {@code <sahi-installation-folder>/bin/sakuli_proxy.sh} */ @Component public class SahiProxy { public static final String SAHI_INJECT_END = "<!--SAHI_INJECT_END-->"; public static final String SAKULI_INJECT_SCRIPT_TAG = "<script src='/_s_/spr/sakuli/inject.js'></script>"; //static fields for property names protected final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private SahiProxyProperties props; private Proxy sahiProxy; /** * see {@link #startProxy(boolean)} with parameter true. */ public void startProxy() throws SakuliInitException, FileNotFoundException { startProxy(true); } /** * Starts a seperate Thread for the sahi proxy. * You can do a shutdown with * * @param asyncron init if a separate thread should started * @throws SakuliInitException if the specified files in the sahi.properties are not valid */ public void startProxy(boolean asyncron) throws SakuliInitException, FileNotFoundException { sahiProxy = new Proxy(props.getProxyPort()); if (Files.exists(props.getSahiHomeFolder()) && Files.exists(props.getSahiConfigFolder())) { logger.info("START Sahi-PROXY: Sahi-Home folder '{}', Sahi-Configuration folder '{}'", props.getSahiHomeFolder().toAbsolutePath().toString(), props.getSahiConfigFolder().toAbsolutePath().toString() ); try { injectCustomJavaScriptFiles(); //set the custom paths to the sahi environment Configuration.init(props.getSahiHomeFolder().toAbsolutePath().toString(), props.getSahiConfigFolder().toAbsolutePath().toString()); Configuration.setUnmodifiedTrafficLogging(false); Configuration.setModifiedTrafficLogging(false); //Starts the sahi proxy as asynchron Thread sahiProxy.start(asyncron); Thread.sleep(200); } catch (RuntimeException e) { logger.error("RUNTIME EXCEPTION"); throw new SakuliInitException(e); } catch (Throwable e) { logger.error("THROWABLE EXCEPTION"); throw new SakuliInitException(e.getMessage()); } } else { throw new FileNotFoundException("the path to '" + SahiProxyProperties.PROXY_HOME_FOLDER + "=" + props.getSahiHomeFolder().toAbsolutePath().toString() + "' or '" + SahiProxyProperties.PROXY_CONFIG_FOLDER + "=" + props.getSahiConfigFolder().toAbsolutePath().toString() + "' is not valid, please check the properties files!"); } } protected void injectCustomJavaScriptFiles() throws IOException { File injectFile = props.getSahiJSInjectConfigFile().toFile(); String injectFileString = FileUtils.readFileToString(injectFile, Charsets.UTF_8); if (!injectFileString.contains(SAKULI_INJECT_SCRIPT_TAG)) { injectFileString = StringUtils.replace(injectFileString, SAHI_INJECT_END, SAKULI_INJECT_SCRIPT_TAG + "\r\n" + SAHI_INJECT_END); FileUtils.writeStringToFile(injectFile, injectFileString, Charsets.UTF_8); logger.info("added '{}' to Sahi inject config file '{}'", SAKULI_INJECT_SCRIPT_TAG, props.getSahiJSInjectConfigFile().toString()); } Path source = props.getSahiJSInjectSourceFile(); Path target = props.getSahiJSInjectTargetFile(); if (isNewer(source, target)) { FileUtils.copyFile(source.toFile(), target.toFile(), false); logger.info("copied file '{}' to target '{}'", source.toString(), target.toString()); } } private boolean isNewer(Path source, Path target) { return !Files.exists(target) || FileUtils.isFileNewer(source.toFile(), target.toFile()); } public void shutdown() throws SakuliInitException { logger.debug("SHUTDOWN SAHI-Proxy now!"); sahiProxy.stop(); if (!sahiProxy.isRunning()) { logger.info("SHUTDOWN SAHI-Proxy SUCCESSFULLY"); } else { throw new SakuliInitException("SAHI-Proxy failed to Shutdown!"); } } }