-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Example: Add datasource-streaming-backend-websocket (#179)
* Add datasource-streaming-backend-websocket example * Add example websocket server
- Loading branch information
1 parent
e6413cf
commit cd09a23
Showing
49 changed files
with
23,727 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Datasource Streaming Backend example | ||
|
||
This is an example of how to implement a Grafana data source plugin with streaming backend support. | ||
|
||
The plugin connects to the backend through a streaming connection and the backend establishes a connection to an external websocket server. | ||
|
||
## Build | ||
|
||
Build the data source plugin | ||
|
||
```sh | ||
cd streaming-backend-websocket-plugin | ||
mage -v | ||
yarn install | ||
yarn build | ||
``` | ||
|
||
and run the grafana and the example websocket server with docker compose: | ||
|
||
```sh | ||
cd streaming-backend-websocket-plugin | ||
docker compose up -d # or docker-compse up -d for old docker versions | ||
``` | ||
|
||
The server can be accessed by the Grafana backend in `ws://websocket-server:8080`. | ||
|
||
Check the [`docker-compose.yaml`](./streaming-backend-websocket-plugin/docker-compose.yaml) for more details. | ||
|
||
The example server sends random numbers controlled by a query parameter. | ||
|
||
## Packages | ||
|
||
### `streaming-backend-websocket-plugin` | ||
|
||
This package contains a Grafana data source plugin that establishes a connection to a WebSocket server, and updates the visualization whenever it receives a new message. | ||
|
||
### `websocket-server` | ||
|
||
This package contains a WebSocket server that returns random values at random intervals. |
13 changes: 13 additions & 0 deletions
13
...tasource-streaming-backend-websocket/streaming-backend-websocket-plugin/.config/.eslintrc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/* | ||
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ | ||
* | ||
* In order to extend the configuration follow the steps in | ||
* https://grafana.github.io/plugin-tools/docs/advanced-configuration#extending-the-eslint-config | ||
*/ | ||
{ | ||
"extends": ["@grafana/eslint-config"], | ||
"root": true, | ||
"rules": { | ||
"react/prop-types": "off" | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
...rce-streaming-backend-websocket/streaming-backend-websocket-plugin/.config/.prettierrc.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/* | ||
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ | ||
* | ||
* In order to extend the configuration follow the steps in .config/README.md | ||
*/ | ||
|
||
module.exports = { | ||
"endOfLine": "auto", | ||
"printWidth": 120, | ||
"trailingComma": "es5", | ||
"semi": true, | ||
"jsxSingleQuote": false, | ||
"singleQuote": true, | ||
"useTabs": false, | ||
"tabWidth": 2 | ||
}; |
16 changes: 16 additions & 0 deletions
16
...asource-streaming-backend-websocket/streaming-backend-websocket-plugin/.config/Dockerfile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
ARG grafana_version=latest | ||
ARG grafana_image=grafana-enterprise | ||
|
||
FROM grafana/${grafana_image}:${grafana_version} | ||
|
||
# Make it as simple as possible to access the grafana instance for development purposes | ||
# Do NOT enable these settings in a public facing / production grafana instance | ||
ENV GF_AUTH_ANONYMOUS_ORG_ROLE "Admin" | ||
ENV GF_AUTH_ANONYMOUS_ENABLED "true" | ||
ENV GF_AUTH_BASIC_ENABLED "false" | ||
# Set development mode so plugins can be loaded without the need to sign | ||
ENV GF_DEFAULT_APP_MODE "development" | ||
|
||
# Inject livereload script into grafana index.html | ||
USER root | ||
RUN sed -i 's/<\/body><\/html>/<script src=\"http:\/\/localhost:35729\/livereload.js\"><\/script><\/body><\/html>/g' /usr/share/grafana/public/views/index.html |
164 changes: 164 additions & 0 deletions
164
...treaming-backend-websocket/streaming-backend-websocket-plugin/.config/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
# Default build configuration by Grafana | ||
|
||
**This is an auto-generated directory and is not intended to be changed! ⚠️** | ||
|
||
The `.config/` directory holds basic configuration for the different tools | ||
that are used to develop, test and build the project. In order to make it updates easier we ask you to | ||
not edit files in this folder to extend configuration. | ||
|
||
## How to extend the basic configs? | ||
|
||
Bear in mind that you are doing it at your own risk, and that extending any of the basic configuration can lead | ||
to issues around working with the project. | ||
|
||
### Extending the ESLint config | ||
|
||
Edit the `.eslintrc` file in the project root in order to extend the ESLint configuration. | ||
|
||
**Example:** | ||
|
||
```json | ||
{ | ||
"extends": "./.config/.eslintrc", | ||
"rules": { | ||
"react/prop-types": "off" | ||
} | ||
} | ||
``` | ||
|
||
--- | ||
|
||
### Extending the Prettier config | ||
|
||
Edit the `.prettierrc.js` file in the project root in order to extend the Prettier configuration. | ||
|
||
**Example:** | ||
|
||
```javascript | ||
module.exports = { | ||
// Prettier configuration provided by Grafana scaffolding | ||
...require('./.config/.prettierrc.js'), | ||
|
||
semi: false, | ||
}; | ||
``` | ||
|
||
--- | ||
|
||
### Extending the Jest config | ||
|
||
There are two configuration in the project root that belong to Jest: `jest-setup.js` and `jest.config.js`. | ||
|
||
**`jest-setup.js`:** A file that is run before each test file in the suite is executed. We are using it to | ||
set up the Jest DOM for the testing library and to apply some polyfills. ([link to Jest docs](https://jestjs.io/docs/configuration#setupfilesafterenv-array)) | ||
|
||
**`jest.config.js`:** The main Jest configuration file that extends the Grafana recommended setup. ([link to Jest docs](https://jestjs.io/docs/configuration)) | ||
|
||
#### ESM errors with Jest | ||
|
||
A common issue found with the current jest config involves importing an npm package which only offers an ESM build. These packages cause jest to error with `SyntaxError: Cannot use import statement outside a module`. To work around this we provide a list of known packages to pass to the `[transformIgnorePatterns](https://jestjs.io/docs/configuration#transformignorepatterns-arraystring)` jest configuration property. If need be this can be extended in the following way: | ||
|
||
```javascript | ||
process.env.TZ = 'UTC'; | ||
const { grafanaESModules, nodeModulesToTransform } = require('./config/jest/utils'); | ||
|
||
module.exports = { | ||
// Jest configuration provided by Grafana | ||
...require('./.config/jest.config'), | ||
// Inform jest to only transform specific node_module packages. | ||
transformIgnorePatterns: [nodeModulesToTransform([...grafanaESModules, 'packageName'])], | ||
}; | ||
``` | ||
|
||
--- | ||
|
||
### Extending the TypeScript config | ||
|
||
Edit the `tsconfig.json` file in the project root in order to extend the TypeScript configuration. | ||
|
||
**Example:** | ||
|
||
```json | ||
{ | ||
"extends": "./.config/tsconfig.json", | ||
"compilerOptions": { | ||
"preserveConstEnums": true | ||
} | ||
} | ||
``` | ||
|
||
--- | ||
|
||
### Extending the Webpack config | ||
|
||
Follow these steps to extend the basic Webpack configuration that lives under `.config/`: | ||
|
||
#### 1. Create a new Webpack configuration file | ||
|
||
Create a new config file that is going to extend the basic one provided by Grafana. | ||
It can live in the project root, e.g. `webpack.config.ts`. | ||
|
||
#### 2. Merge the basic config provided by Grafana and your custom setup | ||
|
||
We are going to use [`webpack-merge`](https://github.com/survivejs/webpack-merge) for this. | ||
|
||
```typescript | ||
// webpack.config.ts | ||
import type { Configuration } from 'webpack'; | ||
import { merge } from 'webpack-merge'; | ||
import grafanaConfig from './.config/webpack/webpack.config'; | ||
|
||
const config = async (env): Promise<Configuration> => { | ||
const baseConfig = await grafanaConfig(env); | ||
|
||
return merge(baseConfig, { | ||
// Add custom config here... | ||
output: { | ||
asyncChunks: true, | ||
}, | ||
}); | ||
}; | ||
|
||
export default config; | ||
``` | ||
|
||
#### 3. Update the `package.json` to use the new Webpack config | ||
|
||
We need to update the `scripts` in the `package.json` to use the extended Webpack configuration. | ||
|
||
**Update for `build`:** | ||
|
||
```diff | ||
-"build": "webpack -c ./.config/webpack/webpack.config.ts --env production", | ||
+"build": "webpack -c ./webpack.config.ts --env production", | ||
``` | ||
|
||
**Update for `dev`:** | ||
|
||
```diff | ||
-"dev": "webpack -w -c ./.config/webpack/webpack.config.ts --env development", | ||
+"dev": "webpack -w -c ./webpack.config.ts --env development", | ||
``` | ||
|
||
### Configure grafana image to use when running docker | ||
|
||
By default `grafana-enterprise` will be used as the docker image for all docker related commands. If you want to override this behaviour simply alter the `docker-compose.yaml` by adding the following build arg `grafana_image`. | ||
|
||
**Example:** | ||
|
||
```yaml | ||
version: '3.7' | ||
|
||
services: | ||
grafana: | ||
container_name: 'myorg-basic-app' | ||
build: | ||
context: ./.config | ||
args: | ||
grafana_version: ${GRAFANA_VERSION:-9.1.2} | ||
grafana_image: ${GRAFANA_IMAGE:-grafana} | ||
``` | ||
In this example we are assigning the environment variable `GRAFANA_IMAGE` to the build arg `grafana_image` with a default value of `grafana`. This will give you the possibility to set the value while running the docker-compose commands which might be convinent in some scenarios. | ||
|
||
--- |
25 changes: 25 additions & 0 deletions
25
...urce-streaming-backend-websocket/streaming-backend-websocket-plugin/.config/jest-setup.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* | ||
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ | ||
* | ||
* In order to extend the configuration follow the steps in | ||
* https://grafana.github.io/plugin-tools/docs/advanced-configuration#extending-the-jest-config | ||
*/ | ||
|
||
import '@testing-library/jest-dom'; | ||
|
||
// https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom | ||
Object.defineProperty(global, 'matchMedia', { | ||
writable: true, | ||
value: jest.fn().mockImplementation((query) => ({ | ||
matches: false, | ||
media: query, | ||
onchange: null, | ||
addListener: jest.fn(), // deprecated | ||
removeListener: jest.fn(), // deprecated | ||
addEventListener: jest.fn(), | ||
removeEventListener: jest.fn(), | ||
dispatchEvent: jest.fn(), | ||
})), | ||
}); | ||
|
||
HTMLCanvasElement.prototype.getContext = () => {}; |
43 changes: 43 additions & 0 deletions
43
...rce-streaming-backend-websocket/streaming-backend-websocket-plugin/.config/jest.config.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ | ||
* | ||
* In order to extend the configuration follow the steps in | ||
* https://grafana.github.io/plugin-tools/docs/advanced-configuration#extending-the-jest-config | ||
*/ | ||
|
||
const path = require('path'); | ||
const { grafanaESModules, nodeModulesToTransform } = require('./jest/utils'); | ||
|
||
module.exports = { | ||
moduleNameMapper: { | ||
'\\.(css|scss|sass)$': 'identity-obj-proxy', | ||
'react-inlinesvg': path.resolve(__dirname, 'jest', 'mocks', 'react-inlinesvg.tsx'), | ||
}, | ||
modulePaths: ['<rootDir>/src'], | ||
setupFilesAfterEnv: ['<rootDir>/jest-setup.js'], | ||
testEnvironment: 'jest-environment-jsdom', | ||
testMatch: [ | ||
'<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}', | ||
'<rootDir>/src/**/*.{spec,test,jest}.{js,jsx,ts,tsx}', | ||
'<rootDir>/src/**/*.{spec,test,jest}.{js,jsx,ts,tsx}', | ||
], | ||
transform: { | ||
'^.+\\.(t|j)sx?$': [ | ||
'@swc/jest', | ||
{ | ||
sourceMaps: 'inline', | ||
jsc: { | ||
parser: { | ||
syntax: 'typescript', | ||
tsx: true, | ||
decorators: false, | ||
dynamicImport: true, | ||
}, | ||
}, | ||
}, | ||
], | ||
}, | ||
// Jest will throw `Cannot use import statement outside module` if it tries to load an | ||
// ES module without it being transformed first. ./config/README.md#esm-errors-with-jest | ||
transformIgnorePatterns: [nodeModulesToTransform(grafanaESModules)], | ||
}; |
25 changes: 25 additions & 0 deletions
25
...ckend-websocket/streaming-backend-websocket-plugin/.config/jest/mocks/react-inlinesvg.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// Due to the grafana/ui Icon component making fetch requests to | ||
// `/public/img/icon/<icon_name>.svg` we need to mock react-inlinesvg to prevent | ||
// the failed fetch requests from displaying errors in console. | ||
|
||
import React from 'react'; | ||
|
||
type Callback = (...args: any[]) => void; | ||
|
||
export interface StorageItem { | ||
content: string; | ||
queue: Callback[]; | ||
status: string; | ||
} | ||
|
||
export const cacheStore: { [key: string]: StorageItem } = Object.create(null); | ||
|
||
const SVG_FILE_NAME_REGEX = /(.+)\/(.+)\.svg$/; | ||
|
||
const InlineSVG = ({ src }: { src: string }) => { | ||
// testId will be the file name without extension (e.g. `public/img/icons/angle-double-down.svg` -> `angle-double-down`) | ||
const testId = src.replace(SVG_FILE_NAME_REGEX, '$2'); | ||
return <svg xmlns="http://www.w3.org/2000/svg" data-testid={testId} viewBox="0 0 24 24" />; | ||
}; | ||
|
||
export default InlineSVG; |
31 changes: 31 additions & 0 deletions
31
...urce-streaming-backend-websocket/streaming-backend-websocket-plugin/.config/jest/utils.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/* | ||
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ | ||
* | ||
* In order to extend the configuration follow the steps in .config/README.md | ||
*/ | ||
|
||
/* | ||
* This utility function is useful in combination with jest `transformIgnorePatterns` config | ||
* to transform specific packages (e.g.ES modules) in a projects node_modules folder. | ||
*/ | ||
const nodeModulesToTransform = (moduleNames) => `node_modules\/(?!(${moduleNames.join('|')})\/)`; | ||
|
||
// Array of known nested grafana package dependencies that only bundle an ESM version | ||
const grafanaESModules = [ | ||
'.pnpm', // Support using pnpm symlinked packages | ||
'@grafana/schema', | ||
'd3', | ||
'd3-color', | ||
'd3-force', | ||
'd3-interpolate', | ||
'd3-scale-chromatic', | ||
'ol', | ||
'react-colorful', | ||
'rxjs', | ||
'uuid', | ||
]; | ||
|
||
module.exports = { | ||
nodeModulesToTransform, | ||
grafanaESModules, | ||
}; |
Oops, something went wrong.