Title: A Portal Architecture Review
1A Portal Architecture Review
2Talk Overview
- Portal architectures
- JSR 168 review
- A motivating example
- Building grid clients with the Java COG.
- Combining the Java COG with Java Server Faces.
3A Famous Web Portal
4A Famous Portal, After Login
5What to Notice
- After logging in, my colors, layouts, and content
all changed. - I get my stock list, my Bloomington weather, my
news stories, etc. - I got rid of Garfield
- As we will see later, each of these content
fragments (encircled) is managed by a thing
called a portlet - I dont guarantee that this is true for
Yahoos web site but it is true for a large class
of enterprise Java portal systems. - Portlets are the key to portal software reuse.
6Let 10,000 Flowers Bloom
- Many portal projects have been launched since
late 90s. - HotPage from SDSC, NCSA efforts, DOD, DOE
Portals, NASA IPG - 2002 Special Issue of Concurrency and
Computation Practice and Experience. - The field continues to be active
- Global Grid Forum 14 Science Gateway workshop in
June 2005. - About 15 gateways will be described in upcoming
issue of Concurrency. - GCE2005 workshop at Supercomputing 05.
- http//www.ggf.org/ggf_events_lodging_ggf15.htm
- How do we share and reuse all of this work?
7Three-Tiered Architecture
Grid and Web Protocols
JDBC, Local, or Remote Connection
Portal User Interface
Database Service
Database
Portal Client Stub
Grid Resource Broker Service
HPC or Compute Cluster
Portal Client Stub
Information and Data Services
Grid Information Services, SRB
Portal Client Stub
- Three-tiered architecture is accepted standard
for accessing Grid and other services
8JSR 168 Overview
9What Is a Portlet?
- A portlet is a piece of Java code that manages
the content of one section of a web portals
HTML. - It can do anything else that a Java web
application can do. - You can connect a portlet to a database, invoke a
web service, download an RSS feed, etc. - It lives in a portlet container, which creates,
manages, and destroys all the portlets of the
portal. - Portlet containers are part of portals.
- Portals must do other things like manage login,
users, groups, layouts, etc. - JSR 168 standardizes two main things
- How the portlet container manages portlet
lifecycles - How the portlets are programmed.
10What is JSR 168?
- From the portlet development point of view, it is
really very simple - You write a java class that extends
GenericPortlet. - You override/implement several methods inherited
from GenericPortlet. - You use some supporting classes/interfaces
- Many are analogous to their servlet equivalents
- Some (portletsession) actually seem to be trivial
wrappers around servlet equivalents in Pluto. - I have a complete example in the extended slides.
- See also tutorial slides.
11Some Open Source JSR 168 Containers
- GridSphere
- http//www.gridsphere.org
- uPortal
- http//www.uportal.org
- LifeRay
- http//sourceforge.net/projects/lportal
- eXo platform
- http//www.exoplatform.com
- StringBeans
- http//www.nabh.com/projects/sbportal
- Jetspeed2
- http//portals.apache.org/jetspeed-2/
12Some GenericPortlet.java Methods
Method Description
Init Called when the portlet is created. Override if you need to set initial params.
doView Controls what happens immediately before the portlet is displayed in view mode. Normally you override this.
doHelp, doEdit Other portlet display modes
processAction Place for handling any ltformgt actions before turning over to the display mode method (like doView). You should override this for web forms.
13Some Supporting Classes/Interfaces
Class Description
PortletContext Similar to servlet context get context info and the RequestDispatcher from here.
PortletSession Stores attribute information for a single portlet application across multiple requests.
RenderRequest, RenderResponse The request and response objects available to the doView() method. Similar to the normal servlet request
ActionRequest,ActionResponse The request and response objects available to the processAction() method. Similar to the servlet request and response objects.
PortletURL Use this to create URLs that reference the portal.
PortletRequestDispatcher Use this to include/forward to a JSP or servlet in the same portlet app.
WindowState See if you are in minimized, maximized, normal state.
14The Big Picture
- As a portlet developer, the previous set of
classes are all you normally touch. - The portlet container (Pluto) is responsible for
running your portlets. - Init, invoke methods, destroy.
- Portlets have a very limited way of interacting
with the container. - The API is basically one-way.
15A Comment on Portlet Coding
- JSR 168 seems to make some important and dubious
assumptions - Developers will gladly ignore other development
methodologies/frameworks like Velocity, Struts,
and Java Server Faces. - Developers instead want to write a GenericPortlet
extension for every single portlet they develop. - And write really complicated processAction() and
doView() methods. - Developers will like the specific JSR 168
portlet-style Model-View-Controller that it
forces on them. - Fortunately, these other development environments
can be mapped to portlet actions. - In the OGCE project, we have developed support
for Velocity portlets. - We are transitioning to Java Server Faces
16A Grid Portlet Scenario
- Developing a Simple Grid Portlet Application
17A Quantum Chemistry Code Submission Form
- You have been asked to develop a submission form
for the Democritos groups Quantum Espresso (QE)
package. - These forms should help users set up and run QE
applications on the TeraGrid and other Grid
installations. - Mix of GT 2, GT 4, Condor, etc., for submission
- You are told to initially support the Plane Wave
Self Consistent Field (PWSCF) code. - Other QE applications may follow.
- These may be coupled with PWSCF into simple
workflows, but this is a later problem.
18Your Deployment Architecture
It acts as a common Gateway to different grid
toolkit installations and resources
Your portal server runs at FSU.
GT 4 _at_TG
TeraGrid LSF
Portal Server _at_FSU
MSI PBS
GT 2 _at_UMN
19Some Issues
- You decide the JSR 168 style portlets are the way
to go - But of course the PWSCF portlet doesnt exist
yet. - You will need to also support other Quantum
Espresso codes. - Would like to reuse as much code as possible.
- But your PWSCF portlet isnt reusable at that
level. - You also would like to simplify saving user input
data and session archiving.
20PWSCF Web Forms for Submission
21Your Choices
- JSR 168 will allow you to share your portlet code
with other collaborators. - The Java COG Kit will help hide the differences
between Grid toolkits for common tasks. - Vanilla JSF will help simplify your portlet
development in several ways. - JSF decouples your backing code from the Servlet
API - You can write your backing code as pure Java
Beans/Plain Old Java Objects. - You dont have to adopt, maintain HTTP parameter
name conventions. - Your form input backing beans can be
serialized/deserialized with Castor. - Coupling JSF and COG will allow you to compose
your Grid actions using simple JSF taglibs. - You can reuse your Grid taglibs in other Quantum
Espresso portlets. - You can compose composite actions
22The Java CoG Kit
- Gregor von Laszewski
- Argonne National Laboratory
- University of Chicago
- gregor_at_mcs.anl.gov
- http//www.cogkit.org
- (as interpreted by MEP)
23CoG Kits
- CoG Kits make Grid programming simple and new
technologies are easy to integrate - We focus on a CoG Kit for Java
- Python also available (K. Jackson, LBNL)
- Availability Java CoG Kit since 1997
- The CoG provides two important things
- A higher level client programming environment
than stubs. - A shield against different versions of the Globus
toolkit - Same high level API works with GT 2.4, GT 3.0.2,
GT 3.2.0, GT 3.2.1, GT 4.0.0
24CoG Abstraction Layers
Development Support
Nano materials
Bio- Informatics
Disaster Management
Portals
Applications
GT2
GT3 OGSI classic
GT4 WS-RF
Condor
Unicore
SSH
Others Avaki SETI
25Task
Task Handler
Task Specification
The class diagram is the same for all grid tasks
(running jobs, modifying files, moving data).
Service
Security Context
Service Contact
Classes also abstract toolkit provider
differences. You set these as parameters GT2,
GT4, etc.
26Java COG Summary
- The Java COG 4 interfaces provide high level
abstractions for building Grid clients. - Abstract out differences between Grid toolkits.
- Provide task abstractions that form the basis for
constructing DAG-style, file-based workflow. - The COG can be used to build a wide range of
clients - Desktops, grid shells, and of course portals.
- Portlets are a well known way to build reusable
portal components.
27Building Grid Portlets with Java Server Faces
28Limitations of Portlets
- Portlets provide a way to bundle and share a
complete application. - RSS portlet, GridFTP portlet, SRB portlet, etc.
- Portlets combine the user interface view and
action code. - But in science gateway development, we often need
finer grained components. - When user clicks button, upload file, launch
code, and move data someplace when done. - Combines GridFTP and Job Submit portlets
- Or maybe OGSA-DAI or SRB or .
- We need a way for the view and action code must
be developed from reusable parts.
29JSF and Science Gateways
- JSF enables you back your science application
input form portlets with Java Beans. - Again, these are independent of the servlet
container, so are easy to test and to reuse in
other applications. - But also, Java Beans can be easily serialized
with XML. - Castor, XML Beans
- Marshal and un-marshal user input for persistent
storage in XML storage services - OGSA-DAI, GPIR, WS-Context
- Potentially, can develop backing code as XML
Schema and generate the code.
30JSF for Grid Enabled HTML Widgets
- Natural program develop Java Bean wrappers
around Java COG kit, OGSA-DAI client API, SRB
Jargon, etc. - Allows simple integration with JSF.
- Some issues exist
- JSF only manages individual bean instances.
- But grid portlets will need to manage an unknown
number of bean instances. - You may launch and monitor many different jobs.
- We need a way of scripting composite actions
created out of multiple reusable actions.
31COG Bean Wrappers
- Recall the COG structure
- Executable tasks abstract basic grid actions and
hide toolkit version differences. - These tasks can be collected into file-based DAG
workflows. - First problem is simple wrap tasks as beans to
make them available to JSF. - GenericGridBean defines the interface
- Second problem is managing multiple individual
tasks.
32Managing Multiple Grid Tasks
- We must create and manage multiple beans for each
task. - That is, I submit the job four times in one
session. - Similarly, we can create multiple task graph
clones. - We do this by cloning and storing each bean.
- Beans have listeners and maintain state.
- Unsubmitted, submitted, active, suspended,
resumed are live - Stored in live repository
- Failed, canceled, completed, unknown are dead
- Stored in archive (WS-Context or other)
- Alternative approach use one bean that is a bean
factory for GenericGridTask beans.
33Task Submission Form
Corresponding JSF snippets ltotaskGraph
id"myGraph" method"taskgraph.test" gt
ltotask id"task1" method"task.create"
type"FileTransfer" /gt ltotask id"task2"
method"task.create" type"JobSubmit" /gt
ltotask id"task3" method"task.create"
type"FileTransfer" /gt ltotaskAdd
name"task1" method"taskgraph.add" /gt
ltotaskAdd name"task2" depends"task1"
method"taskgraph.add" /gt ltotaskAdd
name"task3" depends"task2" method"taskgraph.add
" /gt lt/otaskGraphgt
lthpanelGrid columns"3" gt lthoutputText
value"Hostname () "/gt lthinputText
value"task.hostname"/gt lt/hpanelGridgt
lthpanelGrid columns"3" gt lthoutputText
value"Provider () "/gt lthinputText
value"task.provider"/gt lt/hpanelGridgt
lthpanelGrid columns"2"gt lthcommandButton
id"submit" value"Submit" action"taskgraph.sub
mitAction"/gt lthcommandButton
value"Clear" type"Reset"/gt lt/hpanelGridgt
34Task Monitoring with JSF Data Model
lthdataTable value"jobData.jobs" var"job"gt
lthcolumngt ltffacet name"header"gt
lthoutputText style"font-weight bold"
value"Job ID" /gt lt/ffacetgt
lthoutputText value"job.jobId"/gt
lt/hcolumngt lthcolumngt ltffacet
name"header"gt lthoutputText
style"font-weight bold" value"Submit Date" /gt
lt/ffacetgt lthoutputText
value"job.submitDate"/gt lt/hcolumngt
lthcolumngt ltffacet name"header"gt
lthoutputText style"font-weight bold"
value"Finish Date" /gt lt/ffacetgt
lthoutputText value"job.finishDate"/gt
lt/hcolumngt lthcolumngt ltffacet
name"header"gt lthoutputText
style"font-weight bold" value"Status" /gt
lt/ffacetgt lthoutputText
value"job.status"/gt lt/hcolumngt
lt/hdataTablegt
Corresponding Java class. public class Job
private String jobId private String status
private String submitDate private String
finishDate
35Extended Slides
36The Java CoG Kit
- Gregor von Laszewski
- Argonne National Laboratory
- University of Chicago
- gregor_at_mcs.anl.gov
- http//www.cogkit.org
- (as interpreted by MEP)
37CoG Kits
- CoG Kits make Grid programming simple and new
technologies are easy to integrate - We focus on a CoG Kit for Java
- Python also available (K. Jackson, LBNL)
- Availability Java CoG Kit since 1997
- The CoG provides two important things
- A higher level client programming environment
than stubs. - A shield against different versions of the Globus
toolkit - Same high level API works with GT 2.4, GT 3.0.2,
GT 3.2.0, GT 3.2.1, GT 4.0.0
38CoG Abstraction Layers
Development Support
Nano materials
Bio- Informatics
Disaster Management
Portals
Applications
GT2
GT3 OGSI classic
GT4 WS-RF
Condor
Unicore
SSH
Others Avaki SETI
39(No Transcript)
40Task
Task Handler
Task Specification
The class diagram is the same for all grid tasks
(running jobs, modifying files, moving data).
Service
Security Context
Service Contact
Classes also abstract toolkit provider
differences. You set these as parameters GT2,
GT4, etc.
41Setting Up Task and Specification
- Task tasknew TaskImpl(mytask,
- Task.JOB_SUBMISSION)
- task.setProvider(GT2)
- JobSpecification spec
- new JobSpecificationImpl()
- spec.setExecutable(rm)
- spec.setBatchJob(true)
- spec.setArguments(-r)
-
- task.setSpecification(spec)
42Setting Up the Service and Security Context
- Service servicenew ServiceImpl(Service.JOB_SUBMIS
SION) - service.setProvider(GT2)
- SecurityContext securityContext
- CoreFactory.newSecurityContext(GT2)
- //Use cred object from ProxyManager
- securityContext.setCredentials(cred)
- service.setSecurityContext(
- (SecurityContext)securityContext)
43Set Up Service Contact and Finish
- ServiceContact serviceContact
- new ServiceContact(myhost.myorg.org)
- service.setServiceContact(serviceContact)
- task.setService(
- Service.JOB_SUBMISSION_SERVICE,
- service)
- TaskHandler handlernew GenericTaskHandler()
- handler.submit(task)
44Coupling CoG Tasks
- The COG abstractions also simplify creating
coupled tasks. - Tasks can be assembled into task graphs with
dependencies. - Do Task B after successful Task A
- Graphs can be nested.
45Java COG Summary
- The Java COG 4 interfaces provide high level
abstractions for building Grid clients. - Abstract out differences between Grid toolkits.
- Provide task abstractions that form the basis for
constructing DAG-style, file-based workflow. - The COG can be used to build a wide range of
clients - Desktops, grid shells, and of course portals.
- Portlets are a well known way to build reusable
portal components.
46Building Grid Portlets with Java Server Faces
47Limitations of Portlets
- Portlets provide a way to bundle and share a
complete application. - RSS portlet, GridFTP portlet, SRB portlet, etc.
- Portlets combine the user interface view and
action code. - But in science gateway development, we often need
finer grained components. - When user clicks button, upload file, launch
code, and move data someplace when done. - Combines GridFTP and Job Submit portlets
- Or maybe OGSA-DAI or SRB or .
- We need a way for the view and action code must
be developed from reusable parts.
48PWSCF Web Forms for Submission
49Java Server Faces Overview
- JSF can solve the reusable portlet widget
problem. - JSF can also work in standalone mode outside of
portlets. - Potentially independent of Web applications.
- XUL and Swing widget bindings
- We will first examine JSF generally
- Conclude with integrating JSF and COG
50Advantages of JSF
- JSF hides communication details that connect HTML
forms with backing code. - You dont have to worry about servlet specific
request, response, and session objects. - You dont have to maintain fragile naming
conventions for ltinputgt tags. - Developers only need to develop JavaBeans and tag
libraries. - Beans are independent of Web applications.
- Can be easily written and tested outside of
servlet containers. - Compatible popular Inversion of Control based
systems like JSF and Spring
51JSF and Science Gateways
- JSF enables you back your science application
input form portlets with Java Beans. - Again, these are independent of the servlet
container, so are easy to test and to reuse in
other applications. - But also, Java Beans can be easily serialized
with XML. - Castor, XML Beans
- Marshal and un-marshal user input for persistent
storage in XML storage services - OGSA-DAI, GPIR, WS-Context
- Potentially, can develop backing code as XML
Schema and generate the code.
52A JSF Example
- ltHTMLgt
- ltHEADgt lttitlegtHellolt/titlegt lt/HEADgt
- lt_at_ taglib uri"http//java.sun.com/jsf/html"
prefix"h" gt - lt_at_ taglib uri"http//java.sun.com/jsf/core"
prefix"f" gt - ltbody bgcolor"white"gt
- ltfviewgt
- lthform id"entryForm" gt
- lth2gt Enter some text in the form
belowlt/h2gt - lthinputText id"userSt"
- value"multiEventBean.userString"/gt
- lthcommandButton id"submit"
- action"success" value"Submit" gt
- ltfactionListener type"multiEventTest.
Listener1"/gt - ltfactionListener type"multiEventTest.
Listener2"/gt - lt/hcommandButtongt
- lt/hformgt
- lt/fviewgt
- lt/bodygt
- lt/HTMLgt
53The JSF Page
- Note everything with ltfgt or lthgt namespace
prefix is a JSF tag. - Usually, lthgt tags mimic HTML widgets.
- ltfgt is for non-rendered stuff.
- Everything else is good old HTML.
- There are three different Java classes here.
- They are all in the package multiEventTest
- multiEventBean.java is just a bean with typical
get/set methods. - Listener1.java and Listener2.java implement the
javax.faces.event.ActionListener interface. - All 3 classes are called when you click the
command button. - Also, take a look at ltinputTextgt. This is
roughly equivalent to ltinput name valuegt. - But no name needed. JSF handles parameter names
for you and connects them to the beans you
specify. - This greatly simplifies writing generic actions.
54A Simple Example HtmlDataGrid
- lt_at_ taglib uri"http//java.sun.com/jsf/html"
prefix"h" gt - lt_at_ taglib uri"http//java.sun.com/jsf/core"
prefix"f" gt - ltfviewgt
- lth2gt This shows an example of how to use
- HtmlDataTable to display some results.
- lt/h2gt
- lthdataTable value"ValueBean.itemList"
var"values" border"1"gt - lthcolumngt
- ltffacet name"header"gt
- lthoutputText value"Column 1"/gt
- lt/ffacetgt
- lthoutputText value"values.value1"/gt
- lt/hcolumngt
- lthcolumngt
- ltffacet name"header"gt
- lthoutputText value"Column 2"/gt
- lt/ffacetgt
- lthoutputText value"values.value2"/gt
- lthoutputText value"values.value2"/gt
55It Looks Like This
56Some Explanation
- The lthdataTablegt binds to a particular data set
with valueValueBean.itemList. - ValueBean.itemList must be java.util.List,
java.sql.ResultSet or similar. - The values of these lists may be beans also.
- The var just defines a useful internal value.
- Here, each entry in the list is set equal to
values. - In the example, the items in the list happen to
be simple beans with member variables value1
and value2 along with appropriate
getter/setters. - When you load the page, it just iterates through
the entries in ValueBean.itemList and creates the
table, as you instructed. - Note again there are no loops in the actual page.
Also, you dont know anything about the data you
are getting.
57JSF Magic Data Models
- The M in MVC is the Data Model
- Abstract representation of a data structure
- That is, not tied to the display of the data
(view) - JSF DataModel extension classes include
- Arrays wrap arrays of Java objects
- Lists wraps a java.util.List of Java objects
- Results for JSTLs Result object, which itself
wraps SQL ResultSets. - ResultSets also for JDBC, wraps the ResultsSet
object directly. - Scalar Wraps an individual Java object.
- Typically, these should follow Bean patterns for
naming member data and their associated
getter/setters. - You can write your own specialized Data Models.
- XMLDataModel, for wrapping an XML data bean,
comes to mind. - RSSDataModel is another that I found.
- These are associated with UIData classes in the
JSF page for display. - HtmlDataTable is an example.
58JSF Form Validators
- The user interface stuff (ltfgt and lthgt) has lots
of built-in validators - Verify that input entries are integers, doubles,
etc. - Verify that input entries fall within the correct
range (1 to 10 in the guessNumber example). - Verify the string has the right length.
- You can extend to write your own specialized
validators
59Integrating JSF and COG 4
- Mehmet Nacar and Marlon Pierce
60JSF for Grid Enabled HTML Widgets
- Natural program develop Java Bean wrappers
around Java COG kit, OGSA-DAI client API, SRB
Jargon, etc. - Allows simple integration with JSF.
- Some issues exist
- JSF only manages individual bean instances.
- But grid portlets will need to manage an unknown
number of bean instances. - You may launch and monitor many different jobs.
- We need a way of scripting composite actions
created out of multiple reusable actions.
61COG Bean Wrappers
- Recall the COG structure
- Executable tasks abstract basic grid actions and
hide toolkit version differences. - These tasks can be collected into file-based DAG
workflows. - First problem is simple wrap tasks as beans to
make them available to JSF. - GenericGridBean defines the interface
- Second problem is managing multiple individual
tasks.
62JSF Task Management Class Structure
63Managing Multiple Grid Tasks
- We must create and manage multiple beans for each
task. - That is, I submit the job four times in one
session. - Similarly, we can create multiple task graph
clones. - We do this by cloning and storing each bean.
- Beans have listeners and maintain state.
- Unsubmitted, submitted, active, suspended,
resumed are live - Stored in live repository
- Failed, canceled, completed, unknown are dead
- Stored in archive (WS-Context or other)
- Alternative approach use one bean that is a bean
factory for GenericGridTask beans.
64Managing Multiple Tasks
65Creating Task Graphs
- COG Task Graphs correspond to composite JSF Web
Form actions. - Do X, Y, and then Z when user clicks the button.
- Each of these actions may be reused, but the
entire action is new. - We must do two things
- Wrap the COG TaskGraphHandler with a bean and
bean manager. - Provide tag bindings for defining the custom
actions.
66Constructing Task Graphs
67Task Submission Form
Corresponding JSF snippets ltotaskGraph
id"myGraph" method"taskgraph.test" gt
ltotask id"task1" method"task.create"
type"FileTransfer" /gt ltotask id"task2"
method"task.create" type"JobSubmit" /gt
ltotask id"task3" method"task.create"
type"FileTransfer" /gt ltotaskAdd
name"task1" method"taskgraph.add" /gt
ltotaskAdd name"task2" depends"task1"
method"taskgraph.add" /gt ltotaskAdd
name"task3" depends"task2" method"taskgraph.add
" /gt lt/otaskGraphgt
lthpanelGrid columns"3" gt lthoutputText
value"Hostname () "/gt lthinputText
value"task.hostname"/gt lt/hpanelGridgt
lthpanelGrid columns"3" gt lthoutputText
value"Provider () "/gt lthinputText
value"task.provider"/gt lt/hpanelGridgt
lthpanelGrid columns"2"gt lthcommandButton
id"submit" value"Submit" action"taskgraph.sub
mitAction"/gt lthcommandButton
value"Clear" type"Reset"/gt lt/hpanelGridgt
68Task Monitoring with JSF Data Model
lthdataTable value"jobData.jobs" var"job"gt
lthcolumngt ltffacet name"header"gt
lthoutputText style"font-weight bold"
value"Job ID" /gt lt/ffacetgt
lthoutputText value"job.jobId"/gt
lt/hcolumngt lthcolumngt ltffacet
name"header"gt lthoutputText
style"font-weight bold" value"Submit Date" /gt
lt/ffacetgt lthoutputText
value"job.submitDate"/gt lt/hcolumngt
lthcolumngt ltffacet name"header"gt
lthoutputText style"font-weight bold"
value"Finish Date" /gt lt/ffacetgt
lthoutputText value"job.finishDate"/gt
lt/hcolumngt lthcolumngt ltffacet
name"header"gt lthoutputText
style"font-weight bold" value"Status" /gt
lt/ffacetgt lthoutputText
value"job.status"/gt lt/hcolumngt
lt/hdataTablegt
Corresponding Java class. public class Job
private String jobId private String status
private String submitDate private String
finishDate
69Expressing Task Graphs with Tags
lt_at_taglib uri"http//java.sun.com/jsf/core" prefix"f"gt lt_at_taglib uri"http//java.sun.com/jsf/html" prefix"h"gt lt_at_taglib uri"http//www.ogce.org/gsf/task" prefix"o"gt
ltotaskGraph id"myGraph" method"taskgraph.test" gt ltotask id"task1" method"task.create" type"FileTransfer" /gt ltotask id"task2" method"task.create" type"JobSubmit" /gt ltotask id"task3" method"task.create" type"FileTransfer" /gt ltotaskAdd name"task1" method"taskgraph.add" /gt ltotaskAdd name"task2" depends"task1" method"taskgraph.add" /gt ltotaskAdd name"task3" depends"task2" method"taskgraph.add" /gt lt/otaskGraphgt