Message boards : API : GUI RPC for Java
Message board moderation
Author | Message |
---|---|
Send message Joined: 19 Jan 07 Posts: 1179 |
Would anybody be interested on a Java library to do GUI RPCs? You could make a BOINC Manager clone in Java, or do some standalone apps for useful things that you can't do on the manager, like aborting a lot of tasks. If there is interest, I'll bump it up on my (big) to-do list (I have already started; I'm just adjusting priorities on my dozen half-done projects). |
Send message Joined: 19 Dec 07 Posts: 5 |
Hi Nicolas, i am interested. What would you do: 1. a wrapper (GUI) for the command line version of boinc, or 2. a java application which communicate via (XML ?) rpc calls with boinc. Is there any public information/specification for this interface? ------------ Rechenaugust Would anybody be interested on a Java library to do GUI RPCs? You could make a BOINC Manager clone in Java, or do some standalone apps for useful things that you can't do on the manager, like aborting a lot of tasks. |
Send message Joined: 19 Jan 07 Posts: 1179 |
Hi Nicolas, Communicating via XML directly. Using boinc_cmd would be an abuse... The protocol isn't documented. You'd need to go to the C++ code and figure it out. Which isn't easy, since all elements are 1:1 XML dumps of the internal structures. |
Send message Joined: 19 Dec 07 Posts: 5 |
Hi Nicolas, I used "WireShark" to listen to the communication. Now i am testing my first BoincSocket.class... Authentication seems to work. The first source code will follow in a few days. ------------ Rechenaugust |
Send message Joined: 7 Mar 08 Posts: 5 |
Java web service bindings would be great, then we could have a full featured BOINC web manager. |
Send message Joined: 19 Jan 07 Posts: 1179 |
Java web service bindings would be great, then we could have a full featured BOINC web manager. I never said anything about web services. You don't need a web service binding to make a web-based manager, btw; web services are used for 100 times more things than they should be used due to pure hype :) |
Send message Joined: 7 Mar 08 Posts: 5 |
Java web service bindings would be great, then we could have a full featured BOINC web manager. Yeah you do have a point ... but if there existed web services for BOINC especially to handle server configuration (adding daemons/apps) and for on-demand work generation, it would put BOINC further ahead of the competition. Imagine if one could install a generic BOINC server (i.e. from the trunk) and "dynamically" configure it at runtime to suit ones needs, such as adding/upgrading apps, daemons and especially creating work units. While this might not be worth the effort for your typical science application, for desktop grids which are used to "parallelize" batch files, which can be created and submitted by many trusted people, this would make things a whole lot easier. I mention web services because they are a form of RPCs that are very friendly with corporate firewalls, but any similar technology would work, e.g. CORBA. |
Send message Joined: 19 Jan 07 Posts: 1179 |
Yeah you do have a point ... but if there existed web services for BOINC especially to handle server configuration (adding daemons/apps) and for on-demand work generation, it would put BOINC further ahead of the competition. Note that I was never talking about the server at all, but about the protocol used by the BOINC Manager to talk to the core client. The server can already be automated by simply running remote commands with ssh. To "parallelize batch files", BOINC is probably the wrong tool for the job anyway; BOINC has high throughput, not low latency. |
Send message Joined: 7 Mar 08 Posts: 5 |
Yeah you do have a point ... but if there existed web services for BOINC especially to handle server configuration (adding daemons/apps) and for on-demand work generation, it would put BOINC further ahead of the competition. I do not know how far you've got with yours, but I have already written a quick and dirty one that fits the simple needs for my web application. It is still in its early stages so be warned; some of the functionality has yet to be implemented. I would appreciate any comments or additions. I do not know how to add an attachment so here it is in full. (Depends on DOM4J) import java.net.*; import java.io.*; import org.dom4j.*; import java.security.*; public class BOINCClient { private Socket socket; private OutputStreamWriter output; private InputStream input; //<client_state> //<host_info> public int timezone; public String domain_name; public String ip_addr; public String host_cpid; public int p_ncpus; public String p_vendor; public String p_model; public String p_features; public String p_fpops; public double p_iops; public double p_membw; public double p_calculated; public double m_nbytes; public double m_cache; public double m_swap; public double d_total; public double d_free; public String os_name; public String os_version; public String accelerators; //<time_stats> public double on_frac; public double connected_frac; public double active_frac; public double cpu_efficiency; public double last_update; //<net_stats> public double bwup; public double avg_up; public double avg_time_up; public double bwdown; public double avg_down; public double avg_time_down; //<project> public String master_url; public String project_name; public String symstore; public String user_name; public String team_name; public String host_venue; public String email_hash; public String cross_project_id; public double cpid_time; public double user_total_credit; public double user_expavg_credit; public double user_create_time; public int rpc_seqno; public int hostid; public double host_total_credit; public double host_expavg_credit; public double host_create_time; public int nrpc_failures; public int master_fetch_failures; public double min_rpc_time; public double next_rpc_time; public double short_term_debt; public double long_term_debt; public double resource_share; public double duration_correction_factor; public int sched_rpc_pending; public int send_time_stats_log; public int send_job_log; public double ams_resource_share; public int rr_sim_deadlines_missed; public double last_rpc_time; public double project_files_downloaded_time; public String platform_name; public int core_client_major_version; public int core_client_minor_version; public int core_client_release; //<global_preferences> public int mod_time; public boolean run_on_batteries; public boolean run_if_user_active; public double suspend_if_no_recent_input; public double start_hour; public double end_hour; public double net_start_hour; public double net_end_hour; public boolean confirm_before_connecting; public double work_buf_min_days; public double work_buf_additional_days; public int max_cpus; public double cpu_scheduling_period_minutes; public double disk_interval; public double disk_max_used_gb; public double disk_max_used_pct; public double disk_min_free_gb; public double vm_max_used_pct; public double ram_max_used_busy_pct; public double ram_max_used_idle_pct; public double idle_time_to_run; public double max_bytes_sec_up; public double max_bytes_sec_down; public double cpu_usage_limit; private static String convertToHex(byte[] data) { StringBuffer buf = new StringBuffer(); for (int i = 0; i < data.length; i++) { int halfbyte = (data[i] >>> 4) & 0x0F; int two_halfs = 0; do { if ((0 <= halfbyte) && (halfbyte <= 9)) buf.append((char) ('0' + halfbyte)); else buf.append((char) ('a' + (halfbyte - 10))); halfbyte = data[i] & 0x0F; } while(two_halfs++ < 1); } return buf.toString(); } public static String MD5(String text) { byte[] md5hash = new byte[32]; try { MessageDigest md; md = MessageDigest.getInstance("MD5"); md.update(text.getBytes("iso-8859-1"), 0, text.length()); md5hash = md.digest(); } catch(Exception ignored) {} return convertToHex(md5hash); } public enum BOINCMode { ALWAYS("<always>"), AUTO("<auto>"), NEVER("<never>"); private String mode; BOINCMode(String mode) { this.mode = mode; } @Override public String toString() { return mode; } } public BOINCClient() { } public void connect(String address, int port) throws UnknownHostException, IOException { socket = new Socket(address, port); input = socket.getInputStream(); output = new OutputStreamWriter(socket.getOutputStream(), "ISO8859_1"); } public void close() throws IOException { input.close(); output.close(); socket.close(); } public void startCommand() throws IOException { output.write("<boinc_gui_rpc_request>n"); } public void endCommand() throws IOException { output.write("</boinc_gui_rpc_request>n�03"); output.flush(); } public String read() throws IOException { StringBuilder result = new StringBuilder(); try { int value = 0; while ((value = input.read()) != -1) { if (value == '�03') break; result.append((char) value); } } catch (Exception e) { result.append(e.getMessage()); } return result.toString(); } public boolean success(String response) throws IOException { if (response == null) return false; return response.contains("<success/>"); } public boolean authorized(String response) throws IOException { if (response == null) return false; return response.contains("<authorized/>"); } public boolean authenticate(String password) throws DocumentException, IOException { startCommand(); output.write("<auth1/>n"); endCommand(); Document response = DocumentHelper.parseText(read()); String nonce = response.selectSingleNode("/boinc_gui_rpc_reply/nonce").getText(); startCommand(); output.write("<auth2>n"); output.write("<nonce_hash>" + MD5(nonce + password) + "</nonce_hash>n"); output.write("</auth2>n"); endCommand(); return authorized(read()); } public void getState() throws IOException, DocumentException { startCommand(); output.write("<get_state/>n"); endCommand(); Document document = DocumentHelper.parseText(read()); Element elHostInfo = (Element) document.selectSingleNode("//host_info"); Element elTimeStats = (Element) document.selectSingleNode("//time_stats"); Element elNetStats = (Element) document.selectSingleNode("//net_stats"); Element elProject = (Element) document.selectSingleNode("//project"); Element elPlatformName = (Element) document.selectSingleNode("//platform_name"); Element elMajorVersion = (Element) document.selectSingleNode("//core_client_major_version"); Element elMinorVersion = (Element) document.selectSingleNode("//core_client_minor_version"); Element elRelease = (Element) document.selectSingleNode("//core_client_release"); Element elGlobalPreferences = (Element) document.selectSingleNode("//global_preferences"); try { timezone = Integer.parseInt(elHostInfo.selectSingleNode("timezone").getText()); } catch (Exception e) {} try { domain_name = elHostInfo.selectSingleNode("domain_name").getText(); } catch (Exception e) {} try { ip_addr = elHostInfo.selectSingleNode("ip_addr").getText(); } catch (Exception e) {} try { host_cpid = elHostInfo.selectSingleNode("host_cpid").getText(); } catch (Exception e) {} try { p_ncpus = Integer.parseInt(elHostInfo.selectSingleNode("p_ncpus").getText()); } catch (Exception e) {} try { p_vendor = elHostInfo.selectSingleNode("p_vendor").getText(); } catch (Exception e) {} try { p_model = elHostInfo.selectSingleNode("p_model").getText(); } catch (Exception e) {} try { p_features = elHostInfo.selectSingleNode("p_features").getText(); } catch (Exception e) {} try { p_fpops = elHostInfo.selectSingleNode("p_fpops").getText(); } catch (Exception e) {} try { p_iops = Double.parseDouble(elHostInfo.selectSingleNode("p_iops").getText()); } catch (Exception e) {} try { p_membw = Double.parseDouble(elHostInfo.selectSingleNode("p_membw").getText()); } catch (Exception e) {} try { p_calculated = Double.parseDouble(elHostInfo.selectSingleNode("p_calculated").getText()); } catch (Exception e) {} try { m_nbytes = Double.parseDouble(elHostInfo.selectSingleNode("m_nbytes").getText()); } catch (Exception e) {} try { m_cache = Double.parseDouble(elHostInfo.selectSingleNode("m_cache").getText()); } catch (Exception e) {} try { m_swap = Double.parseDouble(elHostInfo.selectSingleNode("m_swap").getText()); } catch (Exception e) {} try { d_total = Double.parseDouble(elHostInfo.selectSingleNode("d_total").getText()); } catch (Exception e) {} try { d_free = Double.parseDouble(elHostInfo.selectSingleNode("d_free").getText()); } catch (Exception e) {} try { os_name = elHostInfo.selectSingleNode("os_name").getText(); } catch (Exception e) {} try { os_version = elHostInfo.selectSingleNode("os_version").getText(); } catch (Exception e) {} try { accelerators = elHostInfo.selectSingleNode("accelerators").getText(); } catch (Exception e) {} //<time_stats> try { on_frac = Double.parseDouble(elTimeStats.selectSingleNode("on_frac").getText()); } catch (Exception e) {} try { connected_frac = Double.parseDouble(elTimeStats.selectSingleNode("connected_frac").getText()); } catch (Exception e) {} try { active_frac = Double.parseDouble(elTimeStats.selectSingleNode("active_frac").getText()); } catch (Exception e) {} try { cpu_efficiency = Double.parseDouble(elTimeStats.selectSingleNode("cpu_efficiency").getText()); } catch (Exception e) {} try { last_update = Double.parseDouble(elTimeStats.selectSingleNode("last_update").getText()); } catch (Exception e) {} //<net_stats> try { bwup = Double.parseDouble(elNetStats.selectSingleNode("bwup").getText()); } catch (Exception e) {} try { avg_up = Double.parseDouble(elNetStats.selectSingleNode("avg_up").getText()); } catch (Exception e) {} try { avg_time_up = Double.parseDouble(elNetStats.selectSingleNode("avg_time_up").getText()); } catch (Exception e) {} try { bwdown = Double.parseDouble(elNetStats.selectSingleNode("bwdown").getText()); } catch (Exception e) {} try { avg_down = Double.parseDouble(elNetStats.selectSingleNode("avg_down").getText()); } catch (Exception e) {} try { avg_time_down = Double.parseDouble(elNetStats.selectSingleNode("avg_time_down").getText()); } catch (Exception e) {} //<project> try { master_url = elProject.selectSingleNode("master_url").getText(); } catch (Exception e) {} try { project_name = elProject.selectSingleNode("project_name").getText(); } catch (Exception e) {} try { symstore = elProject.selectSingleNode("symstore").getText(); } catch (Exception e) {} try { user_name = elProject.selectSingleNode("user_name").getText(); } catch (Exception e) {} try { team_name = elProject.selectSingleNode("team_name").getText(); } catch (Exception e) {} try { host_venue = elProject.selectSingleNode("host_venue").getText(); } catch (Exception e) {} try { email_hash = elProject.selectSingleNode("email_hash").getText(); } catch (Exception e) {} try { cross_project_id = elProject.selectSingleNode("cross_project_id").getText(); } catch (Exception e) {} try { cpid_time = Double.parseDouble(elProject.selectSingleNode("cpid_time").getText()); } catch (Exception e) {} try { user_total_credit = Double.parseDouble(elProject.selectSingleNode("user_total_credit").getText()); } catch (Exception e) {} try { user_expavg_credit = Double.parseDouble(elProject.selectSingleNode("user_expavg_credit").getText()); } catch (Exception e) {} try { user_create_time = Double.parseDouble(elProject.selectSingleNode("user_create_time").getText()); } catch (Exception e) {} try { rpc_seqno = Integer.parseInt(elProject.selectSingleNode("rpc_seqno").getText()); } catch (Exception e) {} try { hostid = Integer.parseInt(elProject.selectSingleNode("hostid").getText()); } catch (Exception e) {} try { host_total_credit = Double.parseDouble(elProject.selectSingleNode("host_total_credit").getText()); } catch (Exception e) {} try { host_expavg_credit = Double.parseDouble(elProject.selectSingleNode("host_expavg_credit").getText()); } catch (Exception e) {} try { host_create_time = Double.parseDouble(elProject.selectSingleNode("host_create_time").getText()); } catch (Exception e) {} try { nrpc_failures = Integer.parseInt(elProject.selectSingleNode("nrpc_failures").getText()); } catch (Exception e) {} try { master_fetch_failures = Integer.parseInt(elProject.selectSingleNode("master_fetch_failures").getText()); } catch (Exception e) {} try { min_rpc_time = Double.parseDouble(elProject.selectSingleNode("min_rpc_time").getText()); } catch (Exception e) {} try { next_rpc_time = Double.parseDouble(elProject.selectSingleNode("next_rpc_time").getText()); } catch (Exception e) {} try { short_term_debt = Double.parseDouble(elProject.selectSingleNode("short_term_debt").getText()); } catch (Exception e) {} try { long_term_debt = Double.parseDouble(elProject.selectSingleNode("long_term_debt").getText()); } catch (Exception e) {} try { resource_share = Double.parseDouble(elProject.selectSingleNode("resource_share").getText()); } catch (Exception e) {} try { duration_correction_factor = Double.parseDouble(elProject.selectSingleNode("duration_correction_factor").getText()); } catch (Exception e) {} try { sched_rpc_pending = Integer.parseInt(elProject.selectSingleNode("sched_rpc_pending").getText()); } catch (Exception e) {} try { send_time_stats_log = Integer.parseInt(elProject.selectSingleNode("send_time_stats_log").getText()); } catch (Exception e) {} try { send_job_log = Integer.parseInt(elProject.selectSingleNode("send_job_log").getText()); } catch (Exception e) {} try { ams_resource_share = Double.parseDouble(elProject.selectSingleNode("timezone").getText()); } catch (Exception e) {} try { rr_sim_deadlines_missed = Integer.parseInt(elProject.selectSingleNode("rr_sim_deadlines_missed").getText()); } catch (Exception e) {} try { last_rpc_time = Double.parseDouble(elProject.selectSingleNode("last_rpc_time").getText()); } catch (Exception e) {} try { project_files_downloaded_time = Double.parseDouble(elProject.selectSingleNode("project_files_downloaded_time").getText()); } catch (Exception e) {} try { platform_name = elProject.selectSingleNode("platform_name").getText(); } catch (Exception e) {} try { core_client_major_version = Integer.parseInt(elProject.selectSingleNode("core_client_major_version").getText()); } catch (Exception e) {} try { core_client_minor_version = Integer.parseInt(elProject.selectSingleNode("core_client_minor_version").getText()); } catch (Exception e) {} try { core_client_release = Integer.parseInt(elProject.selectSingleNode("core_client_release").getText()); } catch (Exception e) {} //<global_preferences> try { mod_time = Integer.parseInt(elGlobalPreferences.selectSingleNode("mod_time").getText()); } catch (Exception e) {} //run_on_batteries; //run_if_user_active; try { suspend_if_no_recent_input = Double.parseDouble(elGlobalPreferences.selectSingleNode("suspend_if_no_recent_input").getText()); } catch (Exception e) {} try { start_hour = Double.parseDouble(elGlobalPreferences.selectSingleNode("start_hour").getText()); } catch (Exception e) {} try { end_hour = Double.parseDouble(elGlobalPreferences.selectSingleNode("end_hour").getText()); } catch (Exception e) {} try { net_start_hour = Double.parseDouble(elGlobalPreferences.selectSingleNode("net_start_hour").getText()); } catch (Exception e) {} try { net_end_hour = Double.parseDouble(elGlobalPreferences.selectSingleNode("net_end_hour").getText()); } catch (Exception e) {} //confirm_before_connecting; try { work_buf_min_days = Double.parseDouble(elGlobalPreferences.selectSingleNode("work_buf_min_days").getText()); } catch (Exception e) {} try { work_buf_additional_days = Double.parseDouble(elGlobalPreferences.selectSingleNode("work_buf_additional_days").getText()); } catch (Exception e) {} try { max_cpus = Integer.parseInt(elGlobalPreferences.selectSingleNode("max_cpus").getText()); } catch (Exception e) {} try { cpu_scheduling_period_minutes = Double.parseDouble(elGlobalPreferences.selectSingleNode("cpu_scheduling_period_minutes").getText()); } catch (Exception e) {} try { disk_interval = Double.parseDouble(elGlobalPreferences.selectSingleNode("disk_interval").getText()); } catch (Exception e) {} try { disk_max_used_gb = Double.parseDouble(elGlobalPreferences.selectSingleNode("disk_max_used_gb").getText()); } catch (Exception e) {} try { disk_max_used_pct = Double.parseDouble(elGlobalPreferences.selectSingleNode("disk_max_used_pct").getText()); } catch (Exception e) {} try { disk_min_free_gb = Double.parseDouble(elGlobalPreferences.selectSingleNode("disk_min_free_gb").getText()); } catch (Exception e) {} try { vm_max_used_pct = Double.parseDouble(elGlobalPreferences.selectSingleNode("vm_max_used_pct").getText()); } catch (Exception e) {} try { ram_max_used_busy_pct = Double.parseDouble(elGlobalPreferences.selectSingleNode("ram_max_used_busy_pct").getText()); } catch (Exception e) {} try { ram_max_used_idle_pct = Double.parseDouble(elGlobalPreferences.selectSingleNode("ram_max_used_idle_pct").getText()); } catch (Exception e) {} try { idle_time_to_run = Double.parseDouble(elGlobalPreferences.selectSingleNode("idle_time_to_run").getText()); } catch (Exception e) {} try { max_bytes_sec_up = Double.parseDouble(elGlobalPreferences.selectSingleNode("max_bytes_sec_up").getText()); } catch (Exception e) {} try { max_bytes_sec_down = Double.parseDouble(elGlobalPreferences.selectSingleNode("max_bytes_sec_down").getText()); } catch (Exception e) {} try { cpu_usage_limit = Double.parseDouble(elGlobalPreferences.selectSingleNode("cpu_usage_limit").getText()); } catch (Exception e) {} } public String getFileTransfers() throws IOException { startCommand(); output.write("<get_file_transfers/>n"); endCommand(); return read(); } public boolean runBenchmarks() throws IOException { startCommand(); output.write("<run_benchmarks/>n"); endCommand(); return success(read()); } public boolean showGraphics() throws IOException { startCommand(); output.write("<result_show_graphics>n"); endCommand(); return success(read()); } public boolean updateProject(String projectURL) throws IOException { startCommand(); output.write("<project_update>n"); output.write("<project_url>" + projectURL + "</project_url>n"); output.write("</project_update>n"); endCommand(); return success(read()); } public boolean suspendProject(String projectURL) throws IOException { startCommand(); output.write("<project_suspend>n"); output.write("<project_url>" + projectURL + "</project_url>n"); output.write("</project_suspend>n"); endCommand(); return success(read()); } public boolean resumeProject(String projectURL) throws IOException { startCommand(); output.write("<project_resume>n"); output.write("<project_url>" + projectURL + "</project_url>n"); output.write("</project_resume>n"); endCommand(); return success(read()); } public boolean freezeProject(String projectURL) throws IOException { startCommand(); output.write("<project_nomorework>n"); output.write("<project_url>" + projectURL + "</project_url>n"); output.write("</project_nomorework>n"); endCommand(); return success(read()); } public boolean thawProject(String projectURL) throws IOException { startCommand(); output.write("<project_allowmorework>n"); output.write("<project_url>" + projectURL + "</project_url>n"); output.write("</project_allowmorework>n"); endCommand(); return success(read()); } public boolean suspendResult(String result, String projectURL) throws IOException { startCommand(); output.write("<suspend_result>n"); output.write("<project_url>" + projectURL + "</project_url>n"); output.write("<name>" + result + "</name>n"); output.write("</suspend_result>n"); endCommand(); return success(read()); } public boolean resumeResult(String result, String projectURL) throws IOException { startCommand(); output.write("<resume_result>n"); output.write("<project_url>" + projectURL + "</project_url>n"); output.write("<name>" + result + "</name>n"); output.write("</resume_result>n"); endCommand(); return success(read()); } public boolean abortResult(String result, String projectURL) throws IOException { startCommand(); output.write("<abort_result>n"); output.write("<project_url>" + projectURL + "</project_url>n"); output.write("<name>" + result + "</name>n"); output.write("</abort_result>n"); endCommand(); return success(read()); } public boolean retryTransfer(String file, String projectURL) throws IOException { startCommand(); output.write("<retry_file_transfer>n"); output.write("<project_url>" + projectURL + "</project_url>n"); output.write("<filename>" + file + "</filename>n"); output.write("</retry_file_transfer>n"); endCommand(); return success(read()); } public boolean resetProject(String projectURL) throws IOException { startCommand(); output.write("<project_reset>n"); output.write("<project_url>" + projectURL + "</project_url>n"); output.write("</project_reset>n"); endCommand(); return success(read()); } public boolean detachProject(String projectURL) throws IOException { startCommand(); output.write("<project_detach>n"); output.write("<project_url>" + projectURL + "</project_url>n"); output.write("</project_detach>n"); endCommand(); return success(read()); } public boolean attachProject(String projectURL, String key) throws IOException { startCommand(); output.write("<project_attach>n"); output.write("<project_url>" + projectURL + "</project_url>n"); output.write("<authenticator>" + key + "</authenticator>n"); output.write("</project_attach>n"); endCommand(); return success(read()); } public boolean setRunMode(BOINCMode mode) throws IOException { startCommand(); output.write("<set_run_mode>n"); output.write(mode + "n"); output.write("</set_run_mode>n"); endCommand(); return success(read()); } public boolean setNetworkMode(BOINCMode mode) throws IOException { startCommand(); output.write("<set_network_mode>n"); output.write(mode + "n"); output.write("</set_network_mode>n"); endCommand(); return success(read()); } public String getMessages(int seqno) throws IOException { //List<String> messages = new ArrayList<String>(); startCommand(); output.write("<get_messages>n"); output.write("seqno>" + seqno + "</seqno>n"); output.write("</get_messages>n"); endCommand(); String response = read(); //messages.add(response); return response; } } |
Copyright © 2024 University of California.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License,
Version 1.2 or any later version published by the Free Software Foundation.