/*
* Copyright 2005-2010 Ignis Software Tools Ltd. All rights reserved.
*/
package jsystem.treeui.client;
import java.io.File;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import jsystem.framework.FrameworkOptions;
import jsystem.framework.JSystemProperties;
import jsystem.framework.report.ListenerstManager;
import jsystem.framework.report.Reporter;
import jsystem.framework.scenario.Scenario;
import jsystem.framework.scenario.ScenariosManager;
import jsystem.framework.sut.SutFactory;
import jsystem.runner.agent.ProjectComponent;
import jsystem.runner.agent.clients.JSystemAgentClient;
import jsystem.runner.agent.server.RunnerEngine;
import jsystem.runner.agent.server.RunnerEngineImpl;
import jsystem.runner.projectsync.ProjectZip;
import jsystem.treeui.WaitDialog;
import jsystem.treeui.actionItems.SaveScenarioAction;
import jsystem.treeui.images.ImageCenter;
import jsystem.utils.ProgressNotifier;
import jsystem.utils.StringUtils;
/**
* Extension of the {@link JSystemAgentClient} class which which makes needed adjustments to manage and control a remote agent using the
* runner.<br>
*
* @author goland
*/
public class RemoteAgentClient extends JSystemAgentClient {
private static Logger log = Logger.getLogger(RemoteAgentClient.class.getName());
/**
* agent synchronization enum
*/
public enum SyncOptions {
yes, no, compare, askUser
}
/**
* Instance of {@link RunnerEngineImpl} for operations that are common to both scenario studio and runner engine.
*/
private RunnerEngineImpl runnerEngine;
public RemoteAgentClient(String url) throws Exception {
super(url);
runnerEngine = new RunnerEngineImpl();
}
@Override
public void run() throws Exception {
run(SyncOptions.askUser);
}
/**
* Runs selected scenario with selected sut of the automation project which is currently active in runner client application.<br>
*
* Performs the following functionality:<br>
* 1. Signals remote agent to change active automation project to the active automation project in runner client application.<br>
* 2. Compares the md5 of the various automation project components of the local automation project and the remote automation project.<br>
* 3. Packs in a zip file the local project components which are not identical to corresponding components in remote agent. 4. Transfers
* zip file to agent and signals the agent to extract the zip.<br>
* 5. Sets active sut to currently selected sut in runner client application.<br>
* 6. Sets active scenario to currently selected scenario in runner client application.<br>
* 7. Signals agent to run scenario.
*/
public void run(SyncOptions sync) throws Exception {
WaitDialog.launchWaitDialog("Initializing run", null);
try {
int res = 0;
if (SyncOptions.askUser.equals(sync)) {
res = JOptionPane.showOptionDialog(null, "Press yes to copy local project to agent.", "Project synchronization",
JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE,
ImageCenter.getInstance().getImage(ImageCenter.ICON_INFO), new String[] { "Yes", "No" }, "No");
} else if (SyncOptions.no.equals(sync)) {
res = 1;
}
syncAgentsWithLocalProject(new JSystemAgentClient[] { this }, res == 0 ? true : false, new RemoteAgentClientNotifier(), true);
} finally {
WaitDialog.endWaitDialog();
}
// run
getMbeanProxy().run();
report.report("Agent was signaled to run");
}
@Override
public void initReporters() {
super.initReporters();
runnerEngine.initReporters();
RunnerEngine[] engines = JSystemAgentClientsPool.getClients(null);
for (RunnerEngine engine : engines) {
if (engine.getConnectionState().equals(ConnectionState.connected)) {
engine.initReporters();
} else {
log.fine(engine.getId() + " is disconnected. skipping activation");
}
}
}
/**
* Sets active scenario in remote agent.
*
* @see RunnerEngine#setActiveScenario(Scenario)
*/
@Override
public void setActiveScenario(Scenario scenario) throws Exception {
runnerEngine.setActiveScenario(scenario);
}
/**
* Changes project only on local project.<br>
* Remote project is changes when playing the scenario.
*/
@Override
public void changeProject(String projectName) throws Exception {
runnerEngine.changeProject(projectName);
}
@Override
public void changeSut(String sutFile) throws Exception {
runnerEngine.changeSut(sutFile);
super.changeSut(sutFile);
}
/**
* performs refresh operation on local environment and signals agent to refresh engine environment.
*
* @see RunnerEngine#refresh()
*/
@Override
public void refresh() throws Exception {
runnerEngine.refresh();
super.refresh();
}
/**
*
*/
public static void syncAgentsWithLocalProject(JSystemAgentClient[] clients, boolean loadProjectZip, ProgressNotifier notifier,
boolean haltOnError) throws Exception {
int progress = 1;
if (notifier == null) {
return;
}
if (ScenariosManager.isDirty()) {
notifier.notifyProgress("Saving scenario ", progress += 3);
SaveScenarioAction.getInstance().saveCurrentScenario();
}
String projectClasses = JSystemProperties.getInstance().getPreference(FrameworkOptions.TESTS_CLASS_FOLDER);
String currentScenario = ScenariosManager.getInstance().getCurrentScenario().getName();
String sutFile = SutFactory.getInstance().getSutInstance().getSetupName();
int[] selectedTests = ScenariosManager.getInstance().getCurrentScenario().getEnabledTestsIndexes();
File zippedProject = null;
if (loadProjectZip) {
notifier.notifyProgress("Zipping local project ", progress += 3);
ProjectZip zipper = new ProjectZip(new File(projectClasses));
zippedProject = zipper.zipProject(ProjectComponent.values());
notifier.notifyProgress("Finished Zipping local project ", progress += 3);
}
notifier.notifyProgress("Starting synchronization ", progress += 3);
for (JSystemAgentClient client : clients) {
if (client != null) {
if (client.getConnectionState() == ConnectionState.connected) {
try {
client.setNotifier(notifier);
client.synchronizeProject(zippedProject, ProjectZip.getProjectNameFromClassesPath(new File(projectClasses)),
currentScenario, sutFile, selectedTests, JSystemProperties.getInstance().getPreferences());
} catch (Throwable t) {
notifier.notifyProgress("Failed synchronizing " + client.getId(), progress);
notifier.notifyProgress(StringUtils.getStackTrace(t), progress);
if (haltOnError) {
throw new Exception(t);
}
}
notifier.notifyProgress("Ended synchronizing " + client.getId(), progress += 3);
} else {
notifier.notifyProgress("no connection to " + client.getId() + " skipping synchronization", progress += 3);
}
}
}
}
public static void syncAgentsWithLocalProject(JSystemAgentClient[] clients, boolean loadProjectZip, boolean haltOnError)
throws Exception {
Reporter report = ListenerstManager.getInstance();
if (ScenariosManager.isDirty()) {
report.report("Saving scenario ");
SaveScenarioAction.getInstance().saveCurrentScenario();
}
String projectClasses = JSystemProperties.getInstance().getPreference(FrameworkOptions.TESTS_CLASS_FOLDER);
String currentScenario = ScenariosManager.getInstance().getCurrentScenario().getName();
String sutFile = SutFactory.getInstance().getSutInstance().getSetupName();
int[] selectedTests = ScenariosManager.getInstance().getCurrentScenario().getEnabledTestsIndexes();
File zippedProject = null;
if (loadProjectZip) {
report.report("Zipping local project ");
ProjectZip zipper = new ProjectZip(new File(projectClasses));
zippedProject = zipper.zipProject(ProjectComponent.values());
report.report("Finished Zipping local project ");
}
report.report("Starting synchronization ");
for (JSystemAgentClient client : clients) {
if (client != null) {
if (client.getConnectionState() == ConnectionState.connected) {
try {
client.synchronizeProject(zippedProject, ProjectZip.getProjectNameFromClassesPath(new File(projectClasses)),
currentScenario, sutFile, selectedTests, JSystemProperties.getInstance().getPreferences());
} catch (Throwable t) {
report.report("Failed synchronizing " + client.getId());
report.report(StringUtils.getStackTrace(t));
if (haltOnError) {
throw new Exception(t);
}
}
report.report("Ended synchronizing " + client.getId());
} else {
report.report("no connection to " + client.getId() + " skipping synchronization");
}
}
}
}
class RemoteAgentClientNotifier implements ProgressNotifier {
@Override
public void done() {
}
@Override
public void notifyProgress(String message, int progress) {
report.report(message);
}
}
}