|
|
To introduce fabric application development, we will:
- create a "Hello World!" fabric task;
- create fabric application, process flow and task XML files;
- package and deploy the "Hello World!" fabric application;
- create a simple "Hello World!" client;
- and submit "Hello World!" requests to the fabric.
In "Hello World!" example:
- The client submits a request to the fabric to execute the "Hello World!" fabric application's process flow.
- The process flow calls the "Hello World!" task.
- The task returns "Hello World!" in the fabric request to the process flow.
- The process flow returns the request to the client.
- The client receives "Hello World!" in the completed request, which prints the message to the console.
|

About the Tutorial Samples
You may create your own fabric application and client application, or you may use the files and projects provided in tutorial_samples.zip and tutorial_samples.tgz archives. The fabric APIs are not dependent on a particular build tool or development environment (IDE), so you may use your preferred build tools. For your convenience, we have included project files for several platforms.
The "Hello World!" Fabric Task
Java and .NET developers implement fabric tasks as simple object-oriented classes that are marked up using fabric annotations in Java or .NET. 'C' developers implement tasks as 'C' libraries using fabric task interfaces. Examples in each language are shown below.
When a fabric client submits an execution request into a fabric, the request and its user data is passed in a fabric request object. The fabric request object exists for the duration of the request, and is passed to each task executed to fulfill the request. When the fabric has fulfilled the client's request, the fabric request object is returned to the client. A fabric developer can get values from and set values to the fabric request object using the fabric client API and fabric task API. The Java and .NET task API, in particular, support several methods for manipulating values in the fabric request object.
In each "Hello World!" task, the value "Hello World!" is mapped from the method call into the fabric request object. In the cases of Java and .NET, the mapping is accomplished using a Java annotation or a .NET attribute. In the 'C' example, the value "Hello World!" is set into the fabric request object directly and not returned by the function.
Read more about the Task API.
Java HelloWorld.java
(tutorial_samples/java/hello_world/com/appistry/samples/hello_world/)
package com.appistry.samples.hello_world;
import com.appistry.task.Annotations.TaskReturnValue;
public class HelloWorld {
@TaskReturnValue(name="hello")
public String greet() {
return "Hello World!";
}
}
.NET HelloWorld.cs
(tutorial_samples/dotnet/hello_world/hello_world_app/)
using System;
using Appistry.Task;
namespace Appistry.Samples.HelloWorld
{
public class HelloWorld
{
[return: TaskReturnValue("hello")]
public string Greet()
{
return "Hello World!";
}
}
}
'C' hello_world.cpp
(tutorial_samples/cpp/hello_world/hello_world_app/)
#include "fabric_client.h"
#include <string>
using namespace std;
#ifdef _WIN32
#include <windows.h>
#endif
extern "C" void greet(fab_req* request)
{
fab_req_set_string(request, "hello", "Hello World!");
}
hello_world.def (Windows only) (in tutorial_samples/cpp/hello_world/hello_world_app/)
"Hello World!" Task Module Definition XML
Now that we have created our "Hello World!" fabric task, we must present it to the fabric in a task XML definition file. This definition file declaratively defines the task to the fabric.
- The root of the module definition XML is the module element:
| Attribute |
Use |
Description |
| file |
required |
The file attribute specifies the file containing the task and is case sensitive. For Java, this is a .class or .jar file. For .NET this is a .NET assembly. For compiled languages, this is the name of the DLL or library. The file attribute is case sensitive. |
| implementation |
required |
The implementation attribute specifies the task's run time environment: .NET, DLL, or Java. DLL is used for any language including 'C' that creates a DLL or library. |
| className |
optional |
In Java and .NET, the className identifies the class containing the task implementation. In .NET, the className value is the fully-qualified name of the class including package for Java, and namespace for .NET. If the class is not part of a Java package or a .NET namespace, the className value is simply the class name. The className attribute is case sensitive. The className attribute is required if the implementation is .NET or Java. This attribute is ignored if the implementation is DLL. |
- A module can contain many task elements:
| Attribute |
Use |
Description |
| name |
required |
The name attribute identifies the name of the task. The name can be the same as the name of the task function, or it can be an alias for that function. Our example here uses an alias. The name attribute is used to reference the task function from process flow XML definitions. The name attribute is case sensitive. |
| Sub-Element |
Cardinality |
Description |
| method |
0...1 |
The method element identifies the actual function name for the task. For Java and .NET, this is the actual name of the method in the class to be executed. For 'C' this is the actual name of the function to be executed. This is only needed if the method name differs from the task name attribute. |
Java hello_world_task.xml
(tutorial_samples/java/hello_world/
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "ModuleDefinition.dtd">
<module file="hello_world.jar" implementation="Java" className="com.appistry.samples.hello_world.HelloWorld.class">
<task name="helloWorld">
<method>greet</method>
</task>
</module>
.NET hello_world_task.xml
(tutorial_samples/dotnet/hello_world/hello_world_app/)
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "ModuleDefinition.dtd">
<module file="hello_world_dotnet_app.dll" implementation=".NET" className="Appistry.Samples.HelloWorld.HelloWorld">
<task name="HelloWorld">
<method>Greet</method>
</task>
</module>
'C' hello_world_task.xml
(tutorial_samples/cpp/hello_world/hello_world_app/)
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "ModuleDefinition.dtd">
<module file="hello_world_cpp_app.dll" implementation="DLL">
<task name="greet">
<method>greet</method>
</task>
</module>
This document only describes the elements used in the example. Read more about Task Module Definition XML.
"Hello World!" Process Flow Definition XML
Next we must define a fabric process flow to execute our "Hello World!" task. Tasks execute in the fabric in the context of a process flow. Process flows declaratively describe a state machine of activities to be carried out to fulfill a client request in the fabric. The process flow XML is essentially the same for each of our three language samples.
The process flow definition file defines the transition after a task completes. The basic unit of a process definition file is a state. A state is defined as an action to be performed and the transition rules to be followed based on the results of that action. An action is a task or a sub-process flow. The transitions are the rules ordering the execution of the tasks.
The process flow definition file contains:
- A process element: these attributes apply to all tasks within the process flow definition file.
| Attribute |
Description |
| name |
The name of the process flow. This element is required. |
| default-retries |
Default-retries specifies the number of times the task my be re-attempted before returning an error. |
| default-timeout |
Default-timeout specifies the amount of time, in seconds, a task may take to complete before returning an error. |
- A state element: the state element represents the task in the process flow. The first state in every process flow definition is "start". The state element must contain one task sub-element and one or more arc sub-elements.
| Attribute |
Description |
| name |
The name attribute uniquely identifies this "state" in the process flow. The name attribute is case sensitive. |
- A task element: the task element specifies the task to be run upon entering this state in the process flow.
| Attribute |
Description |
| name |
The name specifies the task to be run upon entering this state in the process flow. The value for name is the exact name listed in the task XML definition for the given task. In our example, the name "helloWorld" in the process flow XML definition below references the name "helloWorld" in task XML definition above. The name attribute is case sensitive. |
- An arc element: An arc element defines the transition from one state in the process flow to the next state. In a one-step process flow, which only executes one task, the transition is to the finish state. The arc element has two attributes that we use in the Kick Start sample: task-status and next-state.
| Attribute |
Description |
| task-status |
The task-status attribute identifies the status of the task or sub-process. These values are set by the fabric during task execution.
The possible values for task-status are:
| Value |
Description |
| complete |
The task or sub-process completed successfully. |
| not-attempted |
The application fabric did not attempt to complete the task or sub-process. |
| not-completed |
The task took too long to complete or the task or sub-process status could not be determined. |
|
| next-state |
The next-state attribute identifies the process flow state to be executed next if this arc is followed. |
The "Hello World!" process flow is very simple. It has a "start" state, which calls the "Hello World" task and corresponding "Greet" method. There is only one arc available, upon completion, which results in a "finish" state.
Java hello_world_flow.xml
(tutorial_samples/java/hello_world/com/appistry/samples/hello_world/)
<?xml version="1.0"?>
<!DOCTYPE process SYSTEM "ProcessDefinition.dtd">
<process name="hello_world_flow" default_retries="1" default_timeout="1">
<state name="start">
<task-action task="helloWorld"/>
<arc task-status="complete" next-state="finish"/>
</state>
</process>
.NET hello_world_flow.xml
(tutorial_samples/dotnet/hello_world/hello_world_app/)
<?xml version="1.0"?>
<!DOCTYPE process SYSTEM "ProcessDefinition.dtd">
<process name="hello_world_flow" default_retries="1" default_timeout="1">
<state name="start">
<task-action task="HelloWorld"/>
<arc task-status="complete" next-state="finish"/>
</state>
</process>
'C' hello_world_flow.xml
(tutorial_samples/cpp/hello_world/hello_world_app/)
<?xml version="1.0"?>
<!DOCTYPE process SYSTEM "ProcessDefinition.dtd">
<process name="hello_world_flow" default_retries="1" default_timeout="1">
<state name="start">
<task-action task="greet"/>
<arc task-status="complete" next-state="finish"/>
</state>
</process>
This document only describes the elements used in the example. Read more about process flows.
"Hello World!" Application Definition XML
A fabric application definition file groups the task and process flow files together into a single fabric application. The fabric uses this file to identify the components of a fabric application. The basic elements of a fabric application definition file are tasks and process flows.
- The root of the file is the app element: it sets the name of the fabric application and specifies the version number of the application for deployment in the fabric.
| Attribute |
Description |
| name |
The name attribute sets the name of the fabric application. The name of the fabric application is also the name of the application definition XML file. |
| version |
The version attribute indicates the application version. The fabric uses the version value to ensure the most current application is running. Any change to an application that requires redepolying the application to the fabric requires you to increment this value. If the application is already installed, the fabric does not allow you to deploy a lesser or equal version of the same application. The page Version Description does not exist. |
- The app element declares the tasks element and the process-flows element:
| Element |
Description |
| tasks |
Identifies the list of task definition files in the application. The file sub-element declares the name of the task file. |
| process-flows |
The process-flows element identifies the list of process flow definition files in the application. The file sub-element specifies the name of a process flow definition file and must be identical to the process name. The process-flows element must follow the tasks element. |
The "Hello World!" Application is very simple. It contains one task and one process flow.
Java hello_world_java_app.xml
(tutorial_samples/java/hello_world/)
<?xml version="1.0"?>
<!DOCTYPE app SYSTEM "FabricApp.dtd">
<app name="hello_world_java_app" version="1.0">
<tasks>
<file name="hello_world_task.xml"/>
</tasks>
<process-flows>
<file name="hello_world_flow.xml"/>
</process-flows>
</app>
.NET hello_world_dotnet_app.xml
(tutorial_samples/dotnet/hello_world/hello_world_app/)
<?xml version='1.0'?>
<!DOCTYPE app SYSTEM 'FabricApp.dtd'>
<app name='hello_world_dotnet_app' version='1.0'>
<tasks>
<file name="hello_world_task.xml" />
</tasks>
<process-flows>
<file name="hello_world_flow.xml" />
</process-flows>
</app>
'C' hello_world_cpp_app.xml
(tutorial_samples/cpp/hello_world/hello_world_app/)
<?xml version="1.0"?>
<!DOCTYPE app SYSTEM "FabricApp.dtd">
<app name="hello_world_cpp_app" version="1.0">
<tasks>
<file name="hello_world_task.xml"/>
</tasks>
<process-flows>
<file name="hello_world_flow.xml"/>
</process-flows>
</app>
This document only describes the elements used in the example. Read more about Fabric Application Definition XML.