From bdd78d25f10452d57b94dcb220ae821f04c2007e Mon Sep 17 00:00:00 2001 From: Ezerous Date: Thu, 7 Jan 2021 14:16:40 +0200 Subject: [PATCH] Enhanced API --- .../src/options/breezeOptions.js | 2 + packages/concordia-pinner/src/app.js | 57 +++++++++++++++++++ packages/concordia-pinner/src/constants.js | 8 ++- packages/concordia-pinner/src/index.js | 33 +++-------- 4 files changed, 73 insertions(+), 27 deletions(-) create mode 100644 packages/concordia-pinner/src/app.js diff --git a/packages/concordia-app/src/options/breezeOptions.js b/packages/concordia-app/src/options/breezeOptions.js index 3f3a15f..ea38e82 100644 --- a/packages/concordia-app/src/options/breezeOptions.js +++ b/packages/concordia-app/src/options/breezeOptions.js @@ -8,6 +8,8 @@ import { const REACT_APP_RENDEZVOUS_HOST = process.env.REACT_APP_RENDEZVOUS_HOST || REACT_APP_RENDEZVOUS_HOST_DEFAULT; const REACT_APP_RENDEZVOUS_PORT = process.env.REACT_APP_RENDEZVOUS_PORT || REACT_APP_RENDEZVOUS_PORT_DEFAULT; +export const RENDEZVOUS_URL = `http://${REACT_APP_RENDEZVOUS_HOST}:${REACT_APP_RENDEZVOUS_PORT}`; + const breezeOptions = { ipfs: { repo: 'concordia', diff --git a/packages/concordia-pinner/src/app.js b/packages/concordia-pinner/src/app.js new file mode 100644 index 0000000..cbf9748 --- /dev/null +++ b/packages/concordia-pinner/src/app.js @@ -0,0 +1,57 @@ +import express from 'express'; +import _ from 'lodash'; +import isReachable from 'is-reachable'; + +import { API_PORT, RENDEZVOUS_URL, WEB3_PROVIDER_URL } from './constants'; + +const POLLING_INTERVAL = 1000; + +let app; +let responseBody = { + ipfs:{id:"", localAddresses:[], peers:[], totalPeers:0, repoStats:{}}, + orbit:{identity:{}, databases:[]}, + web3:{url:WEB3_PROVIDER_URL, reachable: false}, + rendezvous:{url:RENDEZVOUS_URL, reachable: false}, + timestamp:0 +}; + +export function startAPI(orbit){ + app = express(); + app.get('/', async (req, res) => { + res.send(responseBody); + }); + + app.listen(API_PORT, () => { + console.log(`Pinner API at http://localhost:${API_PORT}!`); + }); + setInterval(getStats, POLLING_INTERVAL, orbit); +} + +async function getStats(orbit) { + try { + const ipfs = orbit._ipfs; + const {id} = await ipfs.id(); + const peers = await ipfs.swarm.peers(); + const localAddresses = await ipfs.swarm.localAddrs(); + const repoStats = await ipfs.stats.repo(); + const uniquePeers = _.uniqBy(peers, 'peer'); + const orbitIdentity = orbit.identity; + const databases = Object.keys(orbit.stores); + const isWeb3Reachable = await isReachable(WEB3_PROVIDER_URL); + const isRendezvousReachable = await isReachable(RENDEZVOUS_URL); + const timestamp = + new Date(); + + responseBody.ipfs.id = id; + responseBody.ipfs.peers = uniquePeers; + responseBody.ipfs.totalPeers = uniquePeers.length; + responseBody.ipfs.localAddresses = localAddresses; + responseBody.ipfs.repoStats = repoStats; + responseBody.orbit.identity = orbitIdentity; + responseBody.orbit.databases = databases; + responseBody.web3.reachable = isWeb3Reachable; + responseBody.rendezvous.reachable = isRendezvousReachable; + responseBody.timestamp = timestamp; + } catch (err) { + console.error('Error while getting stats:', err) + } +} diff --git a/packages/concordia-pinner/src/constants.js b/packages/concordia-pinner/src/constants.js index cd55e2c..5acb7f8 100644 --- a/packages/concordia-pinner/src/constants.js +++ b/packages/concordia-pinner/src/constants.js @@ -1,9 +1,13 @@ -import breezeOptions from 'concordia-app/src/options/breezeOptions'; +import breezeOptions, {RENDEZVOUS_URL} from 'concordia-app/src/options/breezeOptions'; import { WEB3_HOST_DEFAULT, WEB3_PORT_DEFAULT } from 'concordia-app/src/constants/configuration/defaults'; const { WEB3_HOST, WEB3_PORT } = process.env; -export const web3ProviderUrl = (WEB3_HOST !== undefined && WEB3_PORT !== undefined) +const API_PORT = process.env.PINNER_API_PORT || 4444; + +const WEB3_PROVIDER_URL = (WEB3_HOST !== undefined && WEB3_PORT !== undefined) ? `ws://${WEB3_HOST}:${WEB3_PORT}` : `ws://${WEB3_HOST_DEFAULT}:${WEB3_PORT_DEFAULT}`; export const swarmAddresses = breezeOptions.ipfs.config.Addresses.Swarm; + +export {API_PORT, WEB3_PROVIDER_URL, RENDEZVOUS_URL}; diff --git a/packages/concordia-pinner/src/index.js b/packages/concordia-pinner/src/index.js index 196650e..edb108b 100644 --- a/packages/concordia-pinner/src/index.js +++ b/packages/concordia-pinner/src/index.js @@ -1,14 +1,11 @@ import Web3 from 'web3'; import Contract from 'web3-eth-contract'; import IPFS from 'ipfs'; -import express from 'express' -import isReachable from 'is-reachable'; //TODO: health checking web3 network and rendezvous -import _ from 'lodash'; import { forumContract } from 'concordia-contracts'; import { createOrbitInstance, getPeerDatabases, openKVDBs } from './utils/orbitUtils'; import ipfsOptions from './options/ipfsOptions'; -import { web3ProviderUrl } from './constants'; -const API_PORT = process.env.PINNER_API_PORT || 4444; +import { WEB3_PROVIDER_URL } from './constants'; +import { startAPI } from './app'; process.on('unhandledRejection', error => { // This happens when attempting to initialize without any available Swarm addresses (e.g. Rendezvous) @@ -18,18 +15,17 @@ process.on('unhandledRejection', error => { } }); -let ipfs; - async function main () { - const web3 = new Web3(new Web3.providers.WebsocketProvider(web3ProviderUrl)); + console.log('Initializing...'); + const web3 = new Web3(new Web3.providers.WebsocketProvider(WEB3_PROVIDER_URL)); const networkId = await web3.eth.net.getId(); const contractAddress = forumContract.networks[networkId].address; - Contract.setProvider(web3ProviderUrl); + Contract.setProvider(WEB3_PROVIDER_URL); const contract = new Contract(forumContract.abi, contractAddress); - ipfs = await IPFS.create(ipfsOptions); + const ipfs = await IPFS.create(ipfsOptions); const orbit = await createOrbitInstance(ipfs, contractAddress); // Open & replicate databases of existing users @@ -56,21 +52,8 @@ async function main () { getPeerDatabases(orbit, userAddresses).then(peerDBs => openKVDBs(orbit, peerDBs)); } }); + + startAPI(orbit); } main(); - -const app = express(); - -app.get('/', async (req, res) => { - let responseBody = {peers:[], totalPeers:0}; - const peers = await ipfs.swarm.peers(); //TODO: surround with try - const uniquePeers = _.uniqBy(peers, 'peer'); - responseBody.peers = uniquePeers; - responseBody.totalPeers = uniquePeers.length; - res.send(responseBody); -}); - -app.listen(API_PORT, () => { - console.log(`Pinner API at http://localhost:${API_PORT}!`); -});