Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for indexing profile create #35

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ const {

MODULE_NAME_AUDIO,
EVENT_NAME_AUDIO_CREATED,

MODULE_NAME_PROFILE,
EVENT_NAME_PROFILE_CREATED,
} = require('./names');

const COMMAND_EXECUTION_RESULT_TOPICS = ['transactionID'];
Expand Down Expand Up @@ -164,6 +167,9 @@ const EVENT_TOPIC_MAPPINGS_BY_MODULE = {
[MODULE_NAME_AUDIO]: {
[EVENT_NAME_AUDIO_CREATED]: ['transactionID', 'senderAddress'],
},
[MODULE_NAME_PROFILE]: {
[EVENT_NAME_PROFILE_CREATED]: ['transactionID', 'senderAddress'],
},
};

module.exports = {
Expand Down
7 changes: 7 additions & 0 deletions services/blockchain-connector/shared/sdk/constants/names.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ const EVENT_NAME_COLLECTION_TRANSFERED = 'collectionTransfered';
const MODULE_NAME_AUDIO = 'audio';
const EVENT_NAME_AUDIO_CREATED = 'audioCreated';

// Profiles
const MODULE_NAME_PROFILE = 'profile';
const EVENT_NAME_PROFILE_CREATED = 'profileCreated';

module.exports = {
MODULE_NAME_AUTH,
EVENT_NAME_MULTISIGNATURE_REGISTERED,
Expand Down Expand Up @@ -173,4 +177,7 @@ module.exports = {

MODULE_NAME_AUDIO,
EVENT_NAME_AUDIO_CREATED,

MODULE_NAME_PROFILE,
EVENT_NAME_PROFILE_CREATED,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const {
HTTP: { StatusCodes: { BAD_REQUEST } },
Exceptions: { ValidationException, InvalidParamsException },
} = require('lisk-service-framework');

const dataService = require('../../../shared/dataService');

const getProfiles = async params => {
const profiles = {
data: [],
meta: {},
};

try {
const response = await dataService.getProfiles(params);
if (response.data) profiles.data = response.data;
if (response.meta) profiles.meta = response.meta;

return profiles;
} catch (err) {
let status;
if (err instanceof InvalidParamsException) status = 'INVALID_PARAMS';
if (err instanceof ValidationException) status = BAD_REQUEST;
if (status) return { status, data: { error: err.message } };
throw err;
}
};

module.exports = {
getProfiles,
};
16 changes: 16 additions & 0 deletions services/blockchain-indexer/methods/dataService/modules/profile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const {
getProfiles,
} = require('../controllers/profiles');

module.exports = [
{
name: 'profiles',
controller: getProfiles,
params: {
creatorAddress: { optional: true, type: 'string' },
profileID: { optional: true, type: 'string' },
limit: { optional: true, type: 'number' },
offset: { optional: true, type: 'number' },
},
},
];
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,12 @@ const {
getNetworkDisconnectedPeers,
getNetworkPeersStatistics,
} = require('./network');

// Muzikie Dedicated Modules
const { getSubscriptions } = require('./subscriptions');
const { getCollections } = require('./collections');
const { getAudios } = require('./audios');
const { getProfiles } = require('./profiles');

module.exports = {
// Generators
Expand Down Expand Up @@ -187,4 +190,7 @@ module.exports = {

// audios
getAudios,

// profiles
getProfiles,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
const {
MySQL: { getTableInstance },
} = require('lisk-service-framework');
const BluebirdPromise = require('bluebird');
const transactionsIndexSchema = require('../../database/schema/profiles');
const socialAccountsIndexSchema = require('../../database/schema/socialAccounts');
const config = require('../../../config');

const MYSQL_ENDPOINT = config.endpoints.mysql;

const getProfilesIndex = () => getTableInstance(
transactionsIndexSchema.tableName,
transactionsIndexSchema,
MYSQL_ENDPOINT,
);

const getSocialAccountsIndex = () => getTableInstance(
socialAccountsIndexSchema.tableName,
socialAccountsIndexSchema,
MYSQL_ENDPOINT,
);

const getProfiles = async (params = {}) => {
const profilesTable = await getProfilesIndex();
const total = await profilesTable.count(params);
const profilesData = await profilesTable.find(
{ ...params, limit: params.limit || 10 },
// ['profileID', 'name', 'nickName', 'description', 'socialAccounts', 'creatorAddress'],
['profileID', 'name', 'nickName', 'description', 'creatorAddress'],
);
const socialAccountsTable = await getSocialAccountsIndex();

const data = await BluebirdPromise.map(
profilesData,
async (profile) => {
const socialData = await socialAccountsTable.find(
{ profileID: profile.profileID },
['profileID', 'username', 'platform'],
);

return {
...profile,
socialAccounts: socialData,
};
},
{ concurrency: profilesData.length },
);

const result = {
data,
meta: {
count: data.length,
offset: parseInt(params.offset, 10) || 0,
total,
},
};
return result;
};

module.exports = {
getProfiles,
};
4 changes: 4 additions & 0 deletions services/blockchain-indexer/shared/dataService/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ const { getGenerators } = require('./generators');
const { getSubscriptions } = require('./subscriptions');
const { getCollections } = require('./collections');
const { getAudios } = require('./audios');
const { getProfiles } = require('./profiles');

module.exports = {
// Blocks
Expand Down Expand Up @@ -192,4 +193,7 @@ module.exports = {

// Audios
getAudios,

// Profiles
getProfiles,
};
22 changes: 22 additions & 0 deletions services/blockchain-indexer/shared/dataService/profiles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const { Logger } = require('lisk-service-framework');
const util = require('util');

const logger = Logger();

const business = require('./business');

const getProfiles = async params => {
// Store logs
if (params.profileID) logger.debug(`Retrieved profile with ID ${params.profileID} from Lisk Core`);
else if (params.creatorAddress) logger.debug(`Retrieved profile with creatorAddress: ${params.creatorAddress} from Lisk Core`);
else logger.debug(`Retrieved profile with custom search: ${util.inspect(params)} from Lisk Core`);

// Get data from server
const response = await business.getProfiles(params);

return response;
};

module.exports = {
getProfiles,
};
30 changes: 30 additions & 0 deletions services/blockchain-indexer/shared/database/schema/profiles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module.exports = {
tableName: 'profiles',
primaryKey: 'profileID',
schema: {
profileID: { type: 'string' },
name: { type: 'string', null: true, defaultValue: null },
nickName: { type: 'string', null: true, defaultValue: null },
description: { type: 'string', null: true, defaultValue: null },
// @TODO: Modify Schema in order to support social media accounts
// socialAccounts: { type: 'array',
// items: {
// type: 'object',
// props: {
// username: { type: 'string', null: true, defaultValue: null },
// platform: { type: 'integer', null: true, defaultValue: null },
// },
// },
// },
avatarHash: { type: 'string', null: true, defaultValue: null },
avatarSignature: { type: 'string', null: true, defaultValue: null },
bannerHash: { type: 'string', null: true, defaultValue: null },
bannerSignature: { type: 'string', null: true, defaultValue: null },
// @TODO: creationDate: { type: 'string', null: true, defaultValue: null },
creatorAddress: { type: 'string', null: true, defaultValue: null },
},
indexes: {
creatorAddress: { type: 'string' },
},
purge: {},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = {
tableName: 'socialAccounts',
primaryKey: 'profileID',
schema: {
profileID: { type: 'string' },
username: { type: 'string', null: true, defaultValue: null },
platform: { type: 'string', null: true, defaultValue: null },
},
indexes: {
profileID: { type: 'string' },
},
purge: {},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
const {
Logger,
MySQL: { getTableInstance },
} = require('lisk-service-framework');
const BluebirdPromise = require('bluebird');

const { getLisk32AddressFromPublicKey } = require('../../../utils/account');

const config = require('../../../../config');

const logger = Logger();

const MYSQL_ENDPOINT = config.endpoints.mysql;
const accountsTableSchema = require('../../../database/schema/accounts');
const profilesTableSchema = require('../../../database/schema/profiles');
const socialAccountsTableSchema = require('../../../database/schema/socialAccounts');

const {
MODULE_NAME_PROFILE,
EVENT_NAME_PROFILE_CREATED,
} = require('../../../../../blockchain-connector/shared/sdk/constants/names');

const getAccountsTable = () => getTableInstance(
accountsTableSchema.tableName,
accountsTableSchema,
MYSQL_ENDPOINT,
);

const getProfilesTable = () => getTableInstance(
profilesTableSchema.tableName,
profilesTableSchema,
MYSQL_ENDPOINT,
);

const getSocialAccountsTable = () => getTableInstance(
socialAccountsTableSchema.tableName,
socialAccountsTableSchema,
MYSQL_ENDPOINT,
);

// Command specific constants
const COMMAND_NAME = 'create';

// eslint-disable-next-line no-unused-vars
const applyTransaction = async (blockHeader, tx, events, dbTrx) => {
const accountsTable = await getAccountsTable();
const profilesTable = await getProfilesTable();
const socialAccountsTable = await getSocialAccountsTable();
const senderAddress = getLisk32AddressFromPublicKey(tx.senderPublicKey);

const account = {
address: senderAddress,
};

logger.trace(`Updating account index for the account with address ${account.address}.`);
await accountsTable.upsert(account, dbTrx);
logger.debug(`Updated account index for the account with address ${account.address}.`);

logger.trace(`Indexing profiles with address ${account.address}.`);

const { data: eventData = {} } = events.find(
({ module, name }) => module === MODULE_NAME_PROFILE
&& name === EVENT_NAME_PROFILE_CREATED,
);

const profile = {
...eventData,
...tx.params,
};

await BluebirdPromise.map(
tx.params.socialAccounts,
async socialAccount => {
const socialInfo = {
profileID: eventData.profileID,
username: socialAccount.username,
platform: socialAccount.platform,
};
logger.trace(`Inserting social sccounts for the profile with ID ${eventData.profileID}.`);
await socialAccountsTable.upsert(socialInfo, dbTrx);
logger.debug(`Inserted social sccounts for the profile with ID ${eventData.profileID}.`);
return true;
},
{ concurrency: tx.params.socialAccounts.length },
);

await profilesTable.upsert(profile, dbTrx);
logger.debug(`Indexed profile with ID ${eventData.profileID}.`);
};

// eslint-disable-next-line no-unused-vars
const revertTransaction = async (blockHeader, tx, events, dbTrx) => {};

module.exports = {
COMMAND_NAME,
applyTransaction,
revertTransaction,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Module specific constants
const MODULE_NAME = 'profile';

module.exports = {
MODULE_NAME,
};
Loading