Skip to content

Commit

Permalink
Merge pull request #410 from wuespace/TELESTION-472
Browse files Browse the repository at this point in the history
TELESTION-472 Update documentation and remove unused references
  • Loading branch information
pklaschka authored Jan 10, 2024
2 parents a6b814c + 0e4db70 commit 8e11049
Show file tree
Hide file tree
Showing 21 changed files with 252 additions and 71 deletions.
77 changes: 71 additions & 6 deletions backend-deno/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,31 @@ import {resolve} from "https://deno.land/std@0.183.0/path/mod.ts";
let args = Deno.args;
let natsModule = nats;

/**
* The NATS `JSONCodec`, re-exported for convenience.
*
* See https://docs.nats.io/using-nats/developer/receiving/structure for details.
*
* @example Encoding data into a `Uint8Array` to publish it to NATS
* ```ts
* import {JSONCodec} from "https://deno.land/x/telestion/mod.ts";
*
* const codec = JSONCodec();
*
* const encoded = codec.encode({foo: "bar"});
* console.log(encoded); // Uint8Array(13)
* ```
*
* @example Decoding a `Uint8Array` received from NATS
* ```ts
* import {JSONCodec} from "https://deno.land/x/telestion/mod.ts";
*
* const codec = JSONCodec();
*
* const decoded = codec.decode(msg.data);
* console.log(decoded); // {foo: "bar"}
* ```
*/
export const JSONCodec = nats.JSONCodec;

