Add minimal BlackRoad OS health demo
This commit is contained in:
52
README.md
52
README.md
@@ -1,8 +1,50 @@
|
|||||||

|
# BlackRoad OS Demo
|
||||||
|
|
||||||

|
A minimal Node.js example that shows how a third-party app can call BlackRoad OS services. It provides both a CLI and a tiny HTTP endpoint that fetch health information from the Operator and Core services using environment-configured URLs.
|
||||||
|
|
||||||
# Welcome to your organization's demo respository
|
## Stack and entry points
|
||||||
This code repository (or "repo") is designed to demonstrate the best GitHub has to offer with the least amount of noise.
|
- **Language/runtime:** Node.js (uses the built-in `fetch` available in Node 18+; no extra dependencies required).
|
||||||
|
- **CLI:** `demo.js`
|
||||||
|
- **Server:** `server.js` (listens on `PORT` and responds on `/` or `/demo`).
|
||||||
|
|
||||||
The repo includes an `index.html` file (so it can render a web page), two GitHub Actions workflows, and a CSS stylesheet dependency.
|
## Environment variables
|
||||||
|
| Name | Description | Default |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `OPERATOR_URL` | Base URL for the Operator service (called with `/system/health`). | `http://localhost:8080` |
|
||||||
|
| `CORE_URL` | Base URL for the Core service (called with `/health`). | `http://localhost:8081` |
|
||||||
|
| `PORT` | Port for the demo HTTP server. | `3000` |
|
||||||
|
|
||||||
|
Set them locally with a `.env` file, `export`, or inline before running commands.
|
||||||
|
|
||||||
|
## Running locally
|
||||||
|
1. Ensure Node.js 18+ is installed (for native `fetch`).
|
||||||
|
2. Install dependencies (only needed for the existing CSS dependency):
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
3. Run the CLI health check:
|
||||||
|
```bash
|
||||||
|
OPERATOR_URL=http://localhost:8080 CORE_URL=http://localhost:8081 npm run demo
|
||||||
|
```
|
||||||
|
The script prints the Operator and Core health JSON responses (or friendly errors) using the configured URLs.
|
||||||
|
4. Run the HTTP demo server:
|
||||||
|
```bash
|
||||||
|
OPERATOR_URL=http://localhost:8080 CORE_URL=http://localhost:8081 PORT=3000 npm start
|
||||||
|
```
|
||||||
|
Then open `http://localhost:3000/demo` (or `/`) to see a JSON payload combining both health checks.
|
||||||
|
|
||||||
|
## Railway (optional)
|
||||||
|
This demo can be deployed as a simple service. Suggested settings:
|
||||||
|
- `build_command`: `npm install`
|
||||||
|
- `start_command`: `npm start`
|
||||||
|
- Expose port `PORT` (Railway will set this automatically) and ensure the service binds to `0.0.0.0` (handled by `server.js`).
|
||||||
|
- Provide `OPERATOR_URL` and `CORE_URL` via Railway environment variables.
|
||||||
|
|
||||||
|
If you only need a local demonstration, you can skip Railway entirely.
|
||||||
|
|
||||||
|
## What the demo does
|
||||||
|
- Reads `OPERATOR_URL` and `CORE_URL` from the environment (with sensible localhost defaults).
|
||||||
|
- Calls:
|
||||||
|
- `OPERATOR_URL/system/health` for overall status.
|
||||||
|
- `CORE_URL/health` for Core status.
|
||||||
|
- Prints or returns the responses in a readable JSON shape, demonstrating how an external application can query BlackRoad OS services.
|
||||||
|
|||||||
65
demo.js
Normal file
65
demo.js
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
const defaultCoreUrl = process.env.CORE_URL || 'http://localhost:8081';
|
||||||
|
const defaultOperatorUrl = process.env.OPERATOR_URL || 'http://localhost:8080';
|
||||||
|
|
||||||
|
function buildRequestUrl(baseUrl, path) {
|
||||||
|
return `${baseUrl.replace(/\/$/, '')}/${path.replace(/^\//, '')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchJson(url) {
|
||||||
|
const response = await fetch(url, { headers: { 'accept': 'application/json' } });
|
||||||
|
if (!response.ok) {
|
||||||
|
const text = await response.text();
|
||||||
|
throw new Error(`Request to ${url} failed with ${response.status}: ${text}`);
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function checkOperatorHealth(operatorUrl = defaultOperatorUrl) {
|
||||||
|
const healthUrl = buildRequestUrl(operatorUrl, '/system/health');
|
||||||
|
const body = await fetchJson(healthUrl);
|
||||||
|
return { url: healthUrl, data: body };
|
||||||
|
}
|
||||||
|
|
||||||
|
async function checkCoreHealth(coreUrl = defaultCoreUrl) {
|
||||||
|
const healthUrl = buildRequestUrl(coreUrl, '/health');
|
||||||
|
const body = await fetchJson(healthUrl);
|
||||||
|
return { url: healthUrl, data: body };
|
||||||
|
}
|
||||||
|
|
||||||
|
async function runDemo() {
|
||||||
|
const operatorUrl = process.env.OPERATOR_URL || defaultOperatorUrl;
|
||||||
|
const coreUrl = process.env.CORE_URL || defaultCoreUrl;
|
||||||
|
|
||||||
|
console.log('BlackRoad OS demo: checking services...');
|
||||||
|
console.log(`- OPERATOR_URL: ${operatorUrl}`);
|
||||||
|
console.log(`- CORE_URL: ${coreUrl}`);
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const operatorHealth = await checkOperatorHealth(operatorUrl);
|
||||||
|
console.log(`Operator health (${operatorHealth.url}):`);
|
||||||
|
console.log(JSON.stringify(operatorHealth.data, null, 2));
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Could not fetch operator health:', error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const coreHealth = await checkCoreHealth(coreUrl);
|
||||||
|
console.log(`\nCore health (${coreHealth.url}):`);
|
||||||
|
console.log(JSON.stringify(coreHealth.data, null, 2));
|
||||||
|
} catch (error) {
|
||||||
|
console.error('\nCould not fetch core health:', error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (require.main === module) {
|
||||||
|
runDemo();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
runDemo,
|
||||||
|
checkOperatorHealth,
|
||||||
|
checkCoreHealth,
|
||||||
|
defaultCoreUrl,
|
||||||
|
defaultOperatorUrl,
|
||||||
|
};
|
||||||
@@ -5,5 +5,9 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@primer/css": "17.0.1"
|
"@primer/css": "17.0.1"
|
||||||
},
|
},
|
||||||
|
"scripts": {
|
||||||
|
"start": "node server.js",
|
||||||
|
"demo": "node demo.js"
|
||||||
|
},
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
}
|
}
|
||||||
|
|||||||
57
server.js
Normal file
57
server.js
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
const http = require('http');
|
||||||
|
const {
|
||||||
|
checkOperatorHealth,
|
||||||
|
checkCoreHealth,
|
||||||
|
defaultCoreUrl,
|
||||||
|
defaultOperatorUrl,
|
||||||
|
} = require('./demo');
|
||||||
|
|
||||||
|
const port = process.env.PORT || 3000;
|
||||||
|
const operatorUrl = process.env.OPERATOR_URL || defaultOperatorUrl;
|
||||||
|
const coreUrl = process.env.CORE_URL || defaultCoreUrl;
|
||||||
|
|
||||||
|
function jsonResponse(res, statusCode, body) {
|
||||||
|
const text = JSON.stringify(body, null, 2);
|
||||||
|
res.writeHead(statusCode, {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Content-Length': Buffer.byteLength(text),
|
||||||
|
});
|
||||||
|
res.end(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleRequest(req, res) {
|
||||||
|
if (req.url !== '/' && req.url !== '/demo') {
|
||||||
|
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
||||||
|
res.end('Not Found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const [operatorHealth, coreHealth] = await Promise.allSettled([
|
||||||
|
checkOperatorHealth(operatorUrl),
|
||||||
|
checkCoreHealth(coreUrl),
|
||||||
|
]);
|
||||||
|
|
||||||
|
jsonResponse(res, 200, {
|
||||||
|
operator: operatorHealth.status === 'fulfilled'
|
||||||
|
? operatorHealth.value
|
||||||
|
: { error: operatorHealth.reason.message, url: operatorUrl },
|
||||||
|
core: coreHealth.status === 'fulfilled'
|
||||||
|
? coreHealth.value
|
||||||
|
: { error: coreHealth.reason.message, url: coreUrl },
|
||||||
|
meta: {
|
||||||
|
operatorUrl,
|
||||||
|
coreUrl,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
jsonResponse(res, 500, { error: error.message });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
http.createServer(handleRequest).listen(port, '0.0.0.0', () => {
|
||||||
|
console.log(`Demo server listening on http://0.0.0.0:${port}`);
|
||||||
|
console.log(`Using OPERATOR_URL=${operatorUrl}`);
|
||||||
|
console.log(`Using CORE_URL=${coreUrl}`);
|
||||||
|
console.log('GET / or /demo to see health checks.');
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user