InfluxDB API: Onboarding

We use the InfluxDB API via the InfluxDB Javascript client library.

Organize InfluxDB functionality in app/server/influxdb/

When our IoT Center server starts, it should try to connect to InfluxDB. We want to use the InfluxDB API to check that the database is connected, and that the target bucket is present and accessible. If IoT Center doesn’t find those things, it should set up InfluxDB and create the necessary buckets.

Create an onboarding.js file at server/influxdb/onboarding.js.

mkdir influxdb
touch influxdb/onboarding.js

We will place much more code in this directory going forward. For now, we focus on onboarding.

Onboard InfluxDB

First we import the InfluxDB setup API from the client library client. Then, import the configuration variables from env.js.

const {InfluxDB, HttpError} = require('@influxdata/influxdb-client')
const {SetupAPI} = require('@influxdata/influxdb-client-apis')
const {
  INFLUX_URL,
  INFLUX_TOKEN,
  INFLUX_ORG,
  onboarding_username,
  onboarding_password,
  INFLUX_BUCKET,
} = require('../env')

Create the onboardInfluxDB function in onboarding.js. Paste the following:

async function onboardInfluxDB() {
  const url = INFLUX_URL
  const setupApi = new SetupAPI(new InfluxDB({url}))
}

We need the URL of InfluxDB, so we can talk to its API server. In this line we create a SetupAPI object.

We use getSetup() to check whether InfluxDB has been onboarded, and the postSetup() method to do the setup (by POSTing a request to the InfluxDB API).

async function onboardInfluxDB() {
    const url = INFLUX_URL
    const setupApi = new SetupAPI(new InfluxDB({url}))
    const {allowed} = await setupApi.getSetup()
    if (allowed) {
        await setupApi.postSetup({
            body: {
                org: INFLUX_ORG,
                bucket: INFLUX_BUCKET,
                username: onboarding_username,
                password: onboarding_password,
                token: INFLUX_TOKEN,
            },
        })
        console.log(`InfluxDB has been onboarded.`)
    }
    console.log(`InfluxDB was not onboarded.`)
}

The complete onboarding function

Here is the full onboardInfluxDB function:

async function onboardInfluxDB() {
  const url = INFLUX_URL
  const setupApi = new SetupAPI(new InfluxDB({url}))
  try {
    const {allowed} = await setupApi.getSetup()
    if (allowed) {
      await setupApi.postSetup({
        body: {
          org: INFLUX_ORG,
          bucket: INFLUX_BUCKET,
          username: onboarding_username,
          password: onboarding_password,
          token: INFLUX_TOKEN,
        },
      })
      console.log(`InfluxDB has been onboarded.`)
    }
    let bucketNotFound = false
    try {
      await getBucket(INFLUX_BUCKET)
      console.log(`Bucket '${INFLUX_BUCKET}' exists.`)
    } catch (e) {
      if (e instanceof HttpError && e.statusCode === 401) {
        console.error(
          `Unauthorized to determine whether a bucket '${INFLUX_BUCKET}' exists.`
        )
      } else if (e instanceof HttpError && e.statusCode === 404) {
        // bucket not found
        bucketNotFound = true
      } else {
        console.error(
          `Unable to check whether a bucket '${INFLUX_BUCKET}' exists.`,
          e
        )
      }
    }
    if (bucketNotFound) {
      await createBucket(INFLUX_BUCKET)
      console.log(`Bucket ${INFLUX_BUCKET} created.`)
    }
  } catch (error) {
    console.error(
      `Unable to determine whether InfluxDB at ${INFLUX_URL} is onboarded.`,
      error
    )
  }
}

Bucket creation

This snippet creates a bucket if bucketNotFound is true:

if (bucketNotFound) {
  await createBucket(INFLUX_BUCKET)
  console.log(`Bucket ${INFLUX_BUCKET} created.`)
}

createBucket() is another function that we will define in the server/influxdb/ directory.

Conclusion

Next, we start creating our API for managing devices.