import axios from 'axios';
import strapi from 'your-strapi-module';
const apiBase = `https://api.cloudways.com/api/v1`;
const apiKey = process.env.CLOUDWAYS_API;
const email = process.env.CLOUDWAYS_EMAIL;
const maxRps = 10; // max requests per second for throttling
const throttleInterval = 1000 / maxRps;
// a small wrapper around axios for this particular API
// this might best live in a separate module
const apiRequest = async ({ headers = {}, method = 'get', url }) => {
const opts = {
baseUrl: apiBase,
headers,
method,
url
};
return axios(opts).then( (res) => res.data );
};
// method to obtain OAuth token, again perhaps best in separate module with API axios wrapper.
// this could be made to lazily provision the token on any API request if not already received
const getAccessToken = async () => {
const method = 'post';
const url = `/oauth/access_token?email=${ email }&api_key=${ apiKey }`;
const data = await apiRequest({ method, url});
return data.access_token;
};
const getServerList = async () => strapi.query('server').find({});
const throttlewait = async (asyncFn, ms) => {
await new Promise( (resolve) => setTimeout(resolve, ms) );
return asyncFn();
};
const updateServerStatus = async (serverId, accessToken) => {
const url = `/server/monitor/summary?server_id=${ serverId }&type=db`;
const headers = {
Authorization: 'Bearer ' + accessToken
};
return apiRequest({ headers, url })
.then( ({ content }) => {
// I am not throttling here as no need to throttle this data store query was noted
// Ideally, this could be made into single update query though
const promises = content.map( (app) => {
return strapi.query('subscription').update(
{ ApplicationSlug: app.name },
{ DiskUsage: Math.ceil(app.datapoint[0]) }
);
});
return Promise.all(promises);
});
};
const updateAll = async () = {
// we can parallelize getting access token and getting server list
const initPromises = [
getServerList(),
getAccessToken()
];
const [ serverList, accessToken ] = await Promise.all(initPromises);
// map your server list to an array of update promises
const updatePromises = serverList.map((server, i) => {
const fn = () => updateServerStatus(server.ServerId, accessToken);
// here is how we stagger the requests to meet rate limits
constreturn wait = (i * throttleInterval;throttleInterval)
return throttle .then(fn () => updateServerStatus(server.ServerId, waitaccessToken) );
});
return Promise.all(updatePromises);
};
// call the main function somehow (could be exported from module for example)
export {
updateAll as default,
updateAll,
// again, following probably make sense in separate module
apiRequest,
getAccessToken
}