From d52ac99539ea762434265263db086422b60fd69a Mon Sep 17 00:00:00 2001 From: Joseph Wayne Norton Date: Sat, 13 Nov 2010 00:54:03 +0900 Subject: [PATCH] declare 1st Draft status --- index.html | 2 +- misc-codes/ubf_bertrpc_plugin.erl | 52 ++++ ubf-user-guide.en.html | 423 ++++++++++++++++++++++++++---- 3 files changed, 420 insertions(+), 57 deletions(-) create mode 100644 misc-codes/ubf_bertrpc_plugin.erl diff --git a/index.html b/index.html index 5cb0be3..01ea414 100644 --- a/index.html +++ b/index.html @@ -1,6 +1,6 @@ -UBF Home Page

UBF Home Page


UBF, a framework for Getting Erlang to talk to the outside world. +UBF Home Page

UBF Home Page


UBF, a framework for Getting Erlang to talk to the outside world. This document and the corresponding open-source code repositories are based on Joe Armstrong’s original UBF site and code with an MIT license file added to the distribution. Since then, a large number of diff --git a/misc-codes/ubf_bertrpc_plugin.erl b/misc-codes/ubf_bertrpc_plugin.erl new file mode 100644 index 0000000..da73d9d --- /dev/null +++ b/misc-codes/ubf_bertrpc_plugin.erl @@ -0,0 +1,52 @@ +%%% -*- mode: erlang -*- +%%% @doc Sample BERT-RPC plugin. +%%% +%%% + +-module(ubf_bertrpc_plugin). +-behavior(ubf_plugin_stateless). + +%% Required (except keepalive/0) callback API for UBF stateless +%% implementations. +-export([info/0, description/0, keepalive/0]). +-export([handlerStart/1, handlerStop/3, handlerRpc/1, handlerEvent/1]). + +-import(ubf_plugin_handler, [sendEvent/2, install_handler/2]). + +-compile({parse_transform,contract_parser}). +-add_contract("ubf_bertrpc_plugin"). + +-include("ubf.hrl"). +-include("ubf_plugin_stateless.hrl"). + +info() -> + "I am a BERT-RPC server". + +description() -> + "A BERT-RPC server programmed by UBF". + +keepalive() -> + ok. + +%% @doc start handler +handlerStart(_Args) -> + ack = install_handler(self(), fun handlerEvent/1), + {accept,ok,none,unused}. + +%% @doc stop handler +handlerStop(_Pid, _Reason, _StateData) -> + unused. + +%% @doc rpc handler +%% @TODO Implement BERT-RPC 1.0 synchronous events +handlerRpc(Event) when Event==info; Event==description -> + ?S(?MODULE:Event()); +handlerRpc(Event) when Event==keepalive -> + ?MODULE:Event(). + +%% @doc event handler +%% @TODO: Implement BERT-RPC 1.0 asynchronous events +handlerEvent(Event) -> + %% Let's fake it and echo the request + sendEvent(self(), Event), + fun handlerEvent/1. diff --git a/ubf-user-guide.en.html b/ubf-user-guide.en.html index 97a68cf..c34a07a 100644 --- a/ubf-user-guide.en.html +++ b/ubf-user-guide.en.html @@ -1,6 +1,6 @@ -UBF User’s Guide DRAFT - UNDER CONSTRUCTION

UBF User’s Guide DRAFT - UNDER CONSTRUCTION

Revision History
Revision 0.12010/11/11

1. Preface

UBF is a framework that permits the Erlang to talk to the outside +UBF User’s Guide 1st DRAFT

UBF User’s Guide 1st DRAFT

Revision History
Revision 0.12010/11/12

Table of Contents