const StartServiceConfigSchema = z.object({
Expand All @@ -15,6 +40,21 @@ const StartServiceConfigSchema = z.object({
natsMock: z.unknown().optional(),
});

/**
* The minimal configuration for a Telestion service. Gets used internally by {@link startService}.
*
* See {@link MinimalConfig} for details about the resulting configuration object.
*
* @example Manually parsing the configuration
* ```ts
* import {MinimalConfigSchema} from "https://deno.land/x/telestion/mod.ts";
*
* const rawConfig: unknown = Deno.env.toObject();
*
* const config = MinimalConfigSchema.parse(rawConfig);
* console.log(config.SERVICE_NAME); // "my-service"
* ```
*/
export const MinimalConfigSchema = z.object({
NATS_URL: z.string(),
NATS_USER: z.string().optional(),
Expand All @@ -23,20 +63,45 @@ export const MinimalConfigSchema = z.object({
DATA_DIR: z.string(),
}).passthrough();

/**
* The minimal configuration for a Telestion service. Returned as `config` property by {@link startService}.
*
* ### Properties
* - `NATS_URL: string` The URL of the NATS server.
* - `NATS_USER?: string` The username for the NATS server.
* - `NATS_PASSWORD?: string` The password for the NATS server.
* - `SERVICE_NAME: string` The name of the service.
* - `DATA_DIR: string` The path to the data directory.
*
* Can also contain additional properties under `MinimalConfig[key: string]: unknown`.
*/
export type MinimalConfig = z.infer<typeof MinimalConfigSchema>;

// Development mode => use default values

/**
* Options passed to the {@link startService} function.
*
* ### Properties
* - `nats: boolean = true` Whether to enable NATS or not. Disabling NATS can be useful during development.
* - `overwriteArgs?: string[]` An array of arguments that should overwrite the CLI arguments. Useful for testing.
* - `natsMock?: unknown` A mock for the NATS module. Useful for testing.
*
* @see {@link startService}
*/
export type StartServiceConfig = z.infer<typeof StartServiceConfigSchema>;

/**
* Starts the service and returns the APIs available to the Telestion service.
* @param rawOptions The configuration for the service.
* @param rawOptions.nats Whether to enable NATS or not. Defaults to `true`.
* @param rawOptions.overwriteArgs An array of arguments that should overwrite the CLI arguments. Useful for testing.
* @param rawOptions.natsMock A mock for the NATS module. Useful for testing.
*
* @returns The APIs available to the Telestion service.
* ### Service APIs returned by this function
* - `nc: NATSConnection` The NATS connection object.
* - `messageBus: MessageBus` The NATS message bus. Alias for `nc`.
* - `dataDir: string` The path to the data directory.
* - `serviceName: string` The name of the service.
* - `config: MinimalConfig` The configuration of the service.
* @param rawOptions The configuration for the service. See {@link StartServiceConfig} for details.
*
* @throws If the service couldn't be started.
*
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/.pages
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ collapse: true
nav:
- Overview:
- index.md
- getting-started.md
- Concepts:
- service.md
- message-bus.md
- project-folder-structure.md
- Backend Development
- Frontend Development
- Deployment
Expand Down
1 change: 0 additions & 1 deletion docs/docs/Backend Development/.pages
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
nav:
- index.md
- typescript
- rust
- other-languages.md
- Service Behavior Specification: service-behavior
2 changes: 0 additions & 2 deletions docs/docs/Backend Development/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,4 @@ The most common way to write a backend service is to use TypeScript.

However, for some use cases, it may be necessary to write a backend service in other languages.

Even some of the core services provided out of the box are written in Rust. To learn how to write a service in Rust, see [Using Rust](rust/index.md).

You can even write a backend service in any language you want. The only requirement is that it can communicate with the NATS message bus. To learn how to write a service in other languages, see [Using other languages](other-languages.md).
18 changes: 3 additions & 15 deletions docs/docs/Backend Development/other-languages.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,12 @@ Every Telestion service receives at least the following environment variables:
**If your service doesn't receive any of these environment variables, it should exit with a non-zero exit code.**

!!! warning
There can be multiple instances of a service with the same name running at the same time. They are guaranteed to have the same configuration, apart from the `SERVICE_ID`. If you need a truly unique identifier, you can combine the `SERVICE_NAME` and the process ID.
There can be multiple instances of a service with the same name running at the same time. They are guaranteed to have the same configuration. If you need a truly unique identifier, you can combine the `SERVICE_NAME` and the process ID.

### Logging

Your service should log any "feedback" to `stdout` and `stderr`.

For logging data to files, you should use the [Standard Operations Library](#standard-operations-library).

### Queues

NATS allows you to create queue groups. This means that you can have multiple instances of the same service running, and they'll share the messages they receive.
Expand All @@ -63,20 +61,10 @@ While running, any Telestion service should respond (within 0.5 seconds) to requ
```json
{
"errors": 0, // or number of "recent" errors
"service": "my-service", // the SERVICE_ID
"name": "My Service" // the SERVICE_NAME
}
```

## Standard Operations Library

!!! info
The standard operations library is a library that provides a set of common operations that are used by many Telestion services. While it can be overwritten, every Telestion application comes with an implementation of these operations out-of-the-box that you can use.

### Data Logging

The standard operations library provides a simple way to log data to files.

To use it, publish a message to the `__telestion__/log/[category]` subject with the body you want to log. `[category]` is the category of the log message. It can be any string.
## Service Behavior Specification

The standard operations library then logs the message to the file `logs/[category].log` in your data directory.
A formal description of the behavior of a Telestion service is provided in the [Service Behavior Specification](service-behavior/README.md). It can be used to test libraries for writing Telestion services in other languages.
1 change: 1 addition & 0 deletions docs/docs/Backend Development/typescript/.pages
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ nav:
- configuration.md
- message-bus.md
- e2e-log-service.md
- samples.md
- "API Reference ↗️": https://deno.land/x/telestion/mod.ts
11 changes: 2 additions & 9 deletions docs/docs/Backend Development/typescript/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@

## Configuration Sources

!!! warning
This section is specific to TypeScript services. Only the environment variables are standardized and must be implemented for all Telestion services.

While services in other languages can use the same configuration sources, they aren't required to do so.

Services can be configured using the following sources:

- Environment variables
Expand All @@ -30,7 +25,6 @@ All these sources get combined into a single configuration object. If a configur
2. Environment variables
3. Configuration file


### Environment Variables

Environment variables are the most common way to configure a service. They are easy to use and supported by most platforms.
Expand Down Expand Up @@ -82,8 +76,8 @@ Configuration sources and their order of precedence.
Some configuration values are required for all services. These values are:

* `NATS_URL`: The URL of the NATS server to connect to.
* `NATS_USER`: The username to use when connecting to NATS.
* `NATS_PASSWORD`: The password to use when connecting to NATS.
* `NATS_USER` (if the NATS server requires authentication): The username to use when connecting to NATS.
* `NATS_PASSWORD` (if the NATS user requires authentication): The password to use when connecting to NATS.
* `SERVICE_NAME`: The name of the service. This is used to identify the service in the logs and in the NATS server. This is required for all services.
* `DATA_DIR`: The directory where the service can store data. This is required for all services.

Expand All @@ -101,7 +95,6 @@ Some configuration values are required for all services. These values are:
This way, you don't have to set all the required configuration values when running the service locally.

Without the `--dev` flag, the service fails if any of the required configuration values are missing.


## Accessing the Configuration

Expand Down
4 changes: 4 additions & 0 deletions docs/docs/Backend Development/typescript/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,7 @@ deno run --allow-all service.ts --dev
Now that you have a basic service running, you should have a look at how to make your service configurable.

[Read more about configuration](configuration.md){ .md-button }

If you prefer to learn by example, you can also have a look at the [samples](samples.md).

[Browse samples on GitHub](https://github.com/wuespace/telestion/tree/main/backend-deno/samples){ .md-button }
15 changes: 15 additions & 0 deletions docs/docs/Backend Development/typescript/samples.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Samples

You can find even more samples in the project's GitHub repository under `backend-deno/samples`:

[Browse samples on GitHub](https://github.com/wuespace/telestion/tree/main/backend-deno/samples){ .md-button }

## Running the samples

You can run all the samples using the `docker-compose.yml` file in the linked folder. Just run the following command:

```bash
docker-compose up
```

This will run all the samples, including the required NATS server.
4 changes: 0 additions & 4 deletions docs/docs/Deployment/concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,3 @@ A web server is server software, or hardware dedicated to running said software,
Telestion uses NATS as a message broker. It's required for the communication between the Telestion services (both backend and frontend).

NATS is a simple, secure and high-performance open source messaging system for cloud native applications, IoT messaging, and microservice architectures.




16 changes: 16 additions & 0 deletions docs/docs/Deployment/docker/index.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
# Docker Deployment

This document describes how to deploy Telestion using Docker.

## Guidelines

These guidelines are not strict rules, but they are recommended to follow. If you have a good reason to deviate from them, feel free to do so. Or in other words: If you don't know why you should deviate from them, don't do it.

### Images per Service Type

Depending on your project, it might make sense to have individual images for each service. However, for smaller projects, this is often both unnecessary and cumbersome. In this case, it is recommended to have one image for all services of a specific type.

For example, you would have one image for all Deno based Backend services, one for the frontend, and so on. This way, you won't have to build and push huge numbers of images, and you can still use the same image for all services of a specific type.

### Dependency Installation at Build Time

If you have a service that requires dependencies to be installed, it is recommended to do so at build time. This way, you can be sure that the dependencies are installed when the image is built, and you don't have to wait for them to be installed when the container is started.

This ensures both a faster startup time and a consistent execution environment.
3 changes: 1 addition & 2 deletions docs/docs/Deployment/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ tags: [ Deployment ]

# Deployment


Deployment is the process of making a software system available for use. In the context of Telestion, deployment refers to the process of making the Telestion application available for use.

!!! warning
Expand All @@ -25,6 +24,6 @@ Telestion can be deployed in multiple ways:

## NATS and its configuration

Telestion uses [NATS](https://nats.io/) as a message broker. NATS is a lightweight, high-performance cloud native messaging system. It is used for the communication between the Telestion backend and the Telestion frontend.
Telestion uses [NATS](https://nats.io/) as its message broker. NATS is a lightweight, high-performance cloud-native messaging system. It is used for the communication between the Telestion backend and the Telestion frontend.

No matter which deployment method you choose, you need to configure NATS. The configuration of NATS is described in the [NATS Configuration](nats/index.md) document.
33 changes: 11 additions & 22 deletions docs/docs/Deployment/local/local-nats.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,30 +26,19 @@ NATS can be configured using a configuration file. To run NATS with a configurat
nats-server -c <path-to-config-file>
```

### Adding users

!!! info
This guide will focus on getting you started. We'll look deeper into NATS permissions in the [NATS configuration guide](../nats/index.md).

In your NATS configuration file, add the following section:

```json
authorization {
default_permissions = {
publish = []
subscribe = ["__telestion__.>"]
}
SERVICE = {
publish = ["altitude", "log.>"]
subscribe = ["altitude", "__telestion__.health"]
allow_responses = true
}
users = [
{user: service, password: service, permissions: $SERVICE}
]
As a starting point, you can use the following configuration to enable everything you need while developing:

```json title="nats.conf"
http_port: 8222

websocket: {
port: 9222
no_tls: true
}
```

This will create a user called `service` with the password `service`. This user will be able to publish to the `altitude` subject and subscribe to the `__telestion__.health` subject.
This will enable the HTTP and WebSocket interfaces.

Note that for production deployments, you need to configure NATS to use TLS and set up proper authentication. You can learn more about configuring NATS in the [NATS configuration guide](../nats/index.md).

[Learn more about NATS configuration](../nats/index.md){ .md-button }
43 changes: 43 additions & 0 deletions docs/docs/Deployment/nats/index.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,51 @@
# NATS Server Configuration

The NATS server can be configured using both a configuration file and environment variables.

## Environment Variables

The NATS server configuration is done via environment variables. The following table lists all available environment variables and their default values.

| Environment Variable | Default Value | Description |
|----------------------|---------------|------------------------------|
| `NATS_HOST` | `localhost` | The host of the NATS server. |
| `NATS_PORT` | `4222` | The port of the NATS server. |

## Configuration File

The NATS server can also be configured using a configuration file. To use a configuration file, you need to pass the `-c` flag to the NATS server:

```bash
nats-server -c <path-to-config-file>
```

You can find a full reference of the NATS server configuration in the [NATS documentation](https://docs.nats.io/nats-server/configuration).

For Telestion, the following settings are of special interest:

1. [`websocket`](https://docs.nats.io/running-a-nats-service/configuration/websocket/websocket_conf) - This section configures the WebSocket interface of the NATS server. It's used by the Telestion frontend to connect to the NATS server.
2. [`authorization`](https://docs.nats.io/running-a-nats-service/configuration/securing_nats/authorization) - This section configures who can publish and subscribe to which subjects.
3. [`authorization.users`](https://docs.nats.io/running-a-nats-service/configuration/securing_nats/auth_intro/username_password) - This section configures the user accounts that can connect to the NATS server. It's used to configure the user accounts that can connect to the NATS server. As of right now, Telestion exclusively supports [username/password-based authentication](https://docs.nats.io/running-a-nats-service/configuration/securing_nats/auth_intro/username_password).

### Development Configuration

The following configuration is a good starting point for development.

!!! danger
**Do not use this configuration in production!** It's only meant for development.

There are several problems with this configuration that make it unsuitable for production:

1. it doesn't use TLS for the websocket interface, meaning that all communication is unencrypted
2. it doesn't have any authentication or authorization configured, meaning that anyone can connect to the NATS server and publish/subscribe to any subject

**In essence, if you were to use this configuration in production, you would have a NATS server that is publicly accessible and allows anyone with access to your server to publish/subscribe to any subject!**

```json title="nats.conf"
http_port: 8222

websocket: {
port: 9222
no_tls: true
}
```
Loading

0 comments on commit 8e11049

Please sign in to comment.