Skip to content

Commit

Permalink
Merge pull request #304 from Chia-Network/feature/import-organization…
Browse files Browse the repository at this point in the history
…-api

feat: add import organization api
  • Loading branch information
MichaelTaylor3D authored Feb 16, 2022
2 parents 5ad42ec + f5e355b commit 471766e
Show file tree
Hide file tree
Showing 11 changed files with 188 additions and 30 deletions.
18 changes: 17 additions & 1 deletion src/controllers/organization.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,23 @@ export const create = async (req, res) => {
};

// eslint-disable-next-line
export const importOrg = async (req, res) => {};
export const importOrg = async (req, res) => {
const { orgUid, ip, port } = req.body;
try {
res.json({
message:
'Importing and subscribing organization this can take a few mins.',
});

return Organization.importOrganization(orgUid, ip, port);
} catch (error) {
console.trace(error);
res.status(400).json({
message: 'Error importing organization',
error: error.message,
});
}
};

export const subscribeToOrganization = async (req, res) => {
try {
Expand Down
42 changes: 38 additions & 4 deletions src/datalayer/persistance.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ export const getRoot = async (storeId) => {

try {
const data = JSON.parse(response);
console.log(data);
if (data.status === 2) {
console.log(`Root for ${storeId}`, data);
if (data.status === 2 && !data.hash.includes('0x00000000000')) {
return data;
}

Expand All @@ -138,11 +138,14 @@ export const getStoreData = async (storeId) => {
const data = JSON.parse(response);

if (data.success) {
console.log('Downloaded Data', data);
return data;
}

console.log('&&&&', data);
}

return new Error('Error getting datalayer store data');
return false;
};

export const dataLayerAvailable = async () => {
Expand All @@ -158,7 +161,7 @@ export const dataLayerAvailable = async () => {

const data = JSON.parse(response);

if (Object.keys(data).includes('success')) {
if (Object.keys(data).includes('success') && data.success) {
return true;
}

Expand All @@ -167,3 +170,34 @@ export const dataLayerAvailable = async () => {
return false;
}
};

export const subscribeToStoreOnDataLayer = async (storeId, ip, port) => {
const options = {
url: `${rpcUrl}/subscribe`,
body: JSON.stringify({
id: storeId,
ip,
port,
}),
};

console.log('Subscribing to: ', storeId, ip, port);

try {
const response = await request(
Object.assign({}, getBaseOptions(), options),
);

const data = JSON.parse(response);

if (Object.keys(data).includes('success') && data.success) {
console.log('Successfully Subscribed: ', storeId, ip, port);
return data;
}

return false;
} catch (error) {
console.log('Error Subscribing: ', error);
return false;
}
};
2 changes: 1 addition & 1 deletion src/datalayer/simulator.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,4 @@ export const dataLayerAvailable = async () => {
};

// eslint-disable-next-line
export const subscribeToStore = async (storeId) => {};
export const subscribeToStoreOnDataLayer = async (storeId) => {};
66 changes: 62 additions & 4 deletions src/datalayer/syncService.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import _ from 'lodash';

import logUpdate from 'log-update';

import { decodeHex } from '../utils/datalayer-utils';
import { decodeHex, decodeDataLayerResponse } from '../utils/datalayer-utils';
import { Organization, Staging, ModelKeys } from '../models';

import * as dataLayer from './persistance';
Expand Down Expand Up @@ -115,8 +115,6 @@ export const dataLayerWasUpdated = async () => {
rootResponse = await dataLayer.getRoots(subscribedOrgIds);
}

console.log(rootResponse);

if (!rootResponse.success) {
return [];
}
Expand All @@ -127,7 +125,6 @@ export const dataLayerWasUpdated = async () => {
);

if (org) {
console.log(rootHash);
// store has been updated if its confirmed and the hash has changed
return rootHash.status === 2 && org.registryHash != rootHash.hash;
}
Expand Down Expand Up @@ -155,3 +152,64 @@ export const dataLayerWasUpdated = async () => {

return updatedStoreIds;
};

export const subscribeToStoreOnDataLayer = async (storeId, ip, port) => {
if (process.env.USE_SIMULATOR === 'true') {
return simulator.subscribeToStoreOnDataLayer(storeId, ip, port);
} else {
return dataLayer.subscribeToStoreOnDataLayer(storeId, ip, port);
}
};

export const getSubscribedStoreData = async (
storeId,
ip,
port,
alreadySubscribed = false,
retry = 0,
) => {
if (retry > 30) {
throw new Error('Max retrys exceeded, Can not subscribe to organization');
}

if (!alreadySubscribed) {
const response = await subscribeToStoreOnDataLayer(storeId, ip, port);
if (!response.success) {
console.log(`Retrying...`, retry + 1);
console.log('...');
await new Promise((resolve) => setTimeout(() => resolve(), 30000));
return getSubscribedStoreData(storeId, ip, port, false, retry + 1);
}
}

if (process.env.USE_SIMULATOR !== 'true') {
const storeExistAndIsConfirmed = await dataLayer.getRoot(storeId);
if (!storeExistAndIsConfirmed) {
console.log(`Retrying...`, retry + 1);
console.log('...');
await new Promise((resolve) => setTimeout(() => resolve(), 30000));
return getSubscribedStoreData(storeId, ip, port, true, retry + 1);
}
}

let encodedData;
if (process.env.USE_SIMULATOR === 'true') {
encodedData = await simulator.getStoreData(storeId);
} else {
encodedData = await dataLayer.getStoreData(storeId);
}

if (!encodedData) {
console.log(`Retrying...`, retry + 1);
console.log('...');
await new Promise((resolve) => setTimeout(() => resolve(), 30000));
return getSubscribedStoreData(storeId, ip, port, true, retry + 1);
}

const decodedData = decodeDataLayerResponse(encodedData);

return decodedData.reduce((obj, current) => {
obj[current.key] = current.value;
return obj;
}, {});
};
8 changes: 0 additions & 8 deletions src/datalayer/writeService.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,6 @@ export const pushDataLayerChangeList = (storeId, changeList) => {
pushChangesWhenStoreIsAvailable(storeId, changeList);
};

export const subscribeToStore = async (storeId) => {
if (process.env.USE_SIMULATOR === 'true') {
return simulator.subscribeToStore(storeId);
} else {
return dataLayer.subscribeToStore(storeId);
}
};

export const dataLayerAvailable = async () => {
if (process.env.USE_SIMULATOR === 'true') {
return simulator.dataLayerAvailable();
Expand Down
53 changes: 49 additions & 4 deletions src/models/organizations/organizations.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
import Sequelize from 'sequelize';
const { Model } = Sequelize;
import { sequelize } from '../database';
import { createDataLayerStore, syncDataLayer } from '../../datalayer';
import {
createDataLayerStore,
syncDataLayer,
subscribeToStoreOnDataLayer,
getSubscribedStoreData,
} from '../../datalayer';

import ModelTypes from './organizations.modeltypes.cjs';

Expand Down Expand Up @@ -78,8 +83,48 @@ class Organization extends Model {
};

// eslint-disable-next-line
static importHomeOrganization = (orgUid) => {
throw new Error('Not implemented yet');
static importOrganization = async (orgUid, ip, port) => {
const orgData = await getSubscribedStoreData(orgUid, ip, port);

if (!orgData.registryId) {
throw new Error(
'Currupted organization, no registryId on the datalayer, can not import',
);
}

console.log('IMPORTING REGISTRY: ', orgData.registryId);

const registryData = await getSubscribedStoreData(
orgData.registryId,
ip,
port,
);

if (!registryData.v1) {
throw new Error('Organization has no registry, can not import');
}

console.log('IMPORTING REGISTRY V1: ', registryData.v1);

await subscribeToStoreOnDataLayer(registryData.v1, ip, port);

console.log({
orgUid,
name: orgData.name,
icon: orgData.icon,
registryId: registryData.v1,
subscribed: true,
isHome: false,
});

await Organization.upsert({
orgUid,
name: orgData.name,
icon: orgData.icon,
registryId: registryData.v1,
subscribed: true,
isHome: false,
});
};

// eslint-disable-next-line
Expand All @@ -88,7 +133,7 @@ class Organization extends Model {
if (exists) {
await Organization.update({ subscribed: true }, { orgUid });
} else {
Organization.importHomeOrganization(orgUid);
Organization.importOrganization(orgUid);
}
};

Expand Down
1 change: 1 addition & 0 deletions src/models/organizations/organizations.modeltypes.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module.exports = {
type: Sequelize.STRING,
unique: true,
},
orgHash: Sequelize.STRING,
name: Sequelize.STRING,
icon: Sequelize.STRING,
registryId: Sequelize.STRING,
Expand Down
14 changes: 7 additions & 7 deletions src/models/organizations/organizations.stub.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
[
{
"orgUid": "78b472ff171a20a9de44555d8df2dc1d4c44bae5f700453a1e59ea6b2609dc5c",
"orgUid": "a807e453-6524-49df-a32d-785e56cf5600",
"name": "My Org",
"registryId": "c1c017b595356361c09f9d2f7720c7da637548191764c5d6df547ddd25144d58",
"registryId": "9144c974e146920088514534c89371dc269d1b894a2c7f6cedeb80b804c6cd02",
"icon": "https://climate-warehouse.s3.us-west-2.amazonaws.com/public/orgs/me.svg",
"subscribed": false,
"isHome": false
"subscribed": true,
"isHome": true
},
{
"orgUid": "ca1e1619-d073-4283-bdbc-4ad58838f727",
"name": "Earl Registrt",
"name": "Earl Registry",
"registryId": "047b74ea567f7591f463f29dcec4cab1e760ef181c006fb3865a3e20ca6144aa",
"icon": "https://climate-warehouse.s3.us-west-2.amazonaws.com/public/orgs/austria.svg",
"subscribed": true,
"subscribed": false,
"isHome": false
},
{
"orgUid": "26462fbf4a10175dbc6945dd3fda35e05da845532f585d79097e06d77ef7165e",
"name": "Kyles Org Registry",
"registryId": "eb9f9440f11f2705dd97da824f6f27079cbde3ad4ff4252539f17c8f0c08a4f9",
"icon": "https://climate-warehouse.s3.us-west-2.amazonaws.com/public/orgs/denmark.svg",
"subscribed": true,
"subscribed": false,
"isHome": false
}
]
7 changes: 7 additions & 0 deletions src/utils/datalayer-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,10 @@ export const encodeHex = (str) => {
export const decodeHex = (str) => {
return Buffer.from(str.replace('0x', ''), 'hex').toString();
};

export const decodeDataLayerResponse = (data) => {
return data.keys_values.map((item) => ({
key: decodeHex(item.key),
value: decodeHex(item.value),
}));
};
5 changes: 4 additions & 1 deletion tests/resources/projects.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe('Project Resource CRUD', function () {
it('gets all the projects available', async function () {
// no query params
const projects = await testFixtures.getProjectByQuery();
expect(projects.length).to.equal(8);
expect(projects.length).to.equal(11);
});

it('gets all the projects filtered by orgUid', async function () {
Expand All @@ -38,6 +38,7 @@ describe('Project Resource CRUD', function () {
orgUid: 'a807e453-6524-49df-a32d-785e56cf560e',
search: 'City of Arcata',
});

expect(projects.length).to.equal(1);
});

Expand All @@ -53,6 +54,8 @@ describe('Project Resource CRUD', function () {
page: 2,
limit: 3,
});

console.log(projectsPage2);
expect(projectsPage2.data.length).to.equal(3);
expect(projectsPage1.data).to.not.deep.equal(projectsPage2.data);

Expand Down
2 changes: 2 additions & 0 deletions tests/test-fixtures/project-fixtures.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ export const getProject = async (warehouseProjectId) => {
export const getProjectByQuery = async (query = {}) => {
const result = await supertest(app).get('/v1/projects').query(query);
// expect(result.body).to.be.an('array');
expect('!!!!!', result);
expect(result.statusCode).to.equal(200);

return result.body;
};

Expand Down

0 comments on commit 471766e

Please sign in to comment.