1. Preface
2. Introduction
3. Specifications
3.1. UBF(a)
3.1.1. Integer: [-][0-9]+
3.1.2. String: "…"
3.1.3. Binary: [0-9]+ ~…~
3.1.4. Atom: '…'
3.1.5. Tuple: { Obj1 Obj2 … ObjN-1 ObjN }
3.1.6. List: # ObjN & ObjN-1 & … & Obj2 & Obj1
3.1.7. Term
3.1.8. White space: \s \n \r \t , %…%
3.1.9. Tag: `…`
3.1.10. Register: >C C
3.1.11. Object
3.2. UBF(b)
3.2.1. Name: +NAME("…").
3.2.2. Version: +VSN("…").
3.2.3. Types: +TYPES.
3.2.4. State: +STATE.
3.2.5. Anystate: +ANYSTATE.
3.3. UBF(c)
3.3.1. Calls: Request $ ⇒ {Response, NextState} $
3.3.2. Casts: {'event_in', Event} $ or {'event_out', Event} $
4. Contracts & Plugins
4.1. Contract
4.2. Plugin
4.3. Importing Types
4.4. Compilation Errors
4.5. Miscellaneous
5. Transports
5.1. TCP/IP
5.1.1. UBF: Universal Binary Format
5.1.2. EBF: Erlang Binary Format
5.1.3. JSF: JavaScript Format
5.1.4. TBF / NTBF: Thrift Binary Format / Native Thrift Binary Format
5.1.5. Miscellaneous
5.2. HTTP
5.2.1. JSON-RPC
5.3. Miscellaneous
5.3.1. ETF: Erlang Term Format
5.3.2. LPC: Local Procedure Call
6. Servers
6.1. Stateless
6.2. Stateful
7. Clients
7.1. Erlang
7.2. Python
7.2.1. EBF
7.2.2. JSON-RPC
7.3. Java
7.3.1. UBF
8. Miscellaneous
8.1. Download
8.1.1. Download and install Git
8.1.2. Download the bom.sh tool and then download UBF
8.2. Build - Mandatory
8.3. Build - Optional
8.4. Testing
8.4.1. Unit Tests
8.4.2. EUnit Tests
8.4.3. QuickCheck Tests
8.5. GitHub - Forking Your Own Repositories
8.6. Utilities
8.6.1. Transaction Logging
8.6.2. Canonical Contracts
9. Reference
10. Appendix
10.1. Acknowledgments
10.2. ABNF Definition
10.2.1. UBF(a)
10.2.2. UBF(b)
10.2.3. UBF(c)

1. Preface

UBF is a framework that permits the Erlang to talk to the outside world [UBFPAPER]. The acronym "UBF" stands for "Universal Binary Format", designed and implemented by Joe Armstrong.

This document and the corresponding open-source code repositories hosted on github [UBF] are based on Joe Armstrong’s original UBF @@ -20,7 +20,7 @@ UBF(c) is a meta-level protocol used between a UBF client and a UBF server.

While the XML series of languages had the goal of having a human readable format the UBF languages take the opposite view and provide a -"machine friendly" format. UBF is designed to be easy to implement.

Figure 1. Programming By Contract

+"machine friendly" format. UBF is designed to be easy to implement.

Figure 1. Programming By Contract


Central to UBF is the idea of a "Contract" which regulates the set of legal conversations that can take place between a client and a server. @@ -97,11 +97,11 @@ double quote. Atoms are commonly found in symbolic languages like Lisp, Prolog or Erlang. In C, they would be represented by hashed strings. The essential property of an atom is that two atoms can be compared for equality in constant time. These are used for -representing symbolic constants.

3.1.5. Tuple: { Obj1 Obj2 … ObjN-1 ObjN }

Tuples are used to represent fixed numbers of objects. The byte -codes for "{" and "}" are used to delimit a tuple. Obj1, Obj2, ObjN-1, -and ObjN are arbitrary UBF(a) objects.

3.1.6. List: # ObjN & ObjN-1 & … & Obj2 & Obj1

Lists are used to represent variable numbers of objects. The first -object in the list is Obj1, the second object in the list is Obj2, -etc. Objects are presented in reverse order.

Lisp programmers will recognize # as an operator that pushes NIL (or +representing symbolic constants.

3.1.5. Tuple: { Obj1 Obj2 … ObjN-1 ObjN }

Tuples represent fixed numbers of objects. The byte codes for "{" +and "}" are used to delimit a tuple. Obj1, Obj2, ObjN-1, and ObjN are +arbitrary UBF(a) objects.

3.1.6. List: # ObjN & ObjN-1 & … & Obj2 & Obj1

Lists represent variable numbers of objects. The first object in +the list is Obj1, the second object in the list is Obj2, etc. Objects +are presented in reverse order.

Lisp programmers will recognize # as an operator that pushes NIL (or the end of list) onto the recognition stack and & as an operator that takes the top two items on the recognition stack and replaces them by a list cell.

3.1.7. Term

Terms represent primitive types and compound types.

3.1.8. White space: \s \n \r \t , %…%

For convenience, blank, carriage return, line feed, tab, comma, and @@ -221,8 +221,8 @@ and thus more specific when matching objects.

The "integer", "float", "binary", "string", "atom", "tuple", and "list" predefined types match directly to the corresponding primitive or complex type.

The "term" predefined type matches any object.

The "proplist" predefined type is a specialized version of the "list" -predefined type that matches the following types:

[{term(), term()}]

The "void" predefined type is used as a placeholder to describe the -return value of a function call that does not return to the caller.

The "ascii" attribute permits matches with binaries, strings, and +predefined type that matches the following types:

