aboutsummaryrefslogtreecommitdiff
path: root/doc/gnunet-exercise.tex
blob: 1845e0eb7c451abe95a17113549bccb7d72a6fb4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
\documentclass[10pt]{article}
\usepackage[ansinew]{inputenc}
\usepackage{makeidx,amsmath,amssymb,exscale,multicol,epsfig,graphics,verbatim,ulem}
\usepackage{epsfig,geometry,url,listings}
\geometry{headsep=3ex,hscale=0.9}
\usepackage{hyperref}
\hypersetup{
  pdftitle={gnunet-java tutorial},
  pdfsubject={gnunet-java},
  pdfauthor={Florian Dold <dold@in.tum.de>},
  pdfkeywords={gnunet,java},
  colorlinks=true,
  urlcolor=blue
}

\title{Introduction to gnunet-java}
\author{Florian Dold}
\date{}

\begin{document}

\maketitle


\section{Prerequisites}
This tutorial assumes that you have gnunet$\geq$0.9.2 installed on your system.
Instructions on how to do this can be found at \url{https://gnunet.org/installation}.

TODO: remark about ./configure --enable-javaports / port configuration

Make sure that the default gnunet services are running by typing
\begin{lstlisting}
gnunet-arm -I
\end{lstlisting}
on your command line.

\section{Installing gnunet-java}
Check out the latest version of gnunet-java with
\lstset{language=bash}
\begin{lstlisting}
svn checkout https://gnunet.org/svn/gnunet-java/
\end{lstlisting}
as well as the template directory for extensions with
\begin{lstlisting}
svn checkout https://gnunet.org/svn/gnunet-java-ext/
\end{lstlisting}


\section{First Steps}
Programs to communicate with gnunet are located unter the bin/ directory. You can add this directory to your path,
otherwise you have to prefix every command with this directory.

To test if everything is working, try to run the program gnunet-nse. This should show you the estimated current size
of the network.

\subsection{Project Layout}
src contains the source code of gnunet-java, test contains test cases, bin contains wrappers arround main classes,
tools contain scripts used for development.

gnunet-java-ext has a similar structure.


\section{Creating an extension}
create a copy of gnunet-java-ext and rename it to gnunet-java-hellognunet.

\subsection{configuring your extension}
describe the classpath config file, the shell wrapper

\section{A simple gnunet-java program}
\lstset{language=java}
\begin{lstlisting}
public class HelloGnunet {
    public static void main(String[] args) {
            new Program(args) {
                public void run() {
                    System.out.println("Hello, gnunet");
                }
            }.start();
}
\end{lstlisting}

The Program class takes care of parsing command line arguments (thus it's constructur gets the args array passed)
and loading the gnunet configuration files (accessed by Program.getConfiguration())
(talk about scheduler/asynchronous stuff)

\subsection{Adding and using command line arguments}
Command line options are added by annotating members of your org.gnunet.util.Program-subclass
with the \@Option-annotation.

Let's start with an example:

\lstset{language=java}
\begin{lstlisting}
new Program(args) {
    @Option(
        shortname = "n",
        longname = "name",
        action = OptionAction.STORE_STRING,
        description = "the name of the person you want to greet")
    String name;
[...]
}
\end{lstlisting}

The command line program can now be called with -nXXX or --name=XXX.
Inside of the run-method, the class member 'name' will then be initialized with the passed argument,
or null if the option has not been passed.

The \@Option annotation can not only be used with Strings, but also with booleans and numbers.

(reference the java docs)

By default, the following arguments are available on the command line

(table comes here)

You can change the about text and the version by subclassing the getVersion / getAboutTest methods in your Program subclass.


\subsection{Using an existing service API}
In this section we will use the gnunet statistics api to track how often the HelloGnunet program
has been run.
\subsubsection{Establishing a connection to the statistics service}

\begin{lstlisting}
Statistics statistics = new Statistics(cfg);
\end{lstlisting}

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 you have to wrap your program in the run method: Once all your asynchronous calls are
made, the run method returns, and gnunet-java hast to keep the system running until all work has been done.

\begin{lstlisting}
statistics.set(RelativeTime.SECOND, "gnunet-java-ext-hello", "has said hello", 1,
    new SetCompleted() {
        @Override
        public void onCompleted() {
            System.out.println("done.");
        }

        @Override
        public void onTimeout() {
            System.out.println("timeout while setting");
        }});
\end{lstlisting}


\section {Overview of useful APIs}
statistics

dht
* explain dht-put and dht-get / one example

core
* explain API, maybe refer to example code


\section{Creating a new gnunet-java service}

\subsection{Defining new Messages}
All gnunet services have a common communication protocol.
Every message consists of a header (with the message size and the message type), and a body.

You can define a new type of Message in gnunet-java by annotating a class with 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.

\begin{lstlisting}
@UnionCase(4242)
public class HelloWorldMessage implements GnunetMessage.Body {
    @UInt8
    public int age;
    @ZeroTerminatedString;
    public String name;
}
\end{lstlisting}
Todo: explain the above


Other useful annotations are:
...


Running the msgtypes-tool:

\subsection{Implementing the Service}
Similarily to Program.run, Service.run is the entry point of every gnunet-java service.
It's members can be annotated with the same command line parsing options as in Program.

The first difference is that every Service has at least one server, waiting on new clients to connect.
When implementing a Service, you have to specify the kind of messages you are interested in.

The basic skeleton for a Service looks like this:

\subsubsection{Talking back to a client}
explain Client.this.notifyTransmitReady(...)

\subsection{Creating the configuration file}
For every service ther is a configuration file that specifies
over which port the service is reachable. Other options in the configuration can be used to
configure the service without touching the code or implementing your own configuration.

[provide example config file here]

\subsection{Using arm to start the service}

\section{Communicating with a Service directly}
\subsection{Using the client API}
\subsubsection{Creating a new Client}
\begin{lstlisting}
Client = new Client("hello-world-service", getConfiguration());
\end{lstlisting}
establishes a connection with the service named "hello-world-service". The necessary information (e.g. the right TCP/IP port) for connecting
to the service is is looked up under the section [hello-world-service] in the configuration.



\end{document}