Skip to content

Step By Step: First Service

Tom Janson edited this page Aug 6, 2018 · 23 revisions

In this tutorial, you get an introduction to las2peer development. After this tutorial, you will know the basics of las2peer service development and testing. It does not include information on how to start a las2peer node via the L2pNodeLauncher tool to use it in a 'productive' environment. If you want to (only) learn about this, the tutorial on starting a las2peer network is suggested. Otherwise, we recommend this tutorial as your starting point into las2peer service development.

Please note that this tutorial uses Windows 8 as OS and Eclipse as IDE. If you use another OS or IDE, some of the steps or screenshots might slightly differ from your experience, but you still should be able to follow this tutorial.

1. Project Checkout and Import

So let's begin. First, we have to checkout the template project from GitHub. On the project's main GitHub page, on the right side you can find a "Download ZIP" button. Click this and extract the content to your chosen workspace. (You can delete the -master extension from the folder name):

project main folder

Now, open Eclipse and goto File → Import and select General/Existing Projects into Workspace. A window opens and you should select your workspace as the root directory. You then check the las2peer-Template-Project and click on finish:

import project

2. Adjusting the Service Name and Version

Don't be irritated by all the errors that are shown to you be Eclipse, this is just because we have not fetched any libraries yet, so you basically don't have las2peer at this point yet ;-)

We continue by changing the service name according to your desired choice. Please open the service.properties file (etcant_configuration). You now see four parameters, which you can adjust to your needs. (You could just leave everything as it is, of course, then you will create a service called servicePackage with its main class ServiceClass.) In this example, we changed the values to some alternative ones, just so you can see where else you have to adjust the projects settings if you change those. The alternative values are:

service.version=0.1
service.name=i5.las2peer.services.servicePackage
service.path=i5/las2peer/services/servicePackage
service.class=ServiceClass 

Now, we have to adjust our project's structure accordingly. Therefore, please rename the two packages according to the value you gave service.name (right-click on it → RefactorRename). A warning should pop up when you rename the second package, just continue there.

Next, please change the name of the ServiceClass.java file to the value you gave your service.class (your service name).

Next, please change the name of the service's configuration file in the ./etc folder to the canonical classname of your service with a .properties ending. In the template, rename the file ./etc/i5.las2peer.services.servicePackage.serviceClass.properties accordingly.

The following screenshot shows the renaming, left is the imported project and right the project with the names adjusted to the values above:

old and new project structure

The start script bin/start_network.[sh|bat] will be generated automatically according to the information given in the service.properties file.

3. Fetching Dependencies

Now we have to fetch the actual las2peer (and some additional) libraries to start service development.
Right-click on the build.xml and select Run asAnt build …. A window should open and you should check (only) get_deps as in the following screenshot:

fetching the libraries

You might need to refresh your view (right-click on project → Refresh) and all project errors should be gone now. Notice the new folder lib containing all your las2peer dependencies. If not, Eclipse might have deleted some imports during your renaming process (since those could not be resolved during that time). Just go over each marked error and you should see some correction suggestion like import some.class, which you can click and the error should be gone.

4. Going through the Code

Remark: We will not discuss all the details of a RESTful Web Service here. We just give you the minimal knowledge needed to run your first service. There exists an additional tutorial that covers RESTful development with las2peer in more detail, but it is recommended that you first gain a bit of knowledge of how RESTful architectures look like before you start with it, since it focuses more on the technical part.

The Service Class

Let's take a look at our main service class (MyNewServiceMainClass.java in our example). It starts with the package declaration and then there are some imports. Nothing fancy here, just plain old Java stuff. So next comes the class definition.

You might notice some annotations, such as @Path, which might be not intuitive. With this argument, we explain the WebConnector (or more specifically the RESTMapper, but this is not important at the moment) at which path our service can be reached via the HTTP / HTTPS protocol. A las2peer Connector realizes the communication from a las2peer node to the outside. So the WebConnector is the Connector implementation used for RESTful access via HTTP/HTTPS. In our example we use the path example.

REST services should extend the RESTService class to be invocable from the WebConnector. There also exist other services extending the Service class, which do not provide a RESTful interface.

Let's take a look at the class's content. It contains seven methods. The first method is called validateLogin(). Notice the @GET annotation and again the @Path. This means that the method can be reached via HTTP GET at the path example/validate (main class path and then the path of the individual method).

So what does it do? It creates a String and returns it. Ok, that's clear. The new part is here:

((UserAgent) getActiveAgent()).getLoginName()

While it might be somehow clear what the result of this might be, let's shortly try to understand what exactly is happening. In las2peer, every acting entity is an agent. So a user that calls a service's method is also an agent. So we tell the service to get the active (= calling) agent, then we cast it to a UserAgent (since, as previously said, all acting entities are agents, so the caller could also have been for example a ServiceAgent, which has no login name) to be able to get his login name.

The next method again has two annotations, @Post and @Path. The path contains a value in curly brackets. This value is used in the methods' declaration in the annotation @PathParam("input"). Here you can see one way of passing values to a las2peer service via HTTP / HTTPS. In this case, we can address the method via example/myMethodPath/ and then add the value we want to pass to it, so for example example/myMethodPath/aValue. The method itself just returns a String telling you what you have passed.

The Service Configuration File

Each las2peer service can define its own configuration in an external configuration file. All of these files are expected to be in the ./etc folder. The file name of a service's configuration file must be the canonical service class name followed by a .properties suffix. In our example, such a configuration file would be expected at ./etc/i5.las2peer.services.myNewService.myNewService.properties. In the example below, you find a sample configuration, as also contained in the bundled service config, which defines some configuration parameters to connect your service with a database backend. Syntax is simple: one parameter per line, key=value.

jdbcDriverClassName=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql://localhost:3306/
jdbcSchema=myschema
jdbcLogin=service_login
jdbcPass=service_pass

Parameter values in such a config files are then accessible as ready-to-use variables within Java code. Simply define field variables for the parameters in your Java code. las2peer will automatically add values from the configuration file at runtime.

private String jdbcDriverClassName, jdbcUrl, jdbcSchema, jdbcLogin, jdbcPass;
The Test Class

Now that we understand what our service looks like, let us take a look at the ServiceTest.java which uses JUnit to test our service.

Usually, las2peer test cases try to simulate a service call. This means that you need the following components setup before running your test:

  • a las2peer node
  • your service running at this node
  • a connector running at this node that supports your chosen communication method
  • a user agent that makes the service calls

These are the global variables declared at the beginning of our test class:

  • HTTP_ADDRESS
  • HTTP_PORT
  • node
  • connector
  • logStream
  • testAgent
  • testPass
  • testServiceClass
  • mainPath

The first two define the address and port on which the WebConnector is started. Node and connector are self explaining and the log stream is used to log all upcoming connector events and print them after a test case. The test agent is the user agent used for calling the methods and is unlocked by a pass-phrase. In this case, we use the agent adam from the so called MockAgentFactory that ships with las2peer for exactly those testing cases. The test service class is your service and the main path is the service path we defined at the beginning of our main service class.

Next, we have the startServer and shutdownServer methods. Since those are annotated with @BeforeClass / @AfterClass, they are executed once before the first test and after the last one. Their implementation is a pretty straight forward las2peer node setup / shutdown and will not be discussed in detail here.

Now we focus on the actual tests. The class contains two tests for the two example methods of our service. We will explain the first one in detail. Every test first sets up a so called 'MiniClient', of which you can think as your 'simulated web browser', so it is capable of communicating via HTTP addresses. We then set the address and login of the client and continue by setting a login of the test agent we predefined earlier. Now comes the interesting part. With

ClientResponse result = c.sendRequest("GET", mainPath + "validate", "");

we actually make the service call. It is stored in the variable result for later checks. The method takes three parameters. The first one is the HTTP method, in our example it is "GET". Next comes the path and the last one are parameters, which we don't use here. After the call, we can check the result for expected values. In this case, we check, if the HTTP response code is 200 and if the returned result contains the string adam (since this should be desired behavior of the method, as discussed in the previous section The Service Class). In the end we print out the result again for later reference. It will be stored in our test report. Please note that most of the test case is surrounded by a try-catch block that is responsible for catching all unexpected behavior. In this case, the tests will fail and you will get information on the failure in your test report.

5. Build & Test Your Service

So finally you made it through to the part where you can actually run and test your service :-). In Eclipse, right-click on the build.xml and select Run asAnt build …, just as you did when fetching the dependencies. Then select all and click Run. If you have done everything correctly, the script should run without an error and you should be able to find new log, service and export folders in your project. The export folder contains a folder test_reports where you can find the reports from your tests.

Alternatively, execute the following command on your shell (assuming you have ant and java executables on the path):

ant all

6. Next Steps

This concludes the first steps tutorial. You now should have a very basic idea about las2peer service development. Although we have not discussed every part of your project and how to actually use the compiled service, you know enough to start writing your service code and test it accordingly. The next tutorial on starting a las2peer network focuses more on how the structure of a las2peer node looks like and gives information on how a las2peer instance is set up (what to put in which folder and such things). If you intend to share any of the services you created with the Open Source community, then be sure to properly license your code, following our guidelines. You might also want to consider having your service host its own developer documentation with Swagger, following our guidelines.

Clone this wiki locally