Creating a Ping service in Eyevinn Open Source Cloud

Jonas Birmé - Feb 19 - - Dev Community

The open web service Web Runner gives you the possibility to run your custom code in Eyevinn Open Source Cloud and building solutions based on a combination of the open web services available.

As an example we are going to build a simple "ping" service that provides an endpoint for checking whether a site is responding or not. It will save the checks to an SQL database.

Solution diagram

Prerequisites

  • An account in Eyevinn Open Source Cloud. Sign up here
  • 2 available services in your plan. If you have no remaining services in your plan you can purchase each service individually or upgrade your plan.
  • NodeJS installed

Install OSC Command Line Tool

We will start by installing the CLI for Eyevinn Open Source Cloud.

% npm install -g @osaas/cli@latest
Enter fullscreen mode Exit fullscreen mode

Verify that it is correctly installed.

% osc -v
4.10.0
Enter fullscreen mode Exit fullscreen mode

Now go to the Eyevinn Open Source Cloud web console and navigate to Settings/API and copy the Personal Access Token. Store this in the environment variable OSC_ACCESS_TOKEN.

% export OSC_ACCESS_TOKEN=<personal-access-token>
Enter fullscreen mode Exit fullscreen mode

Initiate a NodeJS project

Create a project folder and initiate a NodeJS project.

% mkdir ping
% cd ping
% npm init
Enter fullscreen mode Exit fullscreen mode

Install typescript.

% npm install --save-dev @types/node typescript
% npm install --save ts-node
Enter fullscreen mode Exit fullscreen mode

We will be using fastify as the API middleware framework so let us install that.

% npm install --save fastify
Enter fullscreen mode Exit fullscreen mode

Build the ping service

Create a folder for the source code and create an index.ts file in that folder.

Add the following code to the src/index.ts file.

import fastify from "fastify";

async function main() {
  const server = fastify();

  server.get('/', async (request, reply) => {
    reply.send('Hello World');
  });

  server.get<{
    Params: { site: string };
    Reply: {
      200: { up: boolean };
      '4xx': { error: string };
    }
  }>('/ping/:site', async (request, reply) => {
    const url = `https://${request.params.site}`;
    try {
      const response = await fetch(url, { method: 'GET' });
      const isUp = response.status >= 200 && response.status < 400;
      reply.code(200).send({ up: isUp });
    } catch (err) {
      reply.code(200).send({ up: false });
    }
  });

  server.listen({ host: '0.0.0.0', port: process.env.PORT ? Number(process.env.PORT) : 8080 }, (err, address) => {
    if (err) console.error(err);
    console.log(`Server listening at ${address}`);
  });
}

main();
Enter fullscreen mode Exit fullscreen mode

Add the following line to the package.json

...
  "scripts": {
    "start": "ts-node src/index.ts",
    ...
  },
...
Enter fullscreen mode Exit fullscreen mode

And add a file tsconfig.json with the following.

{
  "compilerOptions": {
    "target": "ESNext",
    "module": "commonjs",
    "rootDir": "./src",
    "outDir": "./dist",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  }
}
Enter fullscreen mode Exit fullscreen mode

Now let us test what we have created by running the start script.

% npm start
> ping@0.1.0 start
> ts-node src/index.ts

Server listening at http://127.0.0.1:8080
Enter fullscreen mode Exit fullscreen mode

We can test the endpoint with the following curl command to check whether the site www.osaas.io is up.

% curl http://localhost:8080/ping/www.osaas.io
{"up":true}
Enter fullscreen mode Exit fullscreen mode

Save checks to a database

It is often interesting to keep an uptime history so we want to save the result from all checks in a database.

We will be using a PostgreSQL database available as an open web service in Eyevinn Open Source Cloud. To be able to create the database from our application we will install the database module of the Eyevinn OSC javascript SDK and a Postgres client.

% npm install --save @osaas/client-db postgres
Enter fullscreen mode Exit fullscreen mode

Now let us modify our src/index.ts and add that we will setup a database first and a table if it does not exist.