[{term(), term()}]

The "void" predefined type is a placeholder to describe the return +value of a function call that does not return to the caller.

The "ascii" attribute permits matches with binaries, strings, and atoms containing only ASCII values [RFC20]. Similarly, the "asciiprintable" attribute permits matches with only printable ASCII values.

The "nonempty" attribute permits matches with binaries, strings, @@ -247,7 +247,7 @@ transition is ignored and a "server broke contract" error response is returned to the client.

The states of the FSM may also be annotated with events expressed as "asynchronous" casts. Events are asynchronous casts either from the client to the server or from the server to the client. Please see -next section for additional details.

[Note]

The terminology of "call" and of "cast" to distinguish between +next section for additional details.

[Note]

The terminology of "call" and "cast" to distinguish between synchronous and asynchronous interaction is borrowed from Erlang.

3.2.5. Anystate: +ANYSTATE.

The "+ANYSTATE" section of UBF(b) can be used to define additional events that are valid in all states of the FSM.

Events are checked based on direction first, on the current state’s valid events next, and finally on the valid anystate events. Any cast @@ -408,7 +408,7 @@ considered as part of the overall UBF framework. Most importantly, applications can share and re-use the same UBF contracts and plugins irregardless of the network transport.

5.1. TCP/IP

5.1.1. UBF: Universal Binary Format

The name "UBF" is short for "Universal Binary Format". UBF is commonly used to refer to the network transport based on UBF(a) and to -the overall UBF framework.

See Section 3.1, “UBF(a)” for further details.

5.1.2. EBF: Erlang Binary Format

EBF is an implementation of UBF(b) but it does not use UBF(a) for the +the overall UBF framework.

See Section 3.1, “UBF(a)” for further information.

5.1.2. EBF: Erlang Binary Format

EBF is an implementation of UBF(b) but it does not use UBF(a) for the client and server communication. Instead, Erlang-style conventions are used instead:

  • Structured terms are serialized via the Erlang BIFs term_to_binary() @@ -451,7 +451,7 @@ like this:

       record (defined in the contract as "foo() =
     
           {"$T":[{"$A":"bar"}, 42]}

    However, it requires very little JavaScript code to convert objects with the "$R", "$T", and "$A" notation (for records, tuples, and -atoms) into whatever object is most convenient.

    See [UBF_JSONRPC] for further details.

    [Tip]

    Gemini Mobile Technologies, Inc. has implemented and open-sourced +atoms) into whatever object is most convenient.

    See [UBF_JSONRPC] for further information.

    [Tip]

    Gemini Mobile Technologies, Inc. has implemented and open-sourced a module for classifying the input character set to detect non-UTF8 JSON inputs [GMTCHARSET].

    5.1.4. TBF / NTBF: Thrift Binary Format / Native Thrift Binary Format

    TBF and NTBF is an implementation of UBF(b) but it does not use UBF(a) for the client and server communication. Instead, Thrift [THRIFT] @@ -486,13 +486,13 @@ impedance mismatch between the two approaches of Thrift and UBF can only be addressed by further development.

    [Caution]

    Currently, NTBF only implements the encoding and decoding of Thrift’s binary wire-protocol. Unlike standard Thrift clients and servers, a NTBF client and server must "manually" implement the -features provided by the Thrift IDL.

    See [UBF_THRIFT] for further details.

    5.1.5. Miscellaneous

    It is worthwhile to mention there are two new TCP/IP transports namely -PBF and ABF that are under investigation. The name "PBF" is short for -"Google’s Protocol Buffers Format" [PROTOBUF]. The name "ABF" is -short for "Avro Binary Format" [AVRO].

    5.2. HTTP

    5.2.1. JSON-RPC

    JSON-RPC [JSONRPC] is a lightweight remote procedure call protocol +features provided by the Thrift IDL.

    See [UBF_THRIFT] for further information.

5.1.5. Miscellaneous

It is worthwhile to mention two new TCP/IP transports namely PBF and +ABF under investigation. The name "PBF" is short for "Google’s +Protocol Buffers Format" [PROTOBUF]. The name "ABF" is short for +"Avro Binary Format" [AVRO].

5.2. HTTP

5.2.1. JSON-RPC

JSON-RPC [JSONRPC] is a lightweight remote procedure call protocol similar to XML-RPC. The UBF framework implementation of JSON-RPC brings together JSF’s encoder/decoder, UBF(b)'s contract checking, and -an HTTP transport.

Figure 2. Programming By Contract w/ Multiple Transports

+an HTTP transport.

Figure 2. Programming By Contract w/ Multiple Transports


