Skip to content

Commit

Permalink
Merge pull request #8 from fauxauldrich/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
shubhendumadhukar authored Apr 26, 2021
2 parents 4cf020b + 97a0f38 commit 10425b9
Show file tree
Hide file tree
Showing 31 changed files with 210 additions and 1,015 deletions.
9 changes: 3 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
FROM node:14.16-slim
WORKDIR /app
VOLUME /app/certs
VOLUME /app/grpc
VOLUME /app/mocks
RUN npm i -g [email protected]
COPY ./config.yml /app/
CMD ["camouflage", "--config", "config.yml"]
COPY . /app
CMD ["node", "bin/camouflage", "--config", "config.yml"]

56 changes: 52 additions & 4 deletions bin/camouflage.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
#!/usr/bin/env node
const cluster = require("cluster");
const express = require("express");
const metricsServer = express();
const AggregatorRegistry = require("prom-client").AggregatorRegistry;
const aggregatorRegistry = new AggregatorRegistry();
var argv = require("yargs").argv;
const yaml = require("js-yaml");
const winston = require("winston");
const fs = require("fs");
var config = argv.c || argv.config;
var help = argv.h || argv.help;
const osCPUs = require("os").cpus().length;
const camouflage = require("../dist/index");
if (help) {
console.log(
[
Expand Down Expand Up @@ -51,7 +57,6 @@ let inputs = [
config.protocols.https.enable,
config.protocols.http2.enable,
config.protocols.grpc.enable,
config.cpus,
config.protocols.https.key,
config.protocols.https.cert,
config.protocols.http2.key,
Expand All @@ -64,10 +69,53 @@ let inputs = [
config.protocols.grpc.protos_dir,
config.loglevel,
];
if (config.cpus > osCPUs) {
const numCPUs = config.cpus || 1;
const monitoringPort = config.monitoring.port || 5555;
if (numCPUs > osCPUs) {
logger.error("Number of CPUs specified is greater than or equal to availale CPUs. Please specify a lesser number.");
process.exit(1);
}
const camouflage = require("../dist/index");
camouflage.start(...inputs);
if (cluster.isMaster) {
logger.info(`[${process.pid}] Master Started`);
// If current node is a master node, use it to start X number of workers, where X comes from config
for (let i = 0; i < numCPUs; i++) {
let worker = cluster.fork();
// Attach a listner to each worker, so that if worker sends a restart message, running workers can be killed
worker.on("message", (message) => {
if (message === "restart") {
for (let id in cluster.workers) {
cluster.workers[id].process.kill();
}
}
});
}
// If workers are killed or crashed, a new worker should replace them
cluster.on("exit", (worker, code, signal) => {
logger.warn(`[${worker.process.pid}] Worker Stopped ${new Date(Date.now())}`);
let newWorker = cluster.fork();
// Same listener to be attached to new workers
newWorker.on("message", (message) => {
if (message === "restart") {
for (let id in cluster.workers) {
cluster.workers[id].process.kill();
}
}
});
});
metricsServer.get("/metrics", async (req, res) => {
try {
const metrics = await aggregatorRegistry.clusterMetrics();
res.set("Content-Type", aggregatorRegistry.contentType);
res.send(metrics);
} catch (ex) {
res.statusCode = 500;
res.send(ex.message);
}
});

metricsServer.listen(monitoringPort);
logger.info(`Cluster metrics server listening to ${monitoringPort}, metrics exposed on http://localhost:${monitoringPort}/metrics`);
} else {
camouflage.start(...inputs);
}

4 changes: 3 additions & 1 deletion config.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
loglevel: info
cpus: 2
cpus: 1
monitoring:
port: 5555
protocols:
http:
mocks_dir: "./mocks"
Expand Down
53 changes: 49 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
version: "2.1"
networks:
camouflage:
driver: bridge

volumes:
prometheus_data: {}
grafana_data: {}

services:
camouflage:
Expand All @@ -9,14 +16,52 @@ services:
- ./mocks:/app/mocks
- ./grpc:/app/grpc
- ./config.yml:/app/config.yml
restart: unless-stopped
expose:
- 8080
- 8443
- 8081
- 4312
- 8080 # HTTP Port
- 8443 # HTTPs Port
- 8081 # HTTP/2 Port
- 4312 # GRPC Port
- 5555 # Monitoring Port
ports:
- "8080:8080"
- "8443:8443"
- "8081:8081"
- "4312:4312"
- "5555:5555"
networks:
- camouflage
labels:
org.label-schema.group: "camouflage"

prometheus:
image: prom/prometheus:v2.26.0
container_name: prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
restart: unless-stopped
expose:
- 9090
ports:
- "9090:9090"
networks:
- camouflage
labels:
org.label-schema.group: "camouflage"

grafana:
image: grafana/grafana:7.5.2
container_name: grafana
volumes:
- grafana_data:/var/lib/grafana
restart: unless-stopped
expose:
- 3000
ports:
- "3000:3000"
networks:
- camouflage
labels:
org.label-schema.group: "camouflage"

9 changes: 6 additions & 3 deletions docs/available-monitoring.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ Monitoring might not be of paramount importance when you are running unit tests

![Camouflage-MonitoringDashboard](Camouflage-MonitoringDashboard.png)

If you'd like to store this data in Prometheus and then use Grafana to generate your own visualizations, Camouflage also provides you with a prometheus scraping endpoint available at `/monitoring/metrics` which contains information about your host and your mocks. You can install a Prometheus DB and configure it to scrape from `/monitoring/metrics` endpoint, and use that data to create charts for monitoring your application.
!!!note

If you are running more than one worker, above UI would not provide you aggregated metrics. Data displayed will be worker specific data and at this point, we don't have a control on which worker's data will be displayed. Every time UI refreshes, the displayed data might belong to any of the running workers.

To provide the aggregated metrics, Camouflage runs a separate monitoring server, which runs by default on port 5555. The URL `http://localhost:5555/metrics` acts as a scraping endpoint for your Prometheus server. Store this data in Prometheus and then use Grafana to generate your own visualizations. You can install a Prometheus DB and configure it to scrape from `/metrics` endpoint, and use that data to create charts for monitoring your application.

Sample Prometheus yml

Expand All @@ -14,9 +18,8 @@ global:
evaluation_interval: 15s
scrape_configs:
- job_name: 'camouflage'
metrics_path: '/monitoring/metrics'
static_configs:
- targets: ['localhost:8080']
- targets: ['localhost:5555']
```

!!!note
Expand Down
9 changes: 0 additions & 9 deletions docs/future-plans.md

This file was deleted.

4 changes: 3 additions & 1 deletion docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
```yaml
loglevel: info
cpus: 2
monitoring:
port: 5555
protocols:
http:
mocks_dir: "./mocks"
Expand Down Expand Up @@ -45,7 +47,7 @@ X-Custom-Header: Custom-Value
Content-Type: application/json

{
"greeting": "Hey! It works"
"greeting": "Hey! It works!"
}
```

Expand Down
6 changes: 3 additions & 3 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Camouflage Documentation
# Home

Camouflage is a service virtualization tool inspired by [namshi/mockserver](https://github.com/namshi/mockserver){target=\_blank}. As the original description says, the mocking/service virtualization works on a file based structure where _you simply organize your mocked HTTP responses in a bunch of mock files and it will serve them like they were coming from a real API; in this way you can write your frontends without caring too much whether your backend is really ready or not._

Expand All @@ -7,10 +7,10 @@ Camouflage is a service virtualization tool inspired by [namshi/mockserver](http
Well, the original tool has not been maintained for some time now. But more importantly, Camouflage simply borrows the idea from the original and though it does use some of the same logic and functions, majority of the code has been written from scratch.

1. The underlying codebase has been re-written using typescript.
2. Since we are still in development phase, some features from the original tool might be missing. (Because we are yet to develop it, or simply because we haven't made up our mind yet if those features are going to be included or not.)
2. Some features from the original tool might be missing, or have been implemented differently. (import and eval have not been ported to Camouflage)
3. Camouflage introduces handlebars, which allows you to generate dynamic (more real) responses.
4. Using handlebars, you can generate random numbers, string, alphanumeric string, UUIDs and random dates.
5. You can also extract information from request queries, path, body or headers and use them in your response.
6. You can use handlebars to carry out request matching for you. For example, return one response if a query param exists, return another if it doesn't.
7. And, we saved the best for last. Camouflage supports gRPC Mocking!!
7. And, we saved the best for last. Camouflage supports multiple protocols, i.e. HTTP, HTTPs, HTTP2 and gRPC!!

2 changes: 1 addition & 1 deletion docs/mocking-gRPC.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Mocking gRPC

Camouflage v1.0.3 introduces mocking gRPC services. Creation of mocks remains similar to HTTP mocks with some minor changes.
Camouflage introduces mocking gRPC services. Creation of mocks remains similar to HTTP mocks with some minor changes.

For starters, gRPC mocks should not be placed in the same mocks directory as HTTP mocks, instead they should have their own mocks and protos directories. Secondly, the folder structure inside grpc mocks directory will follow the convention ./grpc/mocks/**_package_name_/_service_name_/_method_name_.mock**

Expand Down
2 changes: 0 additions & 2 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,4 @@ nav:
- mocking-gRPC.md
- available-monitoring.md
- tests.md
- releases.md
- future-plans.md

4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "camouflage-server",
"version": "0.1.0",
"version": "0.1.1",
"description": "Easily mock your webservices while testing frontends.",
"homepage": "https://fauxauldrich.github.io/camouflage/",
"keywords": [
Expand Down
9 changes: 9 additions & 0 deletions prometheus.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: "camouflage"
scrape_interval: 5s
static_configs:
- targets: ["camouflage:5555"]

32 changes: 1 addition & 31 deletions site/404.html
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@

<li class="md-nav__item">
<a href="/." class="md-nav__link">
Camouflage Documentation
Home
</a>
</li>

Expand Down Expand Up @@ -349,36 +349,6 @@










<li class="md-nav__item">
<a href="/releases.md" class="md-nav__link">
None
</a>
</li>










<li class="md-nav__item">
<a href="/future-plans/" class="md-nav__link">
Future plans
</a>
</li>



</ul>
</nav>
</div>
Expand Down
Loading

0 comments on commit 10425b9

Please sign in to comment.