import { setupDatabase } from "@osaas/client-db";
import fastify from "fastify";
import postgres from "postgres";

async function main() {
  const server = fastify();
  const dbName = process.env.DB_NAME || 'sitemonitor';
  const dbUser = process.env.DB_USER || 'sitemonitor';
  const dbPassword = process.env.DB_PASSWORD || 'sitemonitor';

  const dbUrl = await setupDatabase('postgres', dbName, {
    username: dbUser,
    password: dbPassword,
    database: dbName,
  });  
  const sql = postgres(new URL(dbName, dbUrl).toString());
  await sql`CREATE TABLE IF NOT EXISTS checks (id BIGSERIAL PRIMARY KEY, site TEXT NOT NULL, up BOOLEAN NOT NULL, created_at TIMESTAMP NOT NULL DEFAULT NOW())`;

  server.get('/', async (request, reply) => {
    reply.send('Hello World');
  });

  server.get<{
    Params: { site: string };
    Reply: {
      200: { up: boolean };
      '4xx': { error: string };
    }
  }>('/ping/:site', async (request, reply) => {
    const url = `https://${request.params.site}`;
    try {
      const response = await fetch(url, { method: 'GET' });
      const isUp = response.status >= 200 && response.status < 400;
      await sql`INSERT INTO checks (site, up) VALUES (${url}, ${isUp})`;
      reply.code(200).send({ up: isUp });
    } catch (err) {
      await sql`INSERT INTO checks (site, up) VALUES (${url}, false)`;
      reply.code(200).send({ up: false });
    }
  });

  server.listen({ host: '0.0.0.0', port: process.env.PORT ? Number(process.env.PORT) : 8080 }, (err, address) => {
    if (err) console.error(err);
    console.log(`Server listening at ${address}`);
  });
}

main();
Enter fullscreen mode Exit fullscreen mode

Now let us run it again.

% npm start
Enter fullscreen mode Exit fullscreen mode

It will create a Postgres database called site monitor and we can verify this by going to the web console.

PostgreSQL instance

If you wanted to give the database another name or use another username or password we can provide that using environment variables, for example:

% DB_NAME=mynewdb npm start
Enter fullscreen mode Exit fullscreen mode

Now when we do a ping it will also save the check and the result from it in the database.

sitemonitor=# select * from checks;                                                                               id |         site         | up |         created_at         
----+----------------------+----+----------------------------
  1 | https://www.osaas.io | t  | 2025-02-18 22:06:00.415521
  2 | https://www.osaas.io | t  | 2025-02-18 22:06:16.508421
  3 | https://www.osaas.io | t  | 2025-02-19 20:52:54.02972
(3 rows)
Enter fullscreen mode Exit fullscreen mode

Run the code in Eyevinn Open Source Cloud

Now we want to make this ping service we created available online. For that we will use the open web service Web Runner. The Web Runner fetches the code from a private (or public) GitHub repository so we will first create a repository for the orchestrator we built.

Create a GitHub repository

% git init
Enter fullscreen mode Exit fullscreen mode

Add a file called .gitignore that contains the following.

dist/
node_modules/
Enter fullscreen mode Exit fullscreen mode

Create a GitHub repository in your GitHub account and push the code.

% git add
% git commit -m "my ping service"
% git remote add origin git@github.com:<your-git-org>/<git-repo>.git
% git branch -M main
% git push -u origin main
Enter fullscreen mode Exit fullscreen mode

Create a GitHub personal access token

For access to you your GitHub repository you need to create a GitHub Personal Access Token first.

  1. Verify your email address, if it hasn't been verified yet.
  2. In the upper-right corner of any page on GitHub, click your profile photo, then click Settings.
  3. In the left sidebar, click Developer settings.
  4. In the left sidebar, under Personal access tokens, click Tokens (classic).
  5. Select Generate new token, then click Generate new token (classic).
  6. In the "Note" field, give your token a descriptive name.
  7. To give your token an expiration, select Expiration, then choose a default option or click Custom to enter a date.
  8. Select the scopes you'd like to grant this token. To use your token to access repositories from the command line, select repo. A token with no assigned scopes can only access public information. For more information, see Scopes for OAuth apps.
  9. Click Generate token and copy it to the clipboard.

