Home

Awesome

HTTP Server For JSON Event Sourcing

This is a standalone HTTP server for interacting with JSON aggregates. On the write-side you can send commands, which are handled asynchronously. They are put on a Kafka command topic, which corresponds to the aggregate type in the command. This is acknowledged with a 202 HTTP status code (Accepted). Changes to aggregates come back through Server-Sent Events. This flow fits well with reactive clients.

The read-side is handled with MongoDB. You can fetch and search aggregates.

The supported paths and methods are explained in the repository pincette-jes-api.

One special path is <contextPath>/health, which just returns status code 200 (OK). This can be used for health checks.

Authentication

All requests should have a JSON Web Token, which may appear as a bearer token in the Authotrization header or the cookie named access_token. The configuration should have the public key with which the tokens can be validated.

Configuration

The configuration is managed by the Lightbend Config package. By default it will try to load conf/application.conf. An alternative configuration may be loaded by adding -Dconfig.resource=myconfig.conf, where the file is also supposed to be in the conf directory. If no configuration file is available it will load a default one from the resources. All configuration entries can be overridden with equivalent environment variables. The following entries are available:

EntryEnvvarMandatoryDefaultDescription
accessLogACCESS_LOGNofalseA boolean indicating if access log entries should be sent to the log topic, which should be set.
contextPathCONTEXT_PATHNo/apiThe URL path prefix.
environmentENVIRONMENTNoNoneThe name of the environment, which will be used as a suffix for the aggregates, e.g. tst, acc, etc.
fanout.uriFANOUT_URINoNoneThe URL of the fanout.io service.
fanout.privateKeyFANOUT_PRIVATE_KEYOnly when FANOUT_URI is presentNoneThe private key in PEM format with which the usernames are signed during the Server-Sent Events set-up.
fanout.publicKeyFANOUT_PUBLIC_KEYOnly when FANOUT_URI is presentNoneThe public key in PEM format with which the usernames are verified during the Server-Sent Events set-up.
jwtPublicKeyJWT_PUBLIC_KEYYesNoneThe public key string, which is used to validate all JSON Web Tokens.
kafkaKAFKA_*Nolocalhost:9092All Kafka settings come below this entry. So for example, the setting bootstrap.servers would go to the entry kafka.bootstrap.servers. The equivalent environment variable would then be KAFKA_BOOTSTRAP_SERVERS.
logLevelLOG_LEVELNoINFOThe log level as defined in java.util.logging.Level.
logTopicLOG_TOPICNoNoneThe Kafka topic where the log entries are sent to in the Elastic Common Schema.
metricsTopicMETRICS_TOPICNoNoneThe Kafka topic where the metrics entries are sent to in JSON. They are per minute and per aggregate/HTTP method.
mongodb.databaseMONGODB_DATABASENoesThe name of the MongoDB database.
mongodb.uriMONGODB_URINomongodb://localhost:27017The URI of the MongoDB service.
whoamiWHOAMINoNoneAn array of fields that are extracted from the JWT and put in a JSON object that becomes the value of the whoami cookie. The cookie can be used by clients to obtain basic information about the current user.

Metrics

If the metricsTopic configration entry is set, metrics messages are sent to it for every aggregate/HTTP method combination. This happens every minute. The messages look like this (the time is in milliseconds):

{
  "aggregate": "my_aggregate",
  "method": "GET",
  "minute": "2023-11-01T17:23:00Z",
  "requestCount": 245,
  "requestBytes": 2786,
  "responseBytes": 32152,
  "timeSpent": 12250,
  "averageRequestBytes": 11,
  "averageResponseBytes": 131,
  "averageTimeSpent": 50  
}

Building and Running

You can build the tool with mvn clean package. This will produce a self-contained JAR-file in the target directory with the form pincette-jes-http-<version>-jar-with-dependencies.jar. You can launch this JAR with java -jar, followed by a port number.

You can run the JVM with the option -mx128m.

Docker

Docker images can be found at https://hub.docker.com/repository/docker/jsoneventsourcing/pincette-jes-http. They expose port 9000. You can either use environment variables to configure them or add a configuration layer with a Docker file that looks like this:

FROM registry.hub.docker.com/jsoneventsourcing/pincette-jes-http:<version>
COPY conf/tst.conf /conf/application.conf

So wherever your configuration file comes from, it should always end up at /conf/application.conf.

Kubernetes

You can mount the configuration in a ConfigMap and Secret combination. The ConfigMap should be mounted at /conf/application.conf. You then include the secret in the configuration from where you have mounted it. See also https://github.com/lightbend/config/blob/main/HOCON.md#include-syntax.