This document seeks to provide the most condensed
possible introduction to SAND. The vast majority of detail has been
relegated to a reference implementation, with only a few of the more basic
points referenced here in the appendices. This introduction represents
an extensive reduction to the bare essentials, and should by no means be
understood to represent a complete description or specification.
SAND (Structs and Nodes Development) is a system architecture and
development platform for building highly flexible and scalable
applications. It is based on structs (which declare data), and nodes
(which receive and produce data), being highly leveraged from within a
fully supportive development environment.
In effect, SAND is a return to the simplicity of a struct declaration for data, and code module to work on it, but at a level that
The intention of SAND is to allow for immediate and continuous
application development, focusing almost exclusively on business logic
rather than underlying technologies. Wherever possible, code is
automatically generated from struct and/or node declarations, and the
business logic is insulated from specific implementations of messaging,
configuration, control, persistence or other technologies. Structs and nodes provide the
conceptual basis, and the development environment makes
the concepts executable.
The term "struct" is borrowed from the C programming language. Like in C, a struct declares a conglomeration of basic data elements. In SAND, structs are standard .java class files that form the meta-source for all data declarations. A struct will
int, long, double, String, Date, or
protected long userID;&
protected long administrators;&
protected BlackboardStruct workstate;)
protected NodeDeclarationStruct nodes;)
Structs form the basis for messages, which define the input and
output for nodes. Each struct definition generates a
corresponding message definition, so for example
BaseUserStruct.java generates the
message class, plus optional verb
messages used for instance management if declared. A message
extends the struct, and adds both autogenerated and manually created
utility methods to manipulate the data within the java runtime.
Structs may extend other structs. So for example
UserStruct.java might extend
and add other data elements useful to a particular application.
Inheritance allows for common code, while also allowing for customized
Struct declarations are leveraged to generate code for configuration,
control, messaging, caching, persistence, serialization etc. The use of
structs allows a data element to exist in a variety of forms (XML,
relational database row, HTML form data, message object etc) without having
to write interfacing and validation code for each format.
The term "node" is borrowed from graph theory, and reflects the graph
formed by the flow of messages in a running SAND system. In SAND, a node
is a java package containing code which is responsible for fulfilling a
single business logic function.
A node is specified by its declaration class. For example an
Authorizer node (in package xxx.xxx.Authorizer) would contain
AuthorizerNodeDecl.java class which is the node
declaration. From this, the SAND development environment will
automatically create an abstract
containing the base implementation code. The developer must then override
AuthorizerNode.java to form
the main processing entry point. All other classes and files in the
package are unrestricted.
A node declaration class must:
int, long, double, String, Date, or
int, long, double, String, Date
A node base class provides:
onReceivestubs and overloaded
Code in a node package:
The SAND development environment (sandbox) takes care of the majority of
"plumbing and processes" necessary in a development project. Creating a
sandbox is a significant effort, but is
both highly flexible and highly re-usable.
A sandbox includes (at a minimum) the basics
project, code generators, and the SAND configuration management tool (sandman). It will typically require additional
supporting technologies (version management, build tools, J2EE container,
database, XML serialization, web server or other UI rendering tools etc) to
be fully functional. The total installation of a sandbox is kept as simple
An installed sandbox includes all directory structures, automated build processes, documentation, and tools. While a complete list of sandbox services and usage is beyond the scope of this document, some of the more noteworthy points that occur during the product lifecycle include:
SAND/docs/index.html, which provides links to other documents in the
docsdirectory tree in addition to project navigation.
The simplicity of the struct declarations, and the verifiable behavior
of the system as a whole, provides enormous leverage at almost all points
in the product lifecycle. SAND provides huge advantages in initial
development, but its primary focus is on the application over time.
struct @tag declarations:
The SAND development environment supports at least the following javadoc tags and parameters for structs:
node @tag declarations:
The SAND development environment supports at least the following javadoc tags and parameters in node declarations:
onReceivemethod is generated in the node base class.
sendmethod is generated in the node base class.
querymethod is generated in the node base class.
onDeliverymethod is generated in the node base class.
Limited types for configuration parameters:
Configuration parameters are limited to the basic types, or arrays of
basic types, in order to provide a consistent configuration interface for
all nodes. Cramming more advanced information into these basic types
through serialized object forms, associated arrays etc. is strongly
discouraged. Where more advanced information is needed by the node, a
struct declaration should be created, with the instances loaded via query
at node initialization time.
All configuration parameters are declared locally to a specific node.
There is no inheritance between groups of nodes, nor is there any concept
of a global configuration attribute. Global values can be specified
through system variables.
Only data members in structs:
If a struct were allowed to declare a
public final static
member, or other data members that are not recognized as part of the
canonical form, then the message class would have access to data not
available in other data representations.
If a struct were allowed to declare methods of any kind, then the message class would have access to data manipulation logic that is not specified for other data representations.
While it may seem odd to only allow protected data elements in a java
class, this is necessary to produce a canonical data declaration which can
manifest itself across more representations than just java classes. Note
that additional data members, constants, methods etc can be added to the
resulting message through both automated and manual code generation, so in
practice this limitation is not a significant development issue.
A SAND development environment (sandbox) provides verb messages (generated from struct tag declarations) that have specific processing requirements. At a minimum, this includes:
public class BaseUserUpdate ... protected long messageID; protected long messageVersion; protected int action; // add|update|delete protected SandAttrVal messageData; ...Notes:
public class BaseUserCollection protected BaseUser baseUsers; ...Notes:
public class BaseUserQuery ... protected SandAttrVal matchInfo; ...Notes:
public class BaseUserHistory ... protected SandAttrVal matchInfo; ...Notes:
SAND development environment effort:
There is a tendency to begrudge the time spent up front in setting up a
development environment since it is not tied to a specific deliverable
feature. However this one aspect of software development frequently
results in an order of magnitude more work than initially estimated, and
ends up either getting done or manifesting itself as wasted development
time. In short you pay for the time either way, but if you do it up front
it takes less total time and development is more productive (and fun).
A quality development environment is part of "doing it right". The test
for if something was "done right" is increasing returns for decreasing
development effort over time.
The "basics" project ships as part of the sandbox, and provides the
fundamental declarations and code needed for SAND development. The basics
project is set up like any other SAND project so it serves as an example in
addition to providing the needed structs and nodes.
A partial sampling of the basics project includes:
protected String username;
protected String password;
protected String attr;
protected String val;
protected SandAttrValStruct data;
protected String classname;
protected String instanceName;
protected int status; // (INITIALIZING,RUNNING,SUSPENDED,STOPPED)
protected String name;
protected String description;
protected SandStructMessage initialData;
protected ServerDeclarationStruct servers;
protected String name;
protected String description;
protected NodeDeclarationStruct nodes;
protected String nodeClassName;
protected String nodeInstanceName;
protected ConfigParam configParams;
protected NodeDeclarationStruct helperNodes;
protected SandMessage messagesToSend;
protected CallResponseStruct queriesToMake;
protected CallResponseStruct queriesToAccept;
protected SandMessage expectedInput;
protected SandMessage query;
protected SandMessage response;
public int getStatus() // NORMAL, SYSERROR, SANDERROR, APPERROR
public String getErrorMessage()
public static RefManager getRefManager();
... methods to resolve ID references of all types ...
public void setUpdates(SandUpdateMessage updates);
public SandUpdateMessage getUpdates();
SAND configuration management tool (sandman):
A sandman implementation is a significant application, which among other things obviates the need for a separate "admin" application under most circumstances. It vastly simplifies many development, deployment, and testing tasks, and under most circumstances can be viewed as a "black box". However there are several aspects which are worth explicitly noting for comparison and implementation purposes:
A SAND application relies on sandman and the generated code, both of
which in turn rely on the supporting technology. This means that the same
application can be configured to run on a single small computer, or
multiple computers in multiple data centers, depending on the underlying
SAND directory structure:
A typical sandbox will assign specific semantics to reserved directory names. For example:
docsdirectory holds documentation files (typically HTML documents) and the generated javadoc directory if applicable
srcdirectory holds source code
builddirectory holds build automation files
envdirectory holds .jar files resulting from the build, and other files needed by the application for configuration or other purposes
testdirectory holds test configurations, test scripts and load test scripts generated from sandman (typically as XML files)
So a subsection of an actual SAND installation might look like:
Pushing the source three levels down is unfortunate, but unfortunately
fairly typical. It is possible to factor the source prefix directories,
but the build processing is usually slowed down far beyond any gain from a
more concise directory structure. The structure may improve as java
compilers continue to evolve.