Create Web Runner instance

Now create a Web Runner instance with the link to the GitHub repository we created.

% osc create eyevinn-web-runner myping \
  -o GitHubUrl=https://github.com/<your-org>/<your-repo> \
  -o GitHubToken="<your-github-token>" \
  -o OscAccessToken="<your-osc-token>"
Instance created:
{
  name: 'myping',
  url: 'https://<yourtenant>-myping.eyevinn-web-runner.auto.prod.osaas.io',
  resources: {
    license: {
      url: 'https://api-eyevinn-web-runner.auto.prod.osaas.io/license'
    },
    app: {
      url: 'https://<yourtenant>-myping.eyevinn-web-runner.auto.prod.osaas.io/'
    }
  },
  GitHubUrl: 'https://github.com/<your-org>/<your-repo>',
  GitHubToken: '<your-github-token>',
  OscAccessToken: '<your-osc-token>',
  ConfigService: 'undefined'
}
Enter fullscreen mode Exit fullscreen mode

After about a minute your ping service is available at the URL https://eyevinnlab-myping.eyevinn-web-runner.auto.prod.osaas.io and we can verify this with curl.

% curl https://eyevinnlab-myping.eyevinn-web-runner.auto.prod.osaas.io/ping/www.osaas.io
{"up":true}
Enter fullscreen mode Exit fullscreen mode

And we can verify that it has saved it to the database.

sitemonitor=# select * from checks;
 id |         site         | up |         created_at         
----+----------------------+----+----------------------------
  1 | https://www.osaas.io | t  | 2025-02-18 22:06:00.415521
  2 | https://www.osaas.io | t  | 2025-02-18 22:06:16.508421
  3 | https://www.osaas.io | t  | 2025-02-19 20:52:54.02972
  4 | https://www.osaas.io | t  | 2025-02-19 21:08:51.192199
(4 rows)
Enter fullscreen mode Exit fullscreen mode

Provide configuration environment variables to Web Runner

If you recall we made it possible to specify which database server it would create or use with the environment variable DB_NAME. How do we provide this configuration to the ping service running as a Web Runner?

For this we can use the Application Config open web service.

So let us start by creating an instance using the OSC command line tool.

% osc web config-create sitemonitor
Configuration service instance available at https://eyevinnlab-sitemonitor.eyevinn-app-config-svc.auto.prod.osaas.io
Enter fullscreen mode Exit fullscreen mode

Opening this URL in a web browser you are presented with a user interface where you can manage configuration variables. Let us add a variable for the database name.

Config service

Now let us replace the web runner we created. Start by removing the one we created.

% osc remove eyevinn-web-runner myping
Are you sure you want to remove myping? (yes/no) yes
Instance removed
Enter fullscreen mode Exit fullscreen mode

And when we now create it again we will refer to the application config service that we created.

% osc create eyevinn-web-runner myping \
  -o GitHubUrl=https://github.com/<your-org>/<your-repo> \
  -o GitHubToken="<your-github-token>" \
  -o OscAccessToken="<your-osc-token>" \
  -o ConfigService=sitemonitor
Enter fullscreen mode Exit fullscreen mode

When we look at the logs we see that it has loaded the environment variables from the application config instance.

Web Runner log

Now let us try to ping again.

% curl https://eyevinnlab-myping.eyevinn-web-runner.auto.prod.osaas.io/ping/www.osaas.io
{"up":true}
Enter fullscreen mode Exit fullscreen mode

And check the new database mynewdb instead.

mynewdb=# select * from checks;
 id |         site         | up |         created_at         
----+----------------------+----+----------------------------
  1 | https://www.osaas.io | t  | 2025-02-19 21:20:43.954277
(1 row)
Enter fullscreen mode Exit fullscreen mode

Conclusion

This was a start and example on how you with the Web Runner open web service can start building solutions based on available open web service in Eyevinn Open Source Cloud without having to provision or manage your own infrastructure.

. . . . . .