As previously stated, central to UBF is the idea of a "Contract" which regulates the set of legal conversations that can take place between a @@ -500,7 +500,7 @@ client and a server. The client-side is depicted in "red" and the server-side is depicted in "blue". The client and server communicate with each other via a TCP/IP and/or HTTP.

Central to UBF is the idea of contract(s) can be shared and re-used by multiple transports. Any data that violates the same contract(s) is -rejected regardless of the transport.

See [UBF_JSONRPC] for further details.

5.3. Miscellaneous

Several transports that do not require an explicit network socket have +rejected regardless of the transport.

See [UBF_JSONRPC] for further information.

5.3. Miscellaneous

Several transports that do not require an explicit network socket have been added to the UBF framework. These transports permit an application to call a plugin directly without the need for TCP/IP or HTTP.

5.3.1. ETF: Erlang Term Format

The concept "ETF" was added to the UBF framework. This transport @@ -622,7 +622,8 @@ follows:

built-in calls by 'contract_manager_tlog' to the 'error_logger' module. If the 2-tuple representation is used and the boolean() member is 'false', then calls to 'error_logger' will not be - attempted. Default: 'undefined'. + attempted. Default: 'undefined'. See Section 8.6.1, “Transaction Logging” for further + information.
{'process_options', list()}
@@ -633,96 +634,406 @@ follows:

stop the server, instead stop the TCP listener that controls it. See the "proc_socket_server" Erlang module for extra details.

[Note]

The NTBF transport protocol is indirectly enabled by specifying the following options: [{'proto', 'tbf'}, {'serverhello', -'undefined'}, {'simplerpc', 'true'}].

6.1. Stateless

Under Construction - TODO

6.2. Stateful

Under Construction - TODO

7. Clients

7.1. Erlang

Under Construction - TODO

7.2. Python

7.2.1. EBF

Under Construction - To Be Added

7.2.2. JSON-RPC

Under Construction - To Be Added

7.3. Java

7.3.1. UBF

Under Construction - To Be Added

8. Miscellaneous

Under Construction - TODO

  • -download +'undefined'}, {'simplerpc', 'true'}].

6.1. Stateless

The stateless server provides a simplified callback API and +implementation in comparision to Joe Armstrong’s original UBF server. +The stateless server is helpful to applications that do not require +explicit state management by the UBF server.

The "ubf_plugin_stateless.hrl" Erlang header file defines the callback +APIs to be implemented by a stateless plugin. The five callbacks are +mandatory for all stateless plugins.

%% common callback API
+-spec info() -> string().
+-spec description() -> string().
+-spec handlerStop(Handler::pid(), Reason::term(), StateData::term()) ->
+                  NewStateData::term().
+
+%% stateless callback API
+-spec handlerStart(Args::term()) ->
+                  {accept, Reply::term(), StateName::atom(), StateDate::term()} |
+                  {reject, Reply::term()}.
+-spec handlerRpc(Call::term()) -> Reply::term().

The info/0 and description/0 functions provide short and long +information about the plugin’s service, respectively.

The handlerStart/1 function is called when starting a new session for +the plugin’s service. The plugin may accept or reject the start +session request. When accepted, the plugin returns the reply for the +client, the name of the state to be used for the entire session, and +optional data for the state. When rejected, the plugin returns the +error for the client.

The handlerStop/3 function is called when stopping a session of the +plugin’s service. The plugin may perform some cleanup inside the +handlerStop function.

The handlerRpc/1 function is called when processing a synchronous call.

For example, the following "skeleton" implementation of a [BERTRPC] +server implemented by UBF illustrates a typical stateless server. The +source code for this implementation can be found on github +[UBF_BERTRPC].

%%% -*- mode: erlang -*-
+%%% @doc Sample BERT-RPC plugin.
+%%%
+%%%
+
+-module(ubf_bertrpc_plugin).
+-behavior(ubf_plugin_stateless).
+
+%% Required (except keepalive/0) callback API for UBF stateless
+%% implementations.
+-export([info/0, description/0, keepalive/0]).
+-export([handlerStart/1, handlerStop/3, handlerRpc/1, handlerEvent/1]).
+
+-import(ubf_plugin_handler, [sendEvent/2, install_handler/2]).
+
+-compile({parse_transform,contract_parser}).
+-add_contract("ubf_bertrpc_plugin").
+
+-include("ubf.hrl").
+-include("ubf_plugin_stateless.hrl").
+
+info() ->
+    "I am a BERT-RPC server".
+
+description() ->
+    "A BERT-RPC server programmed by UBF".
+
+keepalive() ->
+    ok.
+
+%% @doc start handler
+handlerStart(_Args) ->
+    ack = install_handler(self(), fun handlerEvent/1),
+    {accept,ok,none,unused}.
+
+%% @doc stop handler
+handlerStop(_Pid, _Reason, _StateData) ->
+    unused.
+
+%% @doc rpc handler
+%% @TODO Implement BERT-RPC 1.0 synchronous events
+handlerRpc(Event) when Event==info; Event==description ->
+    ?S(?MODULE:Event());
+handlerRpc(Event) when Event==keepalive ->
+    ?MODULE:Event().
+
+%% @doc event handler
+%% @TODO: Implement BERT-RPC 1.0 asynchronous events
+handlerEvent(Event) ->
+    %% Let's fake it and echo the request
+    sendEvent(self(), Event),
+    fun handlerEvent/1.

