Download presentation
Presentation is loading. Please wait.
Published byStephen Oliver Modified over 8 years ago
1
Introduction to job submission portlets Riccardo Bruno (riccardo.bruno@ct.infn.it) INFN Dpt. Of Cataniariccardo.bruno@ct.infn.it Web course on the development of applications for Catania Science Gateways, 23 July 2013
2
2 Outline Pre-requisites MyJobs portlet Installation GridOperations table Portlet Template Get from SVN Compile and test Job submit logging extraction Code explanations init() method and preferences The ACTION/VIEW enums and the portletStatus variable The AppInput Class The getInputForm method The submitJob method Preferences Fixing on GridEngine 1.5.1
3
MyJobs (1/2) MyJob war file available from SourceForge at: MYJOBSURL=http://sourceforge.net/projects/ctsciencegtwys/files/catania-science- gateway/wars/1307/MyJobs.war/download curl -L $MYJOBSURL -o MyJobs.war or, wget $MYJOBSURL -O MyJobs.war Deploy MyJobs with: cp MyJobs $LIFERAY_HOME/deploy/ Watch the Liferay’ server.log file till: ‘MyJobs successfully deployed’ Install the portlet in the portal through liferay menu: Add/More…/INFN/MyJobs
4
MyJobs (2/2) Active Jobs Job Status and Output Search on job description Job description
5
GridOperations table (1/2) Each user action which involves the distributed infrastructure will be tracked by the UsersTracking Database The GridEngine uses the GridOperations table to register applications and services accessing the distributed infrastructure mysql -u tracking_user -pusertracking userstracking desc GridOperations; +-------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | portal | varchar(120) | NO | | NULL | | | description | varchar(200) | NO | | NULL | | +-------------+--------------+------+-----+---------+----------------+ We can register and then track the activity of our developed portlet with: insert into GridOperations values (9,'test','testPortlet');
6
GridOperations table (2/2) How to get GridOperations values id – Just a numeric value; ‘9’ historically used by Tester Apps portal – Use the value highlighted in the figure; Liferay’ right, top-most menu: description – Use any human readable application description Application registration in the GridOperations table is mandatory for the MyJobs portlet GridOperations values will be carefully selected for production portals
7
Portlet Template svn checkout http://svn.code.sf.net/p/ctsciencegtwys/liferay/trunk/gilda/mi-hostname-portlet The portlet template is a complete example of JSR 286 compliant portlet able to submit a sequential Job into a distributed environment. Its java code extends the GenericPortlet class and uses JSP pages to generate the input GUI Java code contains java-doc compliant remarks able to generate automatically help pages
8
Portlet Template - Features It provides a full example on: Define application default values Define distributed infrastructure settings where the application will run Manage input elements from web forms as application input Manage upload file requests Manage portlet preferences to handle distributed infrastructure settings View/Manage the ‘pilot script’ which contains the batch instructions that will be executed on the remote Worker Node (WN). The portlet template can be ‘customized’ as shown by the previous presentation on the ‘generic’ portlet. Make a full copy of the mi-hostname-portlet cp mi-hostname-portlet mi-custom-portlet Open the customze.sh script inside the mi-custom-portlet directory and change all configurable parameters, then execute it: ./customize.sh The new portlet is now an hostname clone configured with your settings and ready to be further customized for application specific requirements
9
Portlet Template install and deploy Compile the template portlet cd mi-hostname-portlet ant deploy (then watch the Liferay’ server log file) Deploy the portlet from Liferay menu as already done for MyJobs Location: Add/More/GILDA/mi-hostname-portlet Test the portlet Press the ‘Demo’ and then ‘Submit’ buttons It is recommended to watch the Liferay’ server log file during the whole process Bottom Top
10
Portlet Template meaning and usage mi-hostname-portlet mi – Multi Infrastructure; it allows to execute the same application on many different insfrastructures (gLite, only) A multi-Infrastructure+multi-Middleware example exists as well and currently running on Chain project Science Gateway. Its code available on Sourceforge as well. hostname – The execution of the ‘hostname’ command on the distributed environments is used exactly like the ‘Helloworld’ examples while approaching new programming languages. It accepts an input file or a text inside the bigger text-area in mutually exclusive fashion. Then just specify a job description string and submit the job with the ‘Submit’ button
11
Before testing the job execution Open the VPN or be sure the eTokenserver allows incoming connections on port 8082 form your portal IP address Check the eTokenserver service is reachable Connect to http://etokenserver.ct.infn.it:8082/eTokenServer/http://etokenserver.ct.infn.it:8082/eTokenServer/ From the interface generate the robot proxy request Execute curl or wget on the generated request Check the system date is aligned with current time On linux check the ntpd service; re-align date as root with: /etc/init.d/ntpd stop ; ntpdate ntp-1.infn.it ; ntpd start Check that Grid CA certificates are updated curl http://grid.ct.infn.it/cron_files/grid_settings.tar.gz > grid_settings.tar.gz tar xvfz grid_settings.tar.gz -C /etc/grid-security/
12
Job Execution Log extraction Liferay server.log file reports: A full dump of the portlet preference values The GridEngine Initialization The Robot proxy retrieval [mi_hostname_portlet:108] dump: Infrastructure #1 enableInfrastructure : 'yes' nameInfrastructure : 'EUMEDGRID-Support infrastructure' acronymInfrastructure: 'EUMEDGRID' [mi_hostname_portlet:108] dump: Infrastructure #1 enableInfrastructure : 'yes' nameInfrastructure : 'EUMEDGRID-Support infrastructure' acronymInfrastructure: 'EUMEDGRID' INFO JSagaJobSubmission - Getting adaptor name... JSagaJobSubmission - Using adaptor: wms INFO RobotProxy - proxyPath=/tmp/7f7e1e98-0fd1-4ebb-a1ae-0627efddf600 INFO RobotProxy - get proxy: http://etokenserver.ct.infn.it:8082/eTokenServer/eToken/332576f78a4fe70a52048043e90cd11f? voms=gridit:gridit&proxy-renewal=true http://etokenserver.ct.infn.it:8082/eTokenServer/eToken/332576f78a4fe70a52048043e90cd11f? voms=gridit:gridit&proxy-renewal=true INFO RobotProxy - proxyPath=/tmp/7f7e1e98-0fd1-4ebb-a1ae-0627efddf600 INFO RobotProxy - get proxy: http://etokenserver.ct.infn.it:8082/eTokenServer/eToken/332576f78a4fe70a52048043e90cd11f? voms=gridit:gridit&proxy-renewal=true http://etokenserver.ct.infn.it:8082/eTokenServer/eToken/332576f78a4fe70a52048043e90cd11f? voms=gridit:gridit&proxy-renewal=true
13
Job Execution Log extraction The JSAGA job submission string The input sandbox file transfers The job id and the job status thread execution INFO JSagaJobSubmission - jobSandbox:/opt/liferay-portal-6.1.1-ce-ga2/glassfish- 3.1.2/domains/domain1/autodeploy/mi-hostname-portlet/WEB- INF/job/pilot_script.sh>pilot_script.sh,/tmp/20130717133558_test_input_file.txt>201307171335 58_test_input_file.txt,/tmp//jobOutput/multiinfrastructuredemojobdescription1_1/<hostname- Output.txt,/tmp//jobOutput/multiinfrastructuredemojobdescription1_1/<hostname-Error.txt Connecting to Gsiftp service at: wms014.cnaf.infn.it:2811... JSagaJobSubmission - Job Submitted: [wms://wms014.cnaf.infn.it:7443/glite_wms_wmproxy_server]- [https://wms014.cnaf.infn.it:9000/kznSb62LcqCW0fXTiTfr7Q] UsersTrackingDBInterface - UpdateJobsStatusAsync running in Thread : Thread[pool-103-thread- 1,5,grizzly-kernel]
14
The Code mi-hostname-portlet files docroot/ css/ main.css images/ AppLogo.png lib/ submit.jsp viewPilot.jsp edit.jsp help.jsp input.jsp icon.png js/ main.js WEBINF/ (See next slide) build.xml customize.sh css styles definition file Application logo Portlet libraries from third parties JSP pages for: View,Help,Edit portlet modes JSP pages for: View,Help,Edit portlet modes WEBINF Contains portlet configurations, Grid job definition and portlet Java code WEBINF Contains portlet configurations, Grid job definition and portlet Java code Ant build definition file Customization script
15
The Code mi-hostname-portlet files WEB-INF/ classes/ src/it/infn/ct/ AppInfrastructureInfo.java AppLogger.java AppPreferences.java mi_hostname_portlet.java tld/ job/ standard_pilot_script.sh pilot_script.sh liferay-display.xml liferay-portlet.xml glassfish-web.xml portlet.xml css styles definition file Portlet’ Java code Portlet’ XML configuration files XML semantic Grid Job files
16
The Java Code Source code available form SourceforgeSourceforge 3 Classes: AppInfrastructureInfo.java Maintains the information about the distributed infrastructure resources and services AppLogger.java Wrapper class dedicated to the logging activity AppPreferences.java Contains portlet preferences related to the Grid job and the distributed infrastructure resource settings mi_hostname_portlet.java Main portlet code which inherits form the GenericPortlet class. It manages the portlet GUI and instructs the GridEngine to submit the job.
17
mi_hostname_portlet.java Types and Classes Actions enumerated types ACTION_INPUT // User asked to submit a job,ACTION_SUBMIT// User asked to rerutn to the input form,ACTION_PILOT // The user did something in the edit pilot screen pane Views enumerated types VIEW_INPUT // View containing application input fields,VIEW_SUBMIT // View reporting the job submission,VIEW_PILOT // Shows the pilot script and makes it editable The couple: ( PortletMode, PortletStatus ) determines the entire portlet workflow; both values handled by JSP pages and Java code. The second variable used both for processAction and doView
18
AppInput class AppInput class defined inside the main Java code source This class is ment to collect all application GUI inputs and must be dynamically instanciated inside the processAction as soon as the user press the ‘Submit’ button class AppInput { // Applicatoin inputs String inputFileName; // Filename for application input file String inputFileText; // GUI Textfield content String jobIdentifier; // User' given job identifier // Each inputSandobox file must be declared below // This variable contains the content of an uploaded file String inputSandbox_inputFile; // Some user level information // must be stored as well String username; String timestamp; class AppInput { // Applicatoin inputs String inputFileName; // Filename for application input file String inputFileText; // GUI Textfield content String jobIdentifier; // User' given job identifier // Each inputSandobox file must be declared below // This variable contains the content of an uploaded file String inputSandbox_inputFile; // Some user level information // must be stored as well String username; String timestamp;
19
processAction (ActionRequest request, ActionResponse response ) Get portal and user information: portalName, username From the request object retrieve the PortletMode; an if … else if … chain handles each different mode: EDIT, VIEW, HELP VIEW Gets the PortletStatus value (Actions) and use this value inside the switch() statement: ACTION_INPUT, ACTION_SUBMIT, ACTION_PILOT EDIT Manages the portlet preferences interface controls HELP Does nothing; just Logs the state ProcessAction sends parameters to the doView() method through the response object
20
doView (RenderRequest request, RenderResponse response ) From request object retrieve the PortletStatus value and determine the variable value currentView and using it for a switch statement Inside the switch, just select the proper jsp page case VIEW_SUBMIT: { _log.info("VIEW_SUBMIT Selected..."); String jobIdentifier = request.getParameter("jobIdentifier"); request.setAttribute("jobIdentifier", jobIdentifier); PortletRequestDispatcher dispatcher=getPortletContext().\ getRequestDispatcher("/submit.jsp"); dispatcher.include(request, response); } case VIEW_SUBMIT: { _log.info("VIEW_SUBMIT Selected..."); String jobIdentifier = request.getParameter("jobIdentifier"); request.setAttribute("jobIdentifier", jobIdentifier); PortletRequestDispatcher dispatcher=getPortletContext().\ getRequestDispatcher("/submit.jsp"); dispatcher.include(request, response); } // Different actions will be performed accordingly to the // different possible view modes switch(Views.valueOf(currentView)) { … // Different actions will be performed accordingly to the // different possible view modes switch(Views.valueOf(currentView)) { …
21
VIEW Mode Workflow VIEW_INPUT ACTION_SUBMIT->VIEW_SUBMIT ACTION_INPUT->VIEW_INPUT
22
EDIT Mode Workflow doEdit() VIEW_INPUT pref_action : next, previous, add, remove, viewPilot pref_action : next, previous, add, remove, viewPilot VIEW_INPUT VIEW_PILOT
23
Variables: JAVA->JSP From doView/doEdit/doHelp: Inside the JSP refer the variable with: id: Variable name class: java.lang.String (or any other class) scope: Normally set to ‘ request ’ Inside JSP code refer the variable value with: request.setAttribute(” ", " "); " class=" " scope=”var scope"/> %>
24
Variables: JSP->Java Inside the JSP use values inside s : Inside the Java code refer the variable with (ProcessAction) : Above example works for ‘normal’ s mi-hostname-porltet uses a particular kind of ‘multipart’ allows file upload but requires to manually handle input parameters as done by the getInputForm() method " id=" " … > (String)request.getParameter(" ");
25
getInputForm() (1/2) Necessary to handle file uploads using the apache’ commons.io.* libraries Mainly consists of a loop which set the java variables It uses an enumerated type to identify input controls Enter the input parameters extraction loop: private enum inputControlsIds { // Input control’ name,… // Other controls }; private enum inputControlsIds { // Input control’ name,… // Other controls }; if (PortletFileUpload.isMultipartContent(request))
26
getInputForm() (2/2) The loop: FileItemFactory factory = new DiskFileItemFactory(); PortletFileUpload upload = new PortletFileUpload( factory ); List items = upload.parseRequest(request); File repositoryPath = new File("/tmp"); DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory(); diskFileItemFactory.setRepository(repositoryPath); Iterator iter = items.iterator(); while (iter.hasNext()) { FileItem item = (FileItem)iter.next(); String fieldName =item.getFieldName(); String fileName =item.getName(); String contentType=item.getContentType(); boolean isInMemory =item.isInMemory(); long sizeInBytes=item.getSize(); switch(inputControlsIds.valueOf(fieldName)) { case var_name: appInput. =item.getString(); break; FileItemFactory factory = new DiskFileItemFactory(); PortletFileUpload upload = new PortletFileUpload( factory ); List items = upload.parseRequest(request); File repositoryPath = new File("/tmp"); DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory(); diskFileItemFactory.setRepository(repositoryPath); Iterator iter = items.iterator(); while (iter.hasNext()) { FileItem item = (FileItem)iter.next(); String fieldName =item.getFieldName(); String fileName =item.getName(); String contentType=item.getContentType(); boolean isInMemory =item.isInMemory(); long sizeInBytes=item.getSize(); switch(inputControlsIds.valueOf(fieldName)) { case var_name: appInput. =item.getString(); break;
27
processInputFile Called in case of input files: processInputFile sets the appInput’ text variable with the uploaded file content (just an example) mi-hostname-portlet has two utilities: WARNIG: File content is logged; disable this for binary files processInputFile(FileItem item, AppInput appInput) { File uploadedFile = new File(theNewFileName); try { item.write(uploadedFile); } processInputFile(FileItem item, AppInput appInput) { File uploadedFile = new File(theNewFileName); try { item.write(uploadedFile); } private String updateString(String file) {…} private void storeString(String fileName,String fileContent) {…} private String updateString(String file) {…} private void storeString(String fileName,String fileContent) {…}
28
submitJob (1/4) Inside the processAction : // Get current preference values getPreferences(request,null); // Create the appInput object AppInput appInput = new AppInput(); // Stores the user submitting the job appInput.username=username; // Determine the submissionTimeStamp SimpleDateFormat dateFormat = new SimpleDateFormat(tsFormat); String timestamp = dateFormat.format(Calendar.getInstance().getTime()); appInput.timestamp=timestamp; // Process input fields and files to upload getInputForm(request,appInput); // Following files have to be updated with // values taken from textareas or from uploaded files: // input_file.txt updateFiles(appInput); // Submit the job submitJob(appInput); // Get current preference values getPreferences(request,null); // Create the appInput object AppInput appInput = new AppInput(); // Stores the user submitting the job appInput.username=username; // Determine the submissionTimeStamp SimpleDateFormat dateFormat = new SimpleDateFormat(tsFormat); String timestamp = dateFormat.format(Calendar.getInstance().getTime()); appInput.timestamp=timestamp; // Process input fields and files to upload getInputForm(request,appInput); // Following files have to be updated with // values taken from textareas or from uploaded files: // input_file.txt updateFiles(appInput); // Submit the job submitJob(appInput);
29
submitJob (2/4) (Old Way) submitJob() method Instructs the GridEngine to submit Create the M.I.JobSubmission object: For development environments: Setup all enabled infrastructures in the preferences // GridEngine' MultiInfrastructure job submission object MultiInfrastructureJobSubmission miJobSubmission = new MultiInfrastructureJobSubmission(); // GridEngine' MultiInfrastructure job submission object MultiInfrastructureJobSubmission miJobSubmission = new MultiInfrastructureJobSubmission(); miJobSubmission = new MultiInfrastructureJobSubmission( ); // Assigns all enabled infrastructures InfrastructureInfo[] infrastructuresInfo= appPreferences.getEnabledInfrastructures(); for(int i=0; i<infrastructuresInfo.length; i++) miJobSubmission.addInfrastructure(infrastructuresInfo[i]); // Assigns all enabled infrastructures InfrastructureInfo[] infrastructuresInfo= appPreferences.getEnabledInfrastructures(); for(int i=0; i<infrastructuresInfo.length; i++) miJobSubmission.addInfrastructure(infrastructuresInfo[i]);
30
submitJob (3/4) (Old Way) Describe the job Submit the job miJobSubmission.setExecutable (…); // Specify the executeable miJobSubmission.setArguments (…); // Specify the application' arguments miJobSubmission.setOutputPath (…); // Specify the output directory miJobSubmission.setOutputFiles(outputSandbox); // Setup output files miJobSubmission.setJobOutput ( outputFile); // std-outputr files miJobSubmission.setJobError ( errorFile); // std-error file miJobSubmission.setInputFiles ( inputSandbox); // input files miJobSubmission.setJDLRequirements(jdlRequirements); miJobSubmission.setExecutable (…); // Specify the executeable miJobSubmission.setArguments (…); // Specify the application' arguments miJobSubmission.setOutputPath (…); // Specify the output directory miJobSubmission.setOutputFiles(outputSandbox); // Setup output files miJobSubmission.setJobOutput ( outputFile); // std-outputr files miJobSubmission.setJobError ( errorFile); // std-error file miJobSubmission.setInputFiles ( inputSandbox); // input files miJobSubmission.setJDLRequirements(jdlRequirements); miJobSubmission.submitJobAsync(appInput.username, portalIPAddress, applicationId, appInput.jobIdentifier);; miJobSubmission.submitJobAsync(appInput.username, portalIPAddress, applicationId, appInput.jobIdentifier);;
31
submitJob (4/4) (New Way, from v1.5.1) Uses a new object to describe the Job first Submit the job GEJobDescription description = new GEJobDescription(); description.setExecutable("/bin/sh"); description.setArguments("hostname.sh"); description.setInputFiles(…); description.setOutputPath(….); description.setOutput(…); description.setError(…); miJobSubmission = new MultiInfrastructureJobSubmission(description); // or for development environments // MultiInfrastructureJobSubmission(,description); GEJobDescription description = new GEJobDescription(); description.setExecutable("/bin/sh"); description.setArguments("hostname.sh"); description.setInputFiles(…); description.setOutputPath(….); description.setOutput(…); description.setError(…); miJobSubmission = new MultiInfrastructureJobSubmission(description); // or for development environments // MultiInfrastructureJobSubmission(,description); miJobSubmission.submitJobAsync(appInput.username, portalIPAddress, applicationId, appInput.jobIdentifier);; miJobSubmission.submitJobAsync(appInput.username, portalIPAddress, applicationId, appInput.jobIdentifier);;
32
Preferences (Generic Settings) Log level Define different levels for the logging activity: INFO, WARN, ERROR,… GridOperations id table value Number of insfrastructures GridOperations description Application requirements ‘Job Requirements’ Pilot job, shows the batch that will be executed remotely UsersTrackingDB connection settings. When !NULL, the portlet will operate in DEBUG mode
33
Preferences (Infrastructure’ Settings) Enable Infrastructure TRUE/FALSE flag Infrastructure number shown Name of the infrastructure Infrastructure short name Information System service WMS (optional) GridEngine allow to specify even a list of Computing Elements; this is not handled by the example RobotProxy settings (Host/Port/VO/Roles/Renewal flag) LocalProxy (Used to bypass the eTokenserver; using Personal Certificates) Software Tags specify which resource is capable to satisfy the tag request WARNING: MultiMiddleware example overrides the meaning of some fields; especially the BDII host which identifies the JSAGA adaptor
34
Preferences (The code) AppPreferences.java Class that contains all portlet’ preference values It provides a method that returns the GridEngine’ InfrastructureInfo object The portlet Init() method loads default settings from the portlet.xml file (customize.sh creates dynamically this file) The Init() method creates two object: AppInitPreferences – Containing default values taken from portlet.xml AppPreferences – Containing portal administrator’ settings (if changed) AppInitPreferences – Meant to revert default settings (not implemented) The customize.sh portlet allow to define default settings for many infrastructures
35
customize.sh BASH script to clone the mi-hostname-portlet, but renaming the whole project with your specific application details, just changing few environment variables Essential customization values AUTH_* values, meant for Application Author details APP_OPERDESC GridOperation’ description field (optional) APP_OPERATIONID The GridOperation.Id for this application ( 9 default) APP_NAME The Application name APP_VERSION The version number of your application INIT_NUMINFRASTRUCTURES The number of infrastructures INIT_n_ Set of infrastructure values 1 <= n <= INIT_NUMINFRASTRUCTURES
36
GridEngine 1.5.1 Fixing (1/2) Before to proceed with testing, please fix your 1.5.1 Download the new fixed jar (jsaga-job-management-1.5.1_fix.jar) GEFIXURL=http://sourceforge.net/projects/ctsciencegtwys/files/cat ania-grid-engine/1.5.1_fix/jsaga-job-management- 1.5.1_fix.jar/download curl -L $GEFIXURL -o /opt/GridEngine/lib/jsaga-job-management- 1.5.1_fix.jar or, wget $GEFIXURL -O /opt/GridEngine/lib/jsaga-job- management-1.5.1_fix.jar Download the DB patch SQL file (JobDescription.sql) GEFIXSQL=http://sourceforge.net/projects/ctsciencegtwys/files/cat ania-grid-engine/1.5.1_fix/JobDescription.sql/download curl -L $GEFIXSQL -o $HOME/JobDescription.sql or wget $GEFIXSQL -o $HOME/JobDescription.sql
37
GridEngine 1.5.1 Fixing (2/2) Now patch your your 1.5.1 Disable the old jar and prepare a symbolic link to the fixed one mv /opt/GridEngine/lib/jsaga-job-management-1.5.1.jar /opt/GridEngine/lib/jsaga-job-management-1.5.1.jar_disabled ln -s /opt/GridEngine/lib/jsaga-job-management-1.5.1_fix.jar /opt/GridEngine/lib/jsaga-job-management-1.5.1.jar Execute the SQL patch mysql -u tracking_user -pusertracking userstracking < $HOME/JobDescription.sql Now compile the mi-hostname-portlet and test it Please report any issue to the list: sg-licence@ct.infn.itsg-licence@ct.infn.it
38
Webinar Now you are really ready to create your own distributed applications for the Catania Science Gateway! Next webinar introduces you to more complex jobs; in particular: collections, parametric and workflows
39
More info GridEngine’ JavadocJavadoc M.I.JobSubmission ConstructorsConstructors SVN mi-hostname-portletmi-hostname-portlet SVN helloworld-portlet (MM/MI) examplehelloworld-portlet
40
40 Thank you !
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.