# Vert.x Http Service Factory

The http service factory is a Vert.x service factory for deploying services from an http server. It it an alternative to the Maven Service Factory for using services hosted on a plain http server, e.g a JavaScript service zipped and hosted somewhere. Unlike the Maven Service Factory, the Http Service Factory does not provide any kind of classpath dependency resolution. To use this feature be sure that `io.vertx:vertx-http-service-factory:3.6.0.CR2` is in your classpath.

    vertx run https://myserver.net/myverticle.zip::my-service

Although it looks like an http URL, it is a verticle identifier with a factory bound to the https prefix (http also supported).

The service identifier is made up of the suffix to form an http URL or the archive that contains the service, followed by a double colon `::` and a service name.

The service name is used to find the service descriptor file inside the artifact which is named by the service name with a `.json` extension. This is explained in the Service Verticle Factory documentation.

For example, to deploy a service that exists in an hosted at `https://myserver.net/myverticle.zip` called `my-service` you would use the string `https://myserver.net/myverticle.zip::my-service`.

Given this string, the verticle factory will use the Vert.x http client try and download the resource `https://myserver.net/myverticle.zip`.

It then constructs a classpath including this archive and creates a classloader with that classpath in order to load the service using the standard Service Verticle Factory.

The Service Verticle Factory will look for a descriptor file called `my-service.json on the constructed classpath to actually load the service.

Given a service identifier the service can be deployed programmatically e.g.:

    vertx.deployVerticle("https://myserver.net/myverticle.zip::my-service", ...)

Or can be deployed on the command line with:

    vertx run https://myserver.net/myverticle.zip::my-service

The service name can be omitted when the service jar `META-INF/MANIFEST` contains a `Main-Verticle`entry that declares the verticle to run:

    vertx.deployVerticle("https://myserver.net/myverticle.zip", ...)

And the manifest contains:

    Main-Verticle: service:my.service

Of course it can be deployed on the command line with:

    vertx run https://myserver.net/myverticle.zip

## Deploying a Java service packaged as a fatjar

The deployer factory can also deploy a Java service packaged as a fatjar, i.e a jar that contains a Java service and all the classes needed to run, for example:

- the jar manifest contains the `Main-Verticle:myservice.json`

- `myservice.json` declares the service via `main:my.Verticle`

- the class `my.Verticle`

- all the classes needed by the verticle to run, for example Google Guava jar, etc…​

## Http client configuration

Files are downloaded using Vert.x http client, by default the https client is configured with the `ssl=true` and `trustAll=true`. The default client options can be overriden to use specific configurations with the vertx.httpServiceFactory.httpClientOptions system property and the vertx.httpServiceFactory.httpsClientOptions system property, these properties are valid for any http resource.

### Client authentication

The client supports basic authentication via the vertx.httpServiceFactory.authUsername and vertx.httpServiceFactory.authPassword system properties.

Authentication is done only for services (i.e basic authentication will not be done for key servers) and only using an https connection.

### Proxy server configuration

The http client can be configured to support a proxy server with the vertx.httpServiceFactory.proxyHost and vertx.httpServiceFactory.proxyPort system properties.

If you need more proxy configuration such as support for SOCKS or proxy authentication, you can use specify them in the vertx.httpServiceFactory.httpClientOptions instead.

    vertx run https://myserver.net/myverticle.zip \
      -Dvertx.httpServiceFactory.httpClientOptions="{\"proxyOptions\":{ \
         \"host\":\"proxy-host\", \
         \"port\":1234 \
         \"type\":\"SOCKS4\"
      } }"

Please see read the `HttpClientOptions` configuration for all the details;

## Public key servers

Signed artifacts signatures are verifed using a public key, public key are retrieved from a public key server.

The public key server uri can be configured with the vertx.httpServiceFactory.keyserverURITemplate system property. The URI template is used to create the public key URI this way:

    String.format(keyserverURITemplate, signature.getKeyID())

When the property is not set, the default public key server is the SKS OpenPGP Public Key Server server used and the uri template used is : `http://pool.sks-keyservers.net:11371/pks/lookup?op=get&options=mr&search=0x%016X` this server will server public key resources with the application/pgp-keys media type.

The Json format sent by Keybase.io is also support. Keybase.io can be used as a public key server with `https://keybase.io/_/api/1.0/key/fetch.json?pgp_key_ids=%016X` URI template.

## Validation policy

The validation policy governs how downloaded services are validated, the vertx.httpServiceFactory.validationPolicy system property configures the behavior of the verticle factory when it attemps to deploy a downloaded service file:

- none : the service file is just deployed as is

- verify : the service file is verified when there is a corresponding .asc signature file, otherwise it is not verified. If the signature cannot be verified, the deployment fails.

- mandatory: the service file must have a corresponding .asc signature file and the signature must be verified.

The default validation policy is_verify_*.

## Cache directory

The cache directory stores the files used by the http service factory after download:

- deployed services

- service signatures

- public keys

The cached files are named after the percent encoded download URL:

    -rw-r--r--  1 julien  staff   270 May  3 21:44 http%3A%2F%2Flocalhost%3A8080%2Fthe_verticle.zip
    -rw-r--r--  1 julien  staff   473 May  3 21:44 http%3A%2F%2Flocalhost%3A8080%2Fthe_verticle.zip.asc
    -rw-r--r--  1 julien  staff  1768 May  3 21:44 http%3A%2F%2Flocalhost%3A8081%2Fpks%2Flookup%3Fop%3Dget%26options%3Dmr%26search%3D0x9F9358A769793D09

The default cache directory .vertx can be set to a specific location with the vertx.httpServiceFactory.cacheDir system property.

## Examples

### Bintray

Bintray is a distribution platform that can be used for hosting files.

### Service zip

    > echo 'console.log("hello world")' > helloworld.js
    > echo '{"main":"helloworld.js"}' > helloworld.json
    > zip helloworld.zip helloworld.json helloworld.js

### Bintray hosting

Assuming you have a Bintray account:

- create a Bintray repository with the generic type, for instance testgenrepo

- in this repository create a package, for instance testpkg

- optionally edit the package and check the GPG sign uploaded files using Bintray’s public /private key pair.

- in this package create a version, for instance 1.0

- now upload the helloworld.zip file

- publish the files

The file are now hosted with an URL like : https://bintray.com/artifact/download/vietj/testgenrepo/helloworld.zip

If you have configured the GPG signature, you will have also the signature file https://bintray.com/artifact/download/vietj/testgenrepo/helloworld.zip.asc. It will be by default downloaded and validated with Bintray’s public key

Of course you can use your own keys for signing the files.

We can run this service with:

    vertx run https://bintray.com/artifact/download/vietj/testgenrepo/helloworld.zip::helloworld
    % Hello World
    Succeeded in deploying verticle