package cz.cuni.mff.d3s.been.web.pages.runtime;
import cz.cuni.mff.d3s.been.api.CommandTimeoutException;
import cz.cuni.mff.d3s.been.api.BeenApiException;
import cz.cuni.mff.d3s.been.core.protocol.command.CommandEntry;
import cz.cuni.mff.d3s.been.core.protocol.command.CommandEntryState;
import cz.cuni.mff.d3s.been.core.ri.*;
import cz.cuni.mff.d3s.been.core.task.TaskEntry;
import cz.cuni.mff.d3s.been.web.components.Layout;
import cz.cuni.mff.d3s.been.web.model.TaskWrkDirChecker;
import cz.cuni.mff.d3s.been.web.pages.Page;
import org.apache.tapestry5.Asset;
import org.apache.tapestry5.Block;
import org.apache.tapestry5.annotations.Environmental;
import org.apache.tapestry5.annotations.InjectComponent;
import org.apache.tapestry5.annotations.Path;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.corelib.components.Zone;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.ajax.AjaxResponseRenderer;
import org.apache.tapestry5.services.javascript.JavaScriptSupport;
import java.util.*;
/**
* This page is used to display information about host runtime and to resolve problems
* on this host runtime
*
* @author Kuba Brecka, donarus
*/
@Page.Navigation(section = Layout.Section.RUNTIME_DETAIL)
public class Detail extends Page {
// -----------------
// INJECTED SERVICES
// -----------------
/**
* Used to update zones returned from ajax link callbacks.
*/
@Inject
private AjaxResponseRenderer ajaxResponseRenderer;
@Environmental
private JavaScriptSupport javaScriptSupport;
// --------------
// OTHER SERVICES
// --------------
/**
* Initialized in onActivate method
*/
@Property
private TaskWrkDirChecker taskWrkDirChecker;
// ---------------
// LOOP PROPERTIES
// ---------------
/**
* property for loop through CPUs
*/
@Property
private Cpu cpu;
/**
* property for loop through network interfaces
*/
@Property
private NetworkInterface networkInterface;
/**
* property for loop through file systems
*/
@Property
private Filesystem filesystem;
/**
* property for loop through all (used or unused task directories)
*/
@Property
private String taskDir;
/**
* property for loop through all unused task directories (from failed tasks)
*/
@Property
private String oldTaskWrkDir;
/**
* property for loop through tasks on underlying runtime
*/
@Property
private TaskEntry task;
/**
* property for loop through command entries for this runtime
*/
@Property
private CommandEntry commandEntry;
/**
* property for loop through interfaces of sample monitor
*/
@Property
private NetworkSample monitorInterface;
/**
* property for loop through file systems of monitor sample
*/
@Property
private FilesystemSample monitorFilesystem;
/**
* index property for loop through old task working directories (used to identify correct zone which
* will be returned from "delete old task working directory" ajax link callback.
*/
@Property
private int zoneIdIndex;
// ----------------
// RENDERED OBJECTS
// ----------------
/**
* displayed runtime
*/
@Property
private RuntimeInfo runtime;
// ------------------------------
// ZONES AND BLOCKS FOR INJECTION
// ------------------------------
/**
* Zone with loop of commandHistory
*/
@InjectComponent
private Zone commandHistoryZone;
/**
* Zone with task count
*/
@InjectComponent
private Zone taskCountZone;
/**
* "Old task working directory has been deleted" block
*/
@Inject
private Block deletedBlock;
/**
* "Old task working directory deletion has timeouted" block
*/
@Inject
private Block timeoutedBlock;
/**
* Block with task list
*/
@Inject
private Block taskListBlock;
/**
* "Old task working directory deletion has failed" block
*/
@Inject
private Block errorBlock;
// ------
// ASSETS
// ------
@Inject
@Path("context:img/ajax-loader.gif")
private Asset spinner;
@Property
private String runtimeId;
// -------------------
// PAGE INITIALIZATION
// -------------------
/**
* Initialize displayed runtime. See official tapestry documentation for more info
* about conventions and page initialization.
*
* @param runtimeId id of displayed runtime
*/
void onActivate(String runtimeId) throws BeenApiException {
this.runtimeId = runtimeId;
runtime = api.getApi().getRuntime(runtimeId);
taskWrkDirChecker = new TaskWrkDirChecker(api.getApi());
}
/**
* Return value will be added to all links to this page rendered on this page. See official
* tapestry documentation for more info about conventions.
*
* @return ID of displayed runtime
*/
Object onPassivate() {
return runtimeId;
}
/**
* Prepare page for rendering - add loading spinner to all links with html class attribute ".progress_on_click"
*/
public void setupRender() {
super.setupRender();
javaScriptSupport.addScript(
" $(document).on(Tapestry.TRIGGER_ZONE_UPDATE_EVENT, '.progress_on_click', function() {\n" +
" $(this).after('<img src=\\\"" + spinner.toClientURL() + "\\\"/>');\n" +
" jQuery(this).hide();\n" +
" });");
}
// -------------------
// AJAX LINK CALLBACKS
// -------------------
/**
* Callback for "delete old task working directory" ajax link.
* <br/><br/>
* timeout: 30s
* <br/> Updates correct zone through {@link AjaxResponseRenderer} with correct block ({@link Detail#deletedBlock}
* if directory has been deleted, {@link Detail#errorBlock} if deletion has failed and {@link Detail#timeoutedBlock}
* if deletion has timeouted)
*
* @param oldTaskWorkingDir task directory which should be deleted
* @param zoneIndex index of the zone which should be updated after this callback
*/
public void onActionFromDeleteOldTaskWrkDir(String oldTaskWorkingDir, int zoneIndex) throws BeenApiException {
this.oldTaskWrkDir = oldTaskWorkingDir;
// create request for delete operation
try {
CommandEntry entry = api.getApi().deleteTaskWrkDirectory(runtime.getId(), oldTaskWorkingDir);
if (entry.getState() == CommandEntryState.FAILED) {
ajaxResponseRenderer.addRender("oldTaskWrkDirDeleteZone_" + zoneIndex, errorBlock);
} else {
ajaxResponseRenderer.addRender("oldTaskWrkDirDeleteZone_" + zoneIndex, deletedBlock);
}
} catch (CommandTimeoutException e) {
ajaxResponseRenderer.addRender("oldTaskWrkDirDeleteZone_" + zoneIndex, timeoutedBlock);
}
ajaxResponseRenderer.addRender("commandHistoryZone", commandHistoryZone.getBody());
}
public String getSubdirName(String fullPath) {
int slashPos = fullPath.lastIndexOf("/");
if (slashPos <= 0) {
slashPos = fullPath.lastIndexOf("\\");
}
if (slashPos < 0) {
slashPos = 0;
}
return fullPath.substring(slashPos +1);
}
/**
* Delete ajax link callback from delete link in {@link Detail#errorBlock}
* see {@link Detail#onActionFromDeleteOldTaskWrkDir(String, int)}
*
* @param oldTaskWorkingDir task directory which should be deleted
* @param zoneIndex index of the zone which should be updated after this callback
*/
public void onActionFromDeleteOldTaskWrkDir_failed(String oldTaskWorkingDir, int zoneIndex) throws BeenApiException {
onActionFromDeleteOldTaskWrkDir(oldTaskWorkingDir, zoneIndex);
}
/**
* Delete ajax link callback from delete link in {@link Detail#timeoutedBlock}
* see {@link Detail#onActionFromDeleteOldTaskWrkDir(String, int)}
*
* @param oldTaskWorkingDir task directory which should be deleted
* @param zoneIndex index of the zone which should be updated after this callback
*/
public void onActionFromDeleteOldTaskWrkDir_timeouted(String oldTaskWorkingDir, int zoneIndex) throws BeenApiException {
onActionFromDeleteOldTaskWrkDir(oldTaskWorkingDir, zoneIndex);
}
public void onActionFromShowTasksLink() {
ajaxResponseRenderer.addRender(taskCountZone.getClientId(), taskListBlock);
}
public void onActionFromHideTasksLink() {
ajaxResponseRenderer.addRender(taskCountZone.getClientId(), taskCountZone.getBody());
}
// ----------------------------------
// TAPESTRY TEMPLATE PROPERTY GETTERS
// ----------------------------------
/**
* Collects history of command entries for underlying runtime.
*
* @return The command history, in the form of a collection of command entries
*/
public Collection<CommandEntry> getCommandEntries() throws BeenApiException {
return api.getApi().listCommandEntries(runtime.getId());
}
/**
* Collect information about tasks on this runtime.
*
* @return The collection of task entries, representing the current state of tasks on this Host Runtime
*/
public Collection<TaskEntry> getTasks() throws BeenApiException {
return api.getApi().listTasks(runtime.getId());
}
}