gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r32924 - gnunet-java/doc


From: gnunet
Subject: [GNUnet-SVN] r32924 - gnunet-java/doc
Date: Mon, 7 Apr 2014 16:21:56 +0200

Author: dold
Date: 2014-04-07 16:21:56 +0200 (Mon, 07 Apr 2014)
New Revision: 32924

Modified:
   gnunet-java/doc/gnunet-java-tutorial.pdf
   gnunet-java/doc/gnunet-java-tutorial.tex
Log:
tutorial

Modified: gnunet-java/doc/gnunet-java-tutorial.pdf
===================================================================
(Binary files differ)

Modified: gnunet-java/doc/gnunet-java-tutorial.tex
===================================================================
--- gnunet-java/doc/gnunet-java-tutorial.tex    2014-04-07 14:14:40 UTC (rev 
32923)
+++ gnunet-java/doc/gnunet-java-tutorial.tex    2014-04-07 14:21:56 UTC (rev 
32924)
@@ -24,7 +24,7 @@
          {\\\$}{{\$ }}1
 }
 
-\newcommand{\exercise}[1]{\noindent\begin{boxedminipage}{\textwidth}{\bf 
Exercise:} #1 \end{boxedminipage}}
+\newcommand{\exercise}[1]{\vskip5pt\noindent\begin{boxedminipage}{\textwidth}{\bf
 Exercise:} #1 \end{boxedminipage}}
 
 \title{A Tutorial for GNUnet 0.10.x (Java version)}
 
@@ -34,7 +34,10 @@
 
 \maketitle
 
-Although GNUnet is primarily developed in the C programming language, it is 
also possible to write components in Java.
+Although GNUnet is primarily developed in the C programming language, it is 
also possible to write peer-to-peer applications
+with GNUnet in Java.
+The GNUnet-Java project provides bindings to a subset of existing GNUnet 
components, and provides the infrastructure to
+develop new components.  GNUnet-Java is less stable and less complete than the 
C version. Please report any bugs or feature requests at 
\url{https://gnunet.org/bugs/}.
 
 \section{Getting Started}
 \subsection{Installing GNUnet}
@@ -42,7 +45,7 @@
 machine.  Instructions on how to do this can be found at
 \url{https://gnunet.org/installation}, or in the C version of the GNUnet
 tutorial.  
-Make sure to run {\tt ./configure} with the option {\tt --enable-javaports}, 
in order to allow
+Make sure to run {\tt ./configure} with the option {\tt -{}-enable-javaports}, 
in order to allow
 Java clients to connect to GNUnet services.
 Start your GNUnet peer with the command {\tt gnunet-arm -s} and convince 
yourself that the default GNUnet services are running by typing {\tt gnunet-arm 
-I}.
 
@@ -70,11 +73,11 @@
 of Gradle on the first run.  Alternatively, download Gradle$\ge$1.11 yourself, 
and use the \texttt{gradle} command
 directly instead of the wrapper.
 
-Build the template project by running the \emph{assemble} task.
+Build the template project by running the \texttt{assemble} task:
 \begin{lstlisting}[language=bash]
 \$ ./gradlew assemble
 \end{lstlisting}
-This will download all required dependencies.  Gradle stores all dependencies 
in an internal cache.  Run
+This will download all direct and transitive dependencies.  Gradle stores all 
dependencies in an internal cache.  Run
 \begin{lstlisting}[language=bash]
 \$ ./gradlew copyDeps
 \end{lstlisting}
@@ -112,6 +115,10 @@
   Get the code above to execute by placing it in a \texttt{*.java} file
   in \texttt{src/main/java/}, running the \texttt{assemble} task from Gradle,
   and invoking \texttt{java} with the right parameters.
+The source code in the extension template should follow
+the the Maven Standard Directory Layout%
+\footnote{\url{https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html}}
+for application code, tests and resources.
 }
 
 \subsection{Adding and using command line arguments}
@@ -133,8 +140,8 @@
 \end{lstlisting}
 
 You can now specify a value for the member {\tt name} at the command
-line, either by the long name with two dashes ({\tt --name=Foo} / {\tt
-  --name FOO}) or the short name ({\tt -n FOO}) with one dash.
+line, either by the long name with two dashes ({\tt -{}-name=Foo} / {\tt
+-{}-name FOO}) or the short name ({\tt -n FOO}) with one dash.
 
 Before the \texttt{run} method is called, the field {\tt name} will
 be set to the given argument.  If the \texttt{name} option is missing,
@@ -152,11 +159,11 @@
 By default, the following arguments are available on the command line:
 
 \begin{itemize}
-\item {\tt -h} / {\tt --help} shows the help text
-\item {\tt -v} / {\tt --version} shows version information
-\item {\tt -c} / {\tt --config} specify an additional configuration file to 
load
-\item {\tt -L} / {\tt --log} specify the log level
-\item {\tt -l} / {\tt --logfile} specify a file to write the logs to
+  \item {\tt -h} / {\tt -{}-help} shows the help text
+  \item {\tt -v} / {\tt -{}-version} shows version information
+  \item {\tt -c} / {\tt -{}-config} specify an additional configuration file 
to load
+  \item {\tt -L} / {\tt -{}-log} specify the log level
+  \item {\tt -l} / {\tt -{}-logfile} specify a file to write the logs to
 \end{itemize}
 
 You can change the about text and the version information by
@@ -172,20 +179,17 @@
 classpath classpath relative to the location of the script file.  The shell 
wrappers
 should therefore always be kept in the \texttt{bin/} directory.
 
-\exercise{Copy the wrapper \texttt{bin/my-ext} and modify it so that
-calls your \texttt{HelloGnuNet} class.}
+\exercise{Copy the wrapper \texttt{bin/my-ext} and modify it to
+call your \texttt{HelloGnuNet} class.}
 
 \subsection{More Documentation}
-The documentation for \emph{gnunet-java} generated by Javadoc is available
+The documentation for \texttt{gnunet-java} generated by Javadoc is available
 at \url{https://gnunet.org/javadoc/}.
 
 \section{The statistics API}
+The statistics service allows to store numbers under a subsystem and a name.
+These values are available to other components, even after your program quits.
 
-In this section we will use the statistics API of GNUnet-Java. The statistics
-service allows to store numbers under a subsystem and a name, which
-are still available to you and other components of your peer after
-your program exits.
-
 \subsection{Connecting to the statistics service}
 
 \begin{lstlisting}[language=java]
@@ -194,14 +198,14 @@
 
 The Statistics constructor is called with the configuration,
 provided by the method {\tt getConfiguration} of the {\tt Program}
-class. This establishes a connection to the
+class.  This establishes a connection to the
 statistics service.  As with most API calls in GNUnet-Java, this
 operation is asynchronous.  This is one of the main reasons why one
-has to wrap teir program in the {\tt run} method of {\tt
+has to wrap their program in the {\tt run} method of {\tt
   Program}: Once all method calls are done, the run method
 returns, and GNUnet-Java keeps the system running until all work is done.
 
-Always remember that you always explicitly have to destroy your {\tt
+Always remember to explicitly destroy your {\tt
   Statistics} instance by calling its {\tt destroy()}
 method. Otherwise there might be pending operations that prevent the
 termination of your program.
@@ -209,9 +213,9 @@
 \subsection{Setting statistics}
 
 You can use the newly created {\tt statistics} handle to, for instance,
-set the value named ``\# bytes sent'' to the value 42. The \texttt{true}
-indicates that the value should be stored persistently.
-Persistent values are kept even if the statistics service restarts.
+set the value named ``\# bytes sent'' to the value 42. The last parameter 
(\texttt{true})
+indicates that the value should be stored persistently (%
+persistent values are stored even if the statistics service restarts).
 
 \begin{lstlisting}[language=java]
 statistics.set("gnunet-java-hello", "# bytes sent", 42, true);
@@ -219,11 +223,11 @@
 
 \subsection{Retrieving statistics}
 
-Retrieving a value is a little bit more complex. Because of the
+Retrieving a value is slightly more complex. Because of the
 asynchronous nature of the GNUnet-Java APIs, the {\tt get} method
 does not directly return values, but a handle (implementing the
-interface {\tt Cancelable}) to cancel the get request. The actual
-values are accessed by passing a callback object to the {\tt get}
+interface {\tt Cancelable}) to cancel the get request.
+The actual values are accessed by passing a callback object to the {\tt get}
 method.
 
 This example retrieves the statistics value ``\# Requests Served'' for the 
subsystem ``gnunet-java-hello''
@@ -237,31 +241,37 @@
         System.out.println(subsyste + " " + name + " " + val);
     }
     public void onTimeout() {
+        // called if the service does not respond after the
+        // specified timeout (one second)
         System.out.println("timeout occured");
     }
 });
 \end{lstlisting}
 
-\exercise{Write a program that sets statistics values, and check the result 
with the {\tt gnunet-statistics} command line tool.}
 \exercise{Read the Javadoc of the statistics service.  What other operations 
can be done on statistics values, other
 than reading and writing them?}
+\exercise{Write a program that increments a statistics value each second. 
Check the result with the {\tt gnunet-statistics} command line tool.
+\emph{Hint}: Use \texttt{Scheduler.addDelayed} to run a function after a 
timeout. }
 
+\section{Sending encrypted messages}
 
-\section{The core API}
+The CORE service is one of the most important components of GNUnet, and
+allows sending encrypted messages to directly connected peers.  Be aware that,
+depending on the used transport protocol, messages sent by CORE arrive with
+varying reliability.
 
-The core API allows sending encrypted messages to directly connected peers.
-
 \subsection{Defining new Messages}
 
 All GNUnet messages follow a common format.  Every
 message consists of a header (with the message size and the message
-type) and a body.
+type) and a body.  The same message format is used both for communication 
between
+GNUnet services and clients, as well as between peers in the network.
 
 You can define a new type of message in GNUnet-Java by annotating a
 class with information on how to represent its members in binary format.
 
 Additionaly, you have to register your new message type with
-GNUnet-Java, giving it a unique id.  Here is an example:
+GNUnet-Java, giving it a unique message type number.  Here is an example:
 
 \begin{lstlisting}[language=java]
 @UnionCase(4242)
@@ -281,7 +291,7 @@
 Every time you add a new type of GNUnet message, you have to run the command
 \lstset{language=bash}
 \begin{lstlisting}
-\$ gradle msgtypes
+\$ ./gradle msgtypes
 \end{lstlisting}
 This generates the file {\tt
   src/main/java/org/gnunet/construct/MsgMap.txt}, which allows the system to
@@ -336,7 +346,7 @@
 
 After specifing your message handler, the {\tt init} method has to be
 called with a callback object.  This starts the handshake with the
-core service, once done the callback object's {\tt onInit} method will
+core service, and once done the callback object's {\tt onInit} method will
 be called with your peer's identity.
 
 \subsection{Sending a message to another peer}
@@ -346,11 +356,12 @@
 the {\tt notifyTransmitReady} method. You have to provide a callback
 object to this method, whose {\tt transmit} method is invoked with a
 {\tt MessageSink} object once the core is ready to transmit your
-message.  Call the {\tt send} method in the {\tt MessageSink} in order
-to finally transmit it.
+message.  Call the {\tt transmit} method in the {\tt MessageSink}
+with a {\tt GnunetMessage.Body} in order transmit it to CORE.
+to finally transmit it. The header of the message is automatically
+added to your message body.
 
 Example:
-
 \begin{lstlisting}[language=java]
 // arguments: messagePriority, timeout, targetPeer, messageSize, transmitter
 core.notifyTransmitReady(0, RelativeTime.FOREVER, myIdentity, 42, new 
MessageTransmitter() {
@@ -367,9 +378,134 @@
 
 \exercise{Write an echo program for core: Send a message to the local peer and 
receive it!}
 
-\section{The Distributed Hash Table (DHT) API}
+\section{Establishing channels to remote peers with MESH}
+In contrast to CORE, the MESH
+service can send messages reliably (if requested) over channels to distant 
peers.
 
+The following code connects to the mesh service, and waits for connections on 
port 42:
+\begin{lstlisting}[language=java]
+Mesh m = new Mesh(cfg, inboundChannelHandler, messageHandler, 42);
+\end{lstlisting}
 
+The \texttt{inboundChannelHandler}'s \texttt{onInboundChannel} is called 
whenever another peer wants to establish a connection
+to our peer on port 42.  The \texttt{messageHandle} must be a Runabout 
instance, and implement visit methods analogously to the
+CORE message handler in the previous section.
+
+The following snippet estavlishes a channel to the given peer on port 42, where
+the channel should not buffer data (first boolean argument) and be reliable 
(second boolean argument).
+\begin{lstlisting}[language=java]
+Channel c = m.createChannel(targetPeer, 42, true, true);
+\end{lstlisting}
+
+A channel can be used to send messages, which are first queued and then sent 
to the mesh service:
+\begin{lstlisting}[language=java]
+c.send(myMessage);
+\end{lstlisting}
+
+Using this way of sending messages may cause the message queue of the channel 
to fill up quickly.
+To prevent this, wrap the message in an \texttt{Envelope}, which can invoke a 
notification callback
+once the message has been sent to the service:
+\begin{lstlisting}[language=java]
+Envelope ev = new Envelope(myMessage);
+ev.notifySent(myNotifySentHandler);
+c.send(myMessage);
+// use ev.cancel() to abort sending the message
+\end{lstlisting}
+Note that the notification is called when the local MESH service accepts the 
message for further transmission,
+not when the target peer receives the message.
+
+\exercise{Write a netcat-style tool that allows to interactively send and 
receive a stream of text on the command line over MESH.}
+
+\section{Managing a peer's egos}
+An ego in GNUnet is a name tied to a key pair. Egos can represent the identity 
of actual users, organisations,
+or more abstract entities.  Managed by the \texttt{IDENTITY} service, egos are 
entirely local to your peer.
+
+For looking up the key of egos, there is a convenient helper function:
+\begin{lstlisting}[language=java]
+Identity.lookup(getConfiguration(), "my-ego-name", new IdentityCallback() {
+    @Override
+    public void onEgo(Identity.Ego ego) {
+        System.out.println("public key: " + ego.getPublicKey());
+        });
+    }
+    @Override
+    public void onError(String errorMessage) {
+        System.err.println("lookup failed: " + errorMessage);
+    }
+});
+\end{lstlisting}
+Creating, renaming and deleting egos requires a handle to the identity service:
+\begin{lstlisting}[language=java]
+Identity identity = new Identity();
+identity.connect(getConfiguration(), null);
+\end{lstlisting}
+The second parameter of \texttt{connect}, which is null in the above code, can
+be a listener object of type \texttt{IdentityListCallback}, and is called 
whenever an identity
+is added, deleted or changed.
+
+After connecting, identities can be created like this:
+\begin{lstlisting}[language=java]
+identity.create(myEgoName, new IdentityContinuation() {
+    @Override
+    public void onError(String errorMessage) {
+      System.out.println("create failed: " + error message);
+    }
+    @Override
+    public void onDone() {
+      System.out.println("create successful");
+    }
+});
+Renaming and deleting egos is done by similar means.
+\end{lstlisting}
+
+
+\section{Using the GNU Name System}
+Resolving and publishing name records in the network can be done with GNS, a 
secure
+and decentralized alternative to the widely used Domain Name System.
+Currently, GNUnet-Java only supports resolving names.
+
+Names must be looked up in a zone, which is simply an ego. 
+Run \texttt{gnunet-gns-import.sh} (distributed with the main GNUnet package) 
in order to
+set up GNS.
+
+Verify that this created a master-zone ego:
+\begin{lstlisting}[language=bash]
+\$ gnunet-identity -d # display all egos
+\end{lstlisting}
+
+Create an A-record in your your master-zone with:
+\begin{lstlisting}[language=bash]
+\$ gnunet-namestore -z master-zone -a -n myrecord -t A -V 1.2.3.4 -e never
+\end{lstlisting}
+
+The following snipped assumes that \texttt{master} is the ego with the name 
``master-zone'',
+as retrieved with the \texttt{Identity.lookup} function.
+\begin{lstlisting}
+final Gns gns = new Gns(getConfiguration());
+// look up an A record
+long typeId = GnsRecord.getIdFromString("A");
+gns.lookup("alice.gnu", master.getPublicKey(), typeId, 
GNS_LOOKUP_OPTION_DEFAULT,
+        null, new LookupResultProcessor() {
+    @Override
+    public void process(GnsRecord[] records) {
+        for (GnsRecord record : records) {
+            System.out.println("Record " +
+                record.getRecordData().asRecordString());
+        }
+    }
+});
+\end{lstlisting}
+A \texttt{GnsRecord} contains the record stored in binary form.
+Calling \texttt{getRecordData} on the record instantiates an object
+whose class is specific to the record type (e.g. \texttt{ARecordData}),
+or an object of type \texttt{UnknownRecordData} if GNUnet-Java does not support
+the given record type.
+
+\exercise{Read more about GNS at 
\url{https://gnunet.org/gns-namestore-editing}.}
+\exercise{Look at the Javadoc for \texttt{org.gnunet.gns.record}. What types 
of records are
+currently supported, which are missing?}
+
+
 \section{Other useful APIs}
 Some other useful service APIs currently implemented are NSE (in {\tt
   org.gnunet.nse.NetworkSizeEstimation}), a service that gives an
@@ -379,11 +515,14 @@
   (in {\tt org.gnunet.peerinfo.PeerInfo}), a service for
 retrieving information about other known peers.
 
-Note that some GNUnet services do not yet have Java bindings.
+The API to the TESTBED service, which allows to manage multiple peers
+for testing and evaluating GNUnet components, is partially implemented.
 
+Among the most important APIs still missing are FS (filesharing) and NAMESTORE 
(manages GNS zone entries).
+
 \section{Writing your own client and service}
 
-GNUnet is split up into many components, every component runs in its own
+GNUnet is split up into many components, with every component running in its 
own
 process.  In the previous sections you have used existing APIs to
 interface with other services written in C.  GNUnet-Java also provides
 the tools necessary to both directly interface with services yourself and
@@ -414,7 +553,7 @@
 
 \subsection{Writing a service}
 
-To implement your own service, just inherit {\tt org.gnunet.util.Service} 
instead of
+To implement your own service, inherit {\tt org.gnunet.util.Service} instead of
 {\tt org.gnunet.util.Program}. The main difference between {\tt Program} and 
{\tt Service} is that the
 {\tt Service} also creates a {\tt Server}, which waits for messages from 
clients.
 You can register a Runabout to receive messages from clients with
@@ -439,7 +578,7 @@
                     }
                 });
             }
-        }.start();
+        }.start(args);
     }
 }
 \end{lstlisting}
@@ -447,7 +586,7 @@
 Always remember to call {\tt getSender().receiveDone()}, as the server does 
not receive further messages
 until {\tt receiveDone} is called, in order to support flow control.
 The object returned by {\tt getSender()} has a {\tt notifyTransmitReady} 
method, which can be used
-to send messages to clients in a similar fashion to writing to CORE.
+to send messages to clients in a similar fashion to sending messages with CORE.
 
 \exercise{Look at the example service implemented in {\tt 
org.gnunet.ext.GreetingService}.
   Run the service ({\tt gnunet-service-greeting}), and connect to it with the 
client program
@@ -456,14 +595,4 @@
   another message type.}
 \exercise{Write an API for a GNUnet service that has not been implemented yet 
in gnunet-java and contribute it back to the project.}
 
-\section{MESH}
-TODO
-
-
-\section{The state of GNUnet-Java}
-
-The GNUnet-Java project is still somewhat unstable and under development, 
expect
-changes that break your stuff!  Please report any bugs or feature
-requests at \url{https://gnunet.org/bugs/}.
-
 \end{document}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]