Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
owenkellogg authored Jun 27, 2023
0 parents commit 27f582a
Show file tree
Hide file tree
Showing 41 changed files with 16,165 additions and 0 deletions.
70 changes: 70 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
version: 2.1
jobs:

build:
docker:
- image: circleci/node:14
- image: circleci/postgres:9.5-postgis
environment:
POSTGRES_USER: postgres
POSTGRES_DB: database
POSTGRES_PASSWORD: "letmein"
- image: rabbitmq:3
steps:
- checkout
- run:
name: Install Dependencies
command: npm install
- run:
name: Run Main Tests
command: npm test
- run:
name: Report Code Coverage
command: |
curl -Os https://uploader.codecov.io/latest/linux/codecov
chmod +x codecov
./codecov
- run:
name: Tag and Release New Version
command: npx semantic-release


build_docker:
docker:
- image: circleci/node:12
steps:
- checkout
- setup_remote_docker
- run:
name: Build docker image
command: docker build -t $DOCKER_REPO:$CIRCLE_BRANCH .
- run:
name: Push to Docker Hub
command: |
docker login --username $DOCKER_USER --password $DOCKER_PASSWORD
docker push $DOCKER_REPO:$CIRCLE_BRANCH
deploy:
machine: true
steps:
- run:
name: Deploy to Web Servers
command: ssh $DEPLOY_HOST "$DEPLOY_COMMAND"


workflows:
version: 2
build_and_deploy:
jobs:
- build
- build_docker:
requires:
- build
- deploy:
requires:
- build_docker
filters:
branches:
only:
- master

4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules/
.rabbi/
.env
.git
15 changes: 15 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.idea/
.vscode/
node_modules/
build/
tmp/
temp/.env
.env
.bit
get402.json
**/*.swp
**/*.swo
*.swo
*.swp
dist/
.rabbi/config.json
9 changes: 9 additions & 0 deletions .sequelizerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

var path = require('path')

module.exports = {
'config': path.resolve('config', 'config.json'),
'migrations-path': path.resolve('src', 'migrations'),
'models-path': path.resolve('src', 'models'),
'seeders-path': path.resolve('src', 'seeders')
}
17 changes: 17 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM node:16

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/

RUN npm install -g typescript
RUN npm install -g ts-node
RUN npm install

# Bundle app source
COPY . /usr/src/app

CMD npm start

104 changes: 104 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
![Rabbi Banner Image](https://doge.bitcoinfiles.org/b463dd2d110537e2c33f26583ed86aa35bdb1bc4f99d8146a590d7a7e95c74a5)

# Typescript API Server

## Installation

To download and install dependencies run `npm install`

## Running

To run the API server run `npm start`

## Testing

To run tests run `npm run test`

## Development

To commit new code run `npm run commit`

## Configuration

Rabbi may be configured in several ways depending on the needs of your environment.

1) Environment Variables

2) Configuration Files

3) Command Line Arguments

The same variables are used in all three options, however in configuration files and command line arguments all variables are strictly lower case, whereas in environment variables they may be upper case or lower case.

### Environment Variables

| Variable | Description | Default | Required |
|----------------------|-----------------------------------------------------------------------------------------|---------|----------|
| HTTP_API_ENABLED | Serve JSON API. | true | false |
| AMQP_ENABLED | Communicate between components via RabbitMQ. Require by some features under src/actors/ | true | false |
| POSTGRES_ENABLED | Will automatically begin logging events to postgres | true | true |
| DATABASE_URL | Postgres connection Url in the form `postgres://user:password@host:port/database | | true |
| HTTP_API_HOST | IP address to bind when serving. Set to 127.0.0.1 or localhost for local-only access | 0.0.0.0 | false |
| HTTP_API_PORT | Port to bind when accepting new API client connections. | 5200 | false |
| PROMETHEUS_ENABLED | Expose /metrics endpoint to allow prometheus to scrape default and your custom metrics. | true | false |
| LOKI_ENABLED | Stream logs from the application to a loki log aggregation server. | false | false |


### Configuration Files

The app loads files from a hierarchy each overriding the previous. First the system level config files are loaded, then user level config file, finally the local config file for development purposes

1) /etc/rabbi/rabbi.json

2) ~/.rabbi/rabbi.json

3) .config/rabbi.json

Config files are JSON objects containing key value pairs where the key is the config variable and the value is the value of the variable. Numbers and booleans will be parsed and made available. Variable names can be either upper or lower case.

```
{
"database_url": "postgres://postgres:[email protected]:5432/boostpow",
"http_api_port": 3000,
"loki_enabled": true,
"loki_url": "https://loki.example.com",
"prometheus_enabled": false
}
```

## System Events

When using AMQP you may bind the following events as routingkeys to receive delivery of these messages to your application. You may also choose to receive these events via Webhook by configuring the `WEBHOOK_URL` and `WEBHOOKS_ENABLED` variables.

| Event | Description |
|----------------------|-----------------------------------------------------------------------------------------|
| prometheus.metrics.scraped | Every time prometheus scrapes |
| http.request | When a client makes a request to the HTTP API |

Additional events can be published and listened to using rabbi

```
import { events } from 'rabbi'
events.publish('game.ended', { winner: 'nobody' })
```
Then in another component or process, or app connected to the same AMQP:

```
import { events } from 'rabbi'
events.on('game.ended', (message: Buffer, json?: any) => {
console.log('---- GAME OVER ----')
if (json && json.winner === 'nobody') {
console.log('nobody wins')
}
})
```

47 changes: 47 additions & 0 deletions __tests__/prometheus_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@

import { server, start } from '../src/server'

import { expect } from './utils'

describe('Scraping Prometheus Metrics', () => {

before(async () => {

await start()

})

it('GET /metrics should provide the metrics', async () => {

const response = await server.inject({
method: 'GET',
url: '/metrics'
})

expect(response.statusCode).to.be.equal(200)

})

it.skip('GET /liveness should return success', async () => {

const response = await server.inject({
method: 'GET',
url: '/liveness'
})

expect(response.statusCode).to.be.equal(200)

})

it.skip('GET /readiness should return success', async () => {

const response = await server.inject({
method: 'GET',
url: '/readiness'
})

expect(response.statusCode).to.be.equal(200)

})

})
37 changes: 37 additions & 0 deletions __tests__/swagger_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

import { server, start } from '../src/server'

import { expect } from './utils'

describe('Swagger Documentation', () => {

before(async () => {

await start()

})

it('GET /swagger.json should provide the API schema', async () => {

const response = await server.inject({
method: 'GET',
url: '/swagger.json'
})

expect(response.statusCode).to.be.equal(200)

})

it('GET / should return the swagger documentation', async () => {

const response = await server.inject({
method: 'GET',
url: '/'
})

expect(response.statusCode).to.be.equal(200)

})

})

15 changes: 15 additions & 0 deletions __tests__/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

import * as assert from 'assert'

export { assert }

import * as chai from 'chai'

const chaiAsPromised = require('chai-as-promised')

chai.use(chaiAsPromised)

const expect = chai.expect

export { expect }

1 change: 1 addition & 0 deletions config/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Loading

0 comments on commit 27f582a

Please sign in to comment.