The above example also introduces three new concepts:

  • +The install_handler/2 and handleEvent/1 functions illustrate how to + receive asynchronous casts sent from the client to the server. The + handler fun Fun should be a function of arity 1. When an + asynchronous UBF message is received, the callback function is + called with the event as its single argument. The Fun is called by + the ubf plugin handler process so the Fun can crash and/or block + this process. The Fun should also return the same or a new Fun for + the next asynchronous event. If the Fun must maintain its own + state, then an intermediate anonymous fun must be used to to bind + the state.
  • -build +The sendEvent/2 function illustrates how to send asynchronous casts + from the server to the client.
  • -test +The "?S(X)" macro definition plus other helpers are located in the + "ubf.hrl" Erlang header file. For Erlang, the implementation of a + UBF string is a two tuple having '#S' as the first element and a + list of integers as the second element. A similar technique is also + used for the implementation of a UBF proplist (i.e. '#P' and + "?P(X)). +

6.2. Stateful

The stateful server is Joe Armstrong’s original UBF server. The +stateful server permits a plugin to transition from one state to +another and also supports a manager framework for managing application +state between multiple clients.

The "ubf_plugin_stateless.hrl" Erlang header file defines the callback +APIs to be implemented by a stateful plugin. The eight callbacks are +mandatory for all stateful plugins.

%% common callback API
+-spec info() -> string().
+-spec description() -> string().
+-spec handlerStop(Handler::pid(), Reason::term(), StateData::term()) ->
+                  NewStateData::term().
+
+%% stateful callback API
+-spec handlerStart(Args::term(), Manager::pid()) ->
+                  {accept, Reply::term(), StateName::atom(), StateDate::term()} |
+                  {reject, Reply::term()}.
+-spec handlerRpc(StateName::atom(), Call::term(), StateDate::term(), Manager::pid()) ->
+                {Reply::term(), NewStateName::atom(), NewStateData::term()}.
+
+-spec managerStart(Args::term()) ->
+                   {ok, ManagerData::term()}.
+-spec managerRestart(Args::term(), Manager::pid()) ->
+                     ok | {error, Reason::term()}.
+-spec managerRpc(Args::term(), ManagerData::term()) ->
+                 {ok, NewManagerData::term()} | {error, Reason::term()}.

The info/0 and description/0 functions provide short and long +information about the plugin’s service, respectively.

The handlerStart/2 function is called when starting a new session for +the plugin’s service. The plugin may accept or reject the start +session request. When accepted, the plugin returns the reply for the +client, the name of the initial state to be used for the session, and +optional data for the state. When rejected, the plugin returns the +error for the client.

The handlerStop/3 function is called when stopping a session of the +plugin’s service. The plugin may perform some cleanup inside the +handlerStop function.

The handlerRpc/1 function is called when processing a synchronous +call.

The managerStart/1 function is called once at the start of the +server’s initialization for each plugin’s service.

The managerRestart/2 function is called to restart a plugin’s service.

The managerRpc/2 function is called when processing a call from +handler. A handler uses the ubf_plugin_handler:ask_manager/2 function +API to make a synchronous call to the manager.

For an example stateful server plugin, please see the +"src/Unit-Test-Files/irc_plugin.erl" Erlang module in the [UBF] +repository. This plugin is the actual server-side implementation for +the IRC protocol application described earlier.

7. Clients

7.1. Erlang

The UBF framework provides two types of Erlang clients: "rpc" and +"lpc". The rpc client is the default client that supports +TCP/IP-based and ETF transports. The lpc client is an alternative +client for making a synchronous local procedure call to a plugin’s +implementation.

The "ubf_client" Erlang module implements most of the commonly-used +client-side functions and contains the implementation for the two +types of Erlang clients.

-module(ubf_client).
+
+-type host() :: nonempty_string().
+-type ipport() :: pos_integer().
+-type name() :: atom().
+-type server() :: name() | pid().
+-type plugin() :: module().
+-type plugins() :: [plugin()].
+-type options() :: [{atom(), term()}].
+-type service() :: {'#S', nonempty_string()} | undefined.
+-type statename() :: atom().
+-type tlogger() :: module().
+
+-spec connect(host() | plugins(), ipport() | server()) ->
+              {ok, Client::pid(), service()} | {error, term()}.
+-spec connect(host() | plugins(), ipport() | server(), timeout()) ->
+              {ok, Client::pid(), service()} | {error, term()}.
+-spec connect(host() | plugins(), ipport() | server(), options(), timeout()) ->
+              {ok, Client::pid(), service()} | {error, term()}.
+
+-spec rpc(Client::pid(), Call::term()) -> timeout | term() | no_return().
+-spec rpc(Client::pid(), Call::term(), timeout()) -> timeout | term() | no_return().
+
+-spec stop(Client::pid()) -> ok.
+
+-spec sendEvent(Handler::pid(), Cast::term()) -> ok | no_return().
+
+-spec install_default_handler(Client::pid()) -> ack.
+-spec install_handler(Client::pid(), Fun::fun()) -> ack.
+
+-spec lpc(plugin(), Call::term()) -> term().
+-spec lpc(plugin(), Call::term(), statename()) -> term().
+-spec lpc(plugin(), Call::term(), statename(), tlogger()) -> term().

The connect/{2,3,4} functions connect to a UBF server. Upon success, +the UBF client’s pid() and the name of the UBF server’s service (if +known) is returned. For TCP/IP transports, the default method is to +connect to the specified host() and TCP ipport(). For the ETF +transport, the alternative method is to connect to server() using the +specified plugins(). The server() is either the process id or process +registered name for an already-started UBF server. See Section 6, “Servers” +for a description of options().

The rpc/{2,3} functions make a synchronous call to the server.

The stop/1 function closes the connection with the server and stops +the client.

The sendEvent/2, install_default_handler/1, and install_handler/2 +functions behave in the same way as the server-side implementation to +send and receive asynchronous casts.

The lpc/{2,3,4} functions make a synchronous local procedure call to a +plugin’s implementation. Regarding the tlogger(), see Section 8.6.1, “Transaction Logging” for +further information.

7.2. Python

7.2.1. EBF

Under Construction - To Be Added

7.2.2. JSON-RPC

Under Construction - To Be Added

7.3. Java

7.3.1. UBF

Under Construction - To Be Added

8. Miscellaneous

8.1. Download

8.1.1. Download and install Git

Download and install [GIT].

Then append the following lines to your ~/.gitconfig file:

[url "git://github.com/norton/gmt-bom.git"]
+     insteadOf = git://github.com/norton/src/erl-tools/gmt-bom.git
+[url "git://github.com/norton/ubf.git"]
+     insteadOf = git://github.com/norton/src/erl-tools/ubf.git
[Note]

UBF requires git version 1.7.x or newer. UBF has been tested +most recently with git version 1.7.1.1.

8.1.2. Download the bom.sh tool and then download UBF

Follow these steps:

$ mkdir -p ~/work/ubf
+$ cd ~/work/ubf
+$ git clone git://github.com/norton/bom.git .
+$ env BOM_GIT=git://github.com/norton/ ./bom.sh co src/erl-tools/ubf
[Tip]

The bom.sh commands diff and status can be used to check the +differences and status of all components, respectively. Type +./bom.sh help for further information.

[Note]

The Bill of Materials (BOM) system is a way to manage the builds +of heterogeneous products with shared components using GIT, GIT-SVN, +SVN, or CVS. BOM maintains hierarchical dependencies between modules +stored in a source code repository. BOM is implemented using bash, +make, and other UNIX tools.

[Note]

The BOM system was originally developed by Gemini Mobile +Technologies as an in-house tool to build and to package it’s own +commercial products. BOM as been open-sourced as one of the helper +tools for UBF.

8.2. Build - Mandatory

  1. +Get and install an [ERLANG] system +

    [Note]

    UBF requires Erlang/OTP R13B01 or newer. UBF has been tested +most recently with Erlang/OTP R13B04.

  2. +Change to your working directory and create the top-level Makefile +

    $ cd ~/work/ubf
    +$ ./bom.sh make
  3. +Build UBF +

    $ make ERL=/usr/local/hibari/ert/R13B04/bin/erl
    +  OR
    +$ make ERL=/usr/local/hibari/ert/R13B04/bin/erl DEBUG="+debug_info"
    [Note]

    Please specify the path to your erlang system’s erl executable.

    [Tip]

    DEBUG="+debug_info" will produce DEBUG enabled beam files.

  4. +Run the unit tests +

    $ make ERL=/usr/local/hibari/ert/R13B04/bin/erl test

8.3. Build - Optional

  1. +Run unit test for one module. +

    $ make ERL=/usr/local/hibari/ert/R13B04/bin/erl \
    +  DEBUG="+debug_info" \
    +  -C src/erl-tools/ubf__HEAD/src check
  2. +Clean one module +

    $ make ERL=/usr/local/hibari/ert/R13B04/bin/erl \
    +  DEBUG="+debug_info" \
    +  -C src/erl-tools/ubf__HEAD/src clean
  3. +Rebuild one module +

    $ make ERL=/usr/local/hibari/ert/R13B04/bin/erl \
    +  DEBUG="+debug_info" \
    +  -C src/erl-tools/ubf__HEAD/src
  4. +Generate EDocs for one module +

    $ make ERL=/usr/local/hibari/ert/R13B04/bin/erl \
    +  DEBUG="+debug_info" \
    +  -C src/erl-tools/ubf__HEAD/src edoc
  5. +Run dialyzer for one module (and it dependencies) +

    $ make ERL=/usr/local/hibari/ert/R13B04/bin/erl \
    +  DEBUG="+debug_info" \
    +  -C src/erl-tools/ubf__HEAD/src run-dialyzer
    [Caution]

    Dialyzer will not work unless all beam files have been +compiled with debug information.

8.4. Testing

8.4.1. Unit Tests

The unit tests in the "src/Unit-Test-Files" directory provide small +examples of how to use all of the public API. In particular, the +*client*.erl files contain comments at the top with a list of +prerequisites and small examples, recipe-style, for starting each +server and using the client.

8.4.2. EUnit Tests

The eunit tests in the "src/Unit-EUnit-Files" directory perform +several smoke and error handling uses cases.

8.4.3. QuickCheck Tests

The quickcheck tests and related helper libaries in the +"src/Unit-Quick-Files" directory have not been open sourced yet. +Please stay tuned!

See [QUVIQ] for further information about quickcheck.

8.5. GitHub - Forking Your Own Repositories

If you are interested in making your own changes to UBF or to one or +more of the other UBF-related repositories, it is a straigthforward +process to fork and to build your own repositories using [GITHUB]. +GitHub provides a friendly and easy to use environment for developers +and the like.

  1. +If you haven’t already done so, create your own account on GitHub + and setup access with your public ssh key. Next using your web + browser, login as yourself to GitHub. +
  2. +Choose all or a subset of the UBF-related repositories that you are + interested in forking. For the sake of an example, let’s choose + the ubf-bertrpc repository and open the front page of this + repository [UBF_BERTRPC] using your web browser. +
  3. +Click on the "Fork" button near the top of the page. This action + creates a clone of the ubf-bertrpc repository in your own account + on GitHub.
  4. -utilities -

    • -txn logging -
    • -canonical contracts -

9. Reference

+Edit and/or append the following lines to your ~/.gitconfig file: +

[url "git://github.com/norton/gmt-bom.git"]
+     insteadOf = git://github.com/norton/src/erl-tools/gmt-bom.git
+[url "git://github.com/norton/ubf.git"]
+     insteadOf = git://github.com/norton/src/erl-tools/ubf.git
+[url "git@github.com:YOURLOGIN/ubf-bertrpc.git"]
+     insteadOf = git://github.com/norton/src/erl-tools/ubf-bertrpc.git
[Caution]

Make sure to replace YOURLOGIN with your GitHub account name.

  • +Follow similar steps as described in Section 8.1, “Download” but use + ubf-bertrpc as the target instead of ubf. +

    $ mkdir -p ~/work/ubf-bertrpc
    +$ cd ~/work/ubf-bertrpc
    +$ git clone git://github.com/norton/bom.git .
    +$ env BOM_GIT=git://github.com/norton/ ./bom.sh co src/erl-tools/ubf-bertrpc
  • +Follow same steps as described in Section 8.2, “Build - Mandatory” to build ubf-bertrpc. +
  • +Next, change directory into the ubf-bertrpc directory and create + a remote pointing to the UBF master repository. +

    $ cd src/erl-tools/ubf-bertrpc__HEAD
    +$ git remote add upstream git://github.com/norton/ubf-bertrpc.git
  • +Create a new remote branch to hold your changes. +

    $ git push origin origin:refs/heads/new_feature_name
  • +Start tracking the new branch. +

    $ git checkout --track -b new_feature_name origin/new_feature_name
  • As needed, pull in all changes from the master branch on the UBF +remote into your new branch.

    $ git pull upstream master

    8.6. Utilities

    8.6.1. Transaction Logging

    For Erlang, the UBF server and the UBF "LPC" client can be configured +to generate a transaction log. The transaction log module must +implement the following tlog/6 callback API.

    -type op() :: rpc | lpc | event_in | event_out.
    +-type now() :: {pos_integer(), pos_integer(), pos_integer()}.
    +-type plugin() :: module().
    +
    +-spec tlog(op(), Start::now(), plugin(), Q::term(), Reply::term(), Status::term()) -> ok.

    8.6.2. Canonical Contracts

    For documentation purposes, it is helpful to generate a "canonical" +version of a UBF contract. This feature is especially helpful when +importing UBF(b) types from one or more plugins.

    For UBF, the ubf_utils:ubf_contract/{1,2} functions are available for +this purpose. For JSON-RPC (and JSF indirectly), the +jsf_utils:ubf_contract/{1,2} functions are available for this purpose.

    9. Reference

    [AVRO] "Avro is a serialization system.", - http://avro.apache.org/. + http://avro.apache.org. -

    +

    -[GMTCHARSET] "Gemini Mobile Technologies, Inc. Charset Module", - http://github.com/norton/gmt-util/blob/master/src/gmt_charset.erl. +[BERTRPC] "BERT and BERT-RPC 1.0 Specification", + http://bert-rpc.org. -

    +

    + +[ERLANG] "A general-purpose programming language and runtime + environment", http://www.erlang.org. + +

    + +[GIT] "Fast Version Control System", http://git-scm.com. + +

    + +[GMTCHARSET] "Gemini Mobile Technologies, Inc. charset module", + https://github.com/norton/gmt-util/blob/master/src/gmt_charset.erl. + +

    + +[GITHUB] "Secure source code hosting and collaborative + development ", https://github.com. + +

    [JSONRPC] "A lightweight remote procedure call protocol similar - to XML-RPC", http://json-rpc.org/. + to XML-RPC", http://json-rpc.org. -

    +

    [MOCHIJSON2] "MochiWeb is an Erlang library for building lightweight HTTP servers.", - http://github.com/mochi/mochiweb/blob/master/src/mochijson2.erl. + https://github.com/mochi/mochiweb/blob/master/src/mochijson2.erl. -

    +

    [PROTOBUF] "Protocol buffers are Google’s language-neutral, platform-neutral, extensible mechanism for serializing structured - data.", http://code.google.com/apis/protocolbuffers/. + data.", http://code.google.com/apis/protocolbuffers. -

    +

    + +[QUVIQ] "Quviq … amazing testing tools", + http://www.quviq.com/. + +

    [RFC20] Vint Cerf, "ASCII format for Network Interchange", RFC20, October 16, 1969. -

    +

    [RFC4627] D. Crockford, "The application/json Media Type for JavaScript Object Notation (JSON)", RFC4627, July 2006. -

    +

    [RFC5234] D. Crocker, Ed. Brandenburg, "Augmented BNF for Syntax Specifications: ABNF", RFC5234, January 2008. -

    +

    [THRIFT] "A software framework for scalable cross-language - services development.", http://incubator.apache.org/thrift/. + services development.", http://incubator.apache.org/thrift. -

    +

    -[UBF] "Universal Binary Format", http://github.com/norton/ubf/. +[UBF] "Universal Binary Format", https://github.com/norton/ubf. -

    +

    [UBF_ABNF] "Universal Binary Format and Augmented Backus-Naur - Form", http://github.com/norton/ubf-abnf/. + Form", https://github.com/norton/ubf-abnf. -

    +

    + +[UBF_BERTRPC] "Universal Binary Format and Binary ERlang Term + RPC", https://github.com/norton/ubf-bertrpc. + +

    [UBF_EEP8] "Universal Binary Format and Erlang Enhancement - Proposal 8", http://github.com/norton/ubf-eep8/. + Proposal 8", https://github.com/norton/ubf-eep8. -

    +

    [UBF_JSONRPC] "Universal Binary Format and JavaScript Object - Notation RPC", https://github.com/norton/ubf-jsonrpc/. + Notation RPC", https://github.com/norton/ubf-jsonrpc. -

    +

    [UBF_THRIFT] "Universal Binary Format and Thrift", - https://github.com/norton/ubf-thrift/. + https://github.com/norton/ubf-thrift. -

    +

    [UBFPAPER] Joe Armstrong, "Getting Erlang to talk to the outside world", Proceedings of the 2002 ACM SIGPLAN workshop on Erlang, pages 64-72, ACM Press, 2002. -

    +

    [UBFSITE] Joe Armstrong, http://www.sics.se/~joe/ubf/site/home.html, March 2003.