/*
* Copyright 2008 Google Inc.
*
* 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 com.google.jstestdriver;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.google.jstestdriver.SlaveBrowser.CommandResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.util.List;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author jeremiele@google.com (Jeremie Lenfant-Engelmann)
*/
public class CommandServlet extends HttpServlet {
private static final long serialVersionUID = 7210927357890630427L;
private static final Logger LOGGER = LoggerFactory.getLogger(CommandServlet.class);
private final Gson gson = new Gson();
private final CapturedBrowsers capturedBrowsers;
private final URLTranslator urlTranslator;
private final URLRewriter urlRewriter;
private final ForwardingMapper forwardingMapper;
public CommandServlet(CapturedBrowsers browsers, URLTranslator urlTranslator,
URLRewriter urlRewriter, ForwardingMapper forwardingMapper) {
this.capturedBrowsers = browsers;
this.urlTranslator = urlTranslator;
this.urlRewriter = urlRewriter;
this.forwardingMapper = forwardingMapper;
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
if (req.getParameter("listBrowsers") != null) {
resp.getWriter().write(listBrowsers());
} else if (req.getParameter("nextBrowserId") != null) {
resp.getWriter().write(capturedBrowsers.getUniqueId());
} else {
streamResponse(req.getParameter("id"), resp.getWriter());
}
resp.getWriter().flush();
}
private CommandResponse getResponse(SlaveBrowser browser) {
CommandResponse cmdResponse = null;
while (cmdResponse == null) {
if (!browser.isAlive()) {
SlaveBrowser deadBrowser = capturedBrowsers.getBrowser(browser.getId());
capturedBrowsers.removeSlave(browser.getId());
Response response = new Response();
response.setBrowser(deadBrowser.getBrowserInfo());
response.setResponse(
gson.toJson(
new BrowserPanic(deadBrowser.getBrowserInfo())));
response.setType(BrowserPanic.TYPE_NAME);
return new CommandResponse(response, true);
}
cmdResponse = browser.getResponse();
}
return cmdResponse;
}
private void substituteBrowserInfo(CommandResponse cmdResponse) {
Response response = cmdResponse.getResponse();
SlaveBrowser slaveBrowser =
capturedBrowsers.getBrowser(response.getBrowser().getId().toString());
if (slaveBrowser != null) {
response.setBrowser(slaveBrowser.getBrowserInfo());
} else {
BrowserInfo nullBrowserInfo = new BrowserInfo();
nullBrowserInfo.setId(response.getBrowser().getId());
nullBrowserInfo.setName("unknown browser");
nullBrowserInfo.setVersion("unknown version");
nullBrowserInfo.setOs("unknown os");
response.setBrowser(nullBrowserInfo);
}
cmdResponse.setResponse(response);
}
public void streamResponse(String id, PrintWriter writer) {
SlaveBrowser browser = capturedBrowsers.getBrowser(id);
CommandResponse cmdResponse = getResponse(browser);
substituteBrowserInfo(cmdResponse);
StreamMessage response =
new StreamMessage(cmdResponse.isLast(), cmdResponse.getResponse());
writer.write(gson.toJson(response));
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
service(req.getParameter("id"), req.getParameter("data"));
}
public String listBrowsers() {
return gson.toJson(capturedBrowsers.getBrowsers());
}
public void service(String id, String data) {
SlaveBrowser browser = capturedBrowsers.getBrowser(id);
data = translateUrls(data);
browser.createCommand(data);
}
private String translateUrls(String data) {
JsonCommand command = gson.fromJson(data, JsonCommand.class);
if (command.getCommand().equals(JsonCommand.CommandType.LOADTEST.getCommand())) {
List<String> parameters = command.getParameters();
String fileSourcesList = parameters.get(0);
List<FileSource> fileSources =
gson.fromJson(fileSourcesList, new TypeToken<List<FileSource>>() {}.getType());
for (FileSource fileSource : fileSources) {
String fileSrc = fileSource.getFileSrc();
if (fileSrc.startsWith("http://") || fileSrc.startsWith("https://")) {
String url = urlRewriter.rewrite(fileSource.getFileSrc());
if (url.startsWith("http://") || url.startsWith("https://")) {
String translation = urlTranslator.getTranslation(url);
if (translation == null) {
try {
urlTranslator.translate(url);
translation = urlTranslator.getTranslation(url);
forwardingMapper.addForwardingMapping(translation, url);
} catch (MalformedURLException e) {
LOGGER.warn("Could not translate URL: " + url
+ " fallback to default URL, things will probably start to act weird...", e);
translation = url;
}
}
fileSource.setBasePath(url);
fileSource.setFileSource(translation);
} else {
fileSource.setBasePath(url);
fileSource.setFileSource(url);
}
}
}
parameters.remove(0);
parameters.add(0, gson.toJson(fileSources));
return gson.toJson(command);
}
return data;
}
}