Quickstart

Creating a New Project form the Giter8 Template

We have created an template project so you can test our etcd client in a convenient manner.

If you want to use this template, firts install Conscript following the instructions in their official page. Next, install Giter8. Once Giter8 has been successfully installed, use the following command to call it:

g8 https://bitbucket.org/eiipii/scalaetcdhttpclienttemplate.g8

Call the command from the directory in which you wish to place the project.

There are two parameters that you can change in order to make things easier. The package parameter will be used to place your organization’s name in the project. The name parameter will name the project. This last parameter will also be used to name a couple of sample classes inside the template. You will be prompted for the values. Hitting enter will yield the default values. Also, if you wish to input the values of the variables through the commandline, use the following command:

g8 https://bitbucket.org/eiipii/scalaetcdhttpclienttemplate.g8 \
--name="the name of the project" --package="org.yourorganization"

By introducing a name using separate words you will get a project in which the sample classes have camel cased names, as in TheNameOfTheProjectSampleClass.

One of the classes is a test which returns the version of the etcd API. It uses a Docker container, so you will have to have Docker in order to run it. Also, you have to keep ports 4001 and 2380 free in order for the container to run properly.

If you want to build your own project on that template project, you are free to do so. Just add and remove the dependencies as you find most convenient.

Adding the Library to Your Project

The first thing you need to do is to add the library to your sbt project. Adding the following lines to the build.sbt file should suffice:

libraryDependencies += "com.eiipii" %% "etcdhttpclient" % "0.1.1"

As for a Maven project, add these lines to your pom.xml:

<dependency>
  <groupId>com.eiipii</groupId>
  <artifactId>etcdhttpclient_2.12</artifactId>
  <version>0.1.1</version>
</dependency>

EtcdClient Setup:

Let us say that you want to use EtcdClient in your code. First, import the client and the DSL for its configuration:

package yourpackage

import com.eiipii.etcd.client.{EtcdClient, EtcdConfiguration, EtcdDSL}

You would probably also need to import Scala Futures, and the Model package:

import com.eiipii.etcd.client.model._

import scala.concurrent.Future

In your code, remember to add an execution context for Scala Futures to work:

implicit val executionContext = ExecutionContext.Implicits.global

As for the tests, in addition to the previous imports, you might also need to set a patience configuration:

implicit val pc = PatienceConfig(Span(3, Seconds), Span(1500, Milliseconds))

Both – the execution context and the patience configuration – are explained in the documentation for Scala Futures.

Simple Configuration

In order to configure the client for making requests to etcd, first you have to establish an entrypoint. This could be an IP address:

//For an instance of etcd in your localhost listening to the standard port
val address: String = "http://127.0.0.1:4001"

val etcdCli = new EtcdClient(EtcdDSL.config(address))

Or it could be a full domain:

val domain: String = "http://www.mydomain.com"

val etcdCli = new EtcdClient(EtcdDSL.config(domain))

Configuration with Basic Authentication

You could also enable other security features. Go to Authentication Methods in order to learn more.

Configuration with TLS

The TLS security protocol is supported in etcd. See the V2 Security Model documentation in order to learn about the possible use cases of etcd with TLS. The following is an example of a possible configuration with TLS taken from our tests:

//Input a the certificates' and key's files as an InputStream
val clientCert = this.getClass.getResourceAsStream("/ssl/client.crt")
val keyFile = this.getClass.getResourceAsStream("/ssl/client_nopass.PKCS8")
val caCert = this.getClass.getResourceAsStream("/ssl/dev-ca.crt")

//Build an SslContext using an SslContextBuilder
val sslContext: = SslContextBuilder.forClient()
trustManager(caCert)
.keyManager(clientCert, keyFile)
.build()

//endpoint of an instance of etcd in the localhost listening to the standard port
val endpoint: String = s"https://localhost:4001"
//insecure client configured for requests to etcd
val etcdCli = new EtcdClient(EtcdDSL.config(endpoint))
//new client using loaded certificates and keys
val secureCli: EtcdClient = etcdCli.withTLS(sslContext)

This is just an example which works with a certain etcd configuration. Since this depends on how etcd is configured, each client setup for TLS will differ. Make sure to fill in the details for properly configuring the TLS protocol according to your needs. Also, look for io.netty.handler.ssl.SslContext in the Netty Javadoc and import the packages you need from that library.

A Sample Request

Let us set a key in etcd:

val backend1: List[String] = List("myloadbalancer","backends","b1","servers","httpd1")
val backendURL1: String = "http://172.0.0.1:80"

val backend2: List[String] = List("myloadbalancer","backends","b2","servers","httpd2")
val backendURL2: String = "http://172.0.0.2:80"

//The EtcdModel object has methods for creating EtcdKey's and EtcdValue's.
//These case classes are used as wrappers for the data used as input in requests.
//There are many such classes in the Model package.
val firstKey: EtcdKey = EtcdModel.fromPath(backend1)
val firstValue: EtcdValue = EtcdModel.value("foo")

val secondKey: EtcdKey = EtcdModel.fromPath(backend2)
val secondValue: EtcdValue = EtcdModel.value("bar")

//etcdCli is an instance of EtcdClient configured as above.
//The outcome of an operation is always a Result class wrapped around a future.
val backend1Set: Future[EtcdSetKeyResult] = etcdCli.setKey(firstKey, firstValue)
val backend2Set: Future[EtcdSetKeyResult] = etcdCli.setKey(secondKey, secondValue)

Remember that these are asynchronous operations, so they are not performed in order unless you compose them using the operations available in the Scala Futures library. Some examples of such composition are available in this document in the subsection titled A Possible Work Flow.

Furthermore, accessing the fields of the response returned by etcd is also only a matter of using the methods of the Scala Futures library, such as functional composition:

val storedValue: Future[EtcdValue] = backend1Set.map { response =>
  response match {
    case EtcdSetKeyResponse(headers, body) =>
      body.node.value
  }
}

All methods function similarly to the setKey method. Just input your data through the correct case class and make a request. Remember that most methods have some extra options. For instance, setKey allows you to set a “time to live” (TTL) span in seconds. The default option, however, is to set a key with no TTL (see EtcdClient.setKey).

Go to EtcdClient in order to read all about supported methods and all the options they feature.

Further Information:

We hope that this section helped you get started. For further details, see the rest of this document. Also, remember that there is a scaladoc, where you could get more details on the implementation.

If you wish to report a bug, go to our Open Support Repository and create an issue. This is a centralized repo for tracking issues over all of our open source projects. Also, take a look at the Open Support Repository in Waffle for a different interface. Don’t forget to use the etcdhttpclient label to help us keep things organized. Before adding an issue, please make sure that it is a new one.

You can also take advantage of our mailing list: etcdhttpclient@googlegroups.com.