Merge pull request #11 from AAVikings/master

Adding changes after team review
This commit is contained in:
z@tOr authored and GitHub committed 2019-02-01 17:42:24 -03:00
commit 29138dd33b
15 files changed
+146 -121

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@superalgos/operations-client",
"version": "0.0.6",
"version": "0.0.7",
"description": "Superalgos Operations client-side web app",
"main": "src/index.js",
"dependencies": {
+9 -2
View File
@@ -157,7 +157,6 @@ class AddClone extends Component {
<FormHelperText>{this.state.selectedBot.kind}</FormHelperText>
</FormControl>
{ /* TRADER BOT */ }
{ this.state.selectedBot.kind === "TRADER" &&
<React.Fragment>
<Typography className={classes.typography} variant='subtitle1' align='justify'>
@@ -213,6 +212,10 @@ class AddClone extends Component {
fullWidth
/>
<Typography className={classes.typography} variant='subtitle1' align='justify'>
The Wait Time represent the number of miliseconds the bot will wait between executions.
</Typography>
<TextField
id="waitTime"
label="Wait Time"
@@ -261,7 +264,6 @@ class AddClone extends Component {
</React.Fragment>
}
{ /* INDICATOR AND EXTRACTOR BOTS */ }
{ (this.state.selectedBot.kind === "INDICATOR"
|| this.state.selectedBot.kind === "EXTRACTOR") &&
<React.Fragment>
@@ -366,6 +368,11 @@ class AddClone extends Component {
</React.Fragment>
}
<Typography className={classes.typography} variant='subtitle1' align='justify'>
You will your clone information under Active Clones until it finishes the execution, then it will moved to the History.
</Typography>
<div className={classes.actionButton} >
<Button
type="submit"
+2 -2
View File
@@ -107,8 +107,8 @@ class ListClones extends Component {
<Typography className={classes.cloneInfoNormal}>{clone.buyAverage}</Typography>
<Typography className={classes.cloneInfoNormal}>{clone.sellAverage}</Typography>
<Typography className={classes.cloneInfoNormal}>{clone.marketRate}</Typography>
<Typography className={classes.cloneInfoNormal}>{clone.combinedProfitsA}</Typography>
<Typography className={classes.cloneInfoNormal}>{clone.combinedProfitsB}</Typography>
<Typography className={classes.cloneInfoNormal}>{clone.combinedProfitsA}%</Typography>
<Typography className={classes.cloneInfoNormal}>{clone.combinedProfitsB}%</Typography>
</React.Fragment>
}
</div>
+2 -2
View File
@@ -24,13 +24,13 @@ class Home extends Component {
</Typography>
<div className='column'>
<Typography align='justify'>
The Operations module allows you to create copies of your bot
The Operations module allows you to create instances of your bots
that will be executed on a virtual machine.
</Typography>
</div>
<div className='column'>
<Typography align='justify'>
</Typography>
</div>
</div>
+1 -1
View File
@@ -14,7 +14,7 @@
"containers": [
{
"name": "aadev",
"image": "benme/aadev:v3.5",
"image": "benme/aadev:v3.6",
"command": ["node", "Run.js"],
"env": [
]
-14
View File
@@ -7,17 +7,3 @@ export function toPlatformDatetime (epoch) {
export function isDefined (d) {
return d !== null && typeof d !== 'undefined'
}
export function getJobNameFromClone (clone) {
return clone.teamSlug + '-' + clone.botSlug + '-' + clone.mode.toLowerCase()
}
export function getSelectedBot(botsByUser, selectedBotId){
if(isDefined(botsByUser)){
for (var i = 0; i < botsByUser.fb.length; i++) {
if(botsByUser.fb[i].id === selectedBotId){
return botsByUser.fb[i]
}
}
}
}
+9 -1
View File
@@ -2,7 +2,15 @@ import logger from '../config/logger'
export class AuthentificationError extends Error {
code = 401
message = 'Autentification not found, you have to be authentificated to perform this action'
message = 'Autentification not found, you have to be authentificated to perform this action.'
constructor(){
super()
}
}
export class AutorizationError extends Error {
code = 401
message = 'You are not authorized to perform this action.'
constructor(){
super()
}
-30
View File
@@ -1,30 +0,0 @@
import logger from '../config/logger'
import axios from 'axios'
const teamAvatar = async(authorization, teamId) => {
logger.debug('GraphQL call teamAvatar.')
return axios({
url: process.env.GATEWAY_ENDPOINT,
method: 'post',
data: {
query: `
query Teams_Team($teamId: String!){
teams_TeamById(teamId:$teamId) {
profile{
avatar
}
}
}
`,
variables: {
teamId: teamId
}
},
headers: {
authorization: authorization
}
})
};
export default teamAvatar
@@ -1,16 +1,16 @@
import logger from '../config/logger'
import axios from 'axios'
const teams_FbByTeamMember = (authorization) => {
logger.debug('GraphQL call teams_FbByTeamMember')
const teamQuery = async(authorization, teamId) => {
logger.debug('GraphQL retrieving team information. %s', teamId)
return axios({
url: process.env.GATEWAY_ENDPOINT,
method: 'post',
data: {
query: `
query Teams_FbByTeamMember {
teams_FbByTeamMember {
query Teams_Team($teamId: String!){
teams_TeamById(teamId:$teamId) {
id
name
slug
@@ -24,11 +24,18 @@ const teams_FbByTeamMember = (authorization) => {
members {
member {
alias
authId
}
}
profile{
avatar
}
}
}
`,
variables: {
teamId: teamId
}
},
headers: {
authorization: authorization
@@ -36,4 +43,4 @@ const teams_FbByTeamMember = (authorization) => {
})
};
export default teams_FbByTeamMember
export default teamQuery
+40 -12
View File
@@ -1,27 +1,55 @@
import logger from '../config/logger'
import { getJobNameFromClone, getSelectedBot } from '../config/utils'
import teamAvatar from '../graphQLCalls/teamAvatar'
import { isDefined } from '../config/utils'
import { AutorizationError } from '../errors'
// TODO Refactor this code once financial beings api is ready
const cloneDetails = async(authorization, botsByUser, clone) => {
const cloneDetails = async(authId, team, clone) => {
logger.debug('Retrieving clone details.')
let selectedBot = getSelectedBot(botsByUser.data.data.teams_FbByTeamMember, clone.botId)
clone.teamId = botsByUser.data.data.teams_FbByTeamMember.id
if(!isAuthorized(team, authId)){
logger.debug('User %s is not authorized to manage team %s.', authId, team.slug )
throw new AutorizationError()
}
let selectedBot = getSelectedBot(team, clone.botId)
clone.teamId = team.id
clone.botId = selectedBot.id
clone.kind = selectedBot.kind
clone.teamSlug = botsByUser.data.data.teams_FbByTeamMember.slug
clone.teamSlug = team.slug
clone.botSlug = selectedBot.slug
clone.cloneName = getJobNameFromClone(clone)
clone.teamName = botsByUser.data.data.teams_FbByTeamMember.name
clone.cloneName = clone.teamSlug + '-' + clone.botSlug + '-' + clone.mode.toLowerCase()
clone.teamName = team.name
clone.botName = selectedBot.name
clone.botAvatar = selectedBot.avatar
let team = await teamAvatar(authorization, botsByUser.data.data.teams_FbByTeamMember.id)
clone.teamAvatar = team.data.data.teams_TeamById.profile.avatar
clone.userLoggedIn = botsByUser.data.data.teams_FbByTeamMember.members[0].member.alias //TODO change by context info if possible
clone.teamAvatar = team.profile.avatar
clone.userLoggedIn = team.members[0].member.alias //TODO change by context info if possible
logger.debug('Retrieving clone details complete.')
return clone
};
function getSelectedBot(team, selectedBotId){
logger.debug('Getting selected bot.')
if(isDefined(team)){
for (var i = 0; i < team.fb.length; i++) {
if(team.fb[i].id === selectedBotId){
return team.fb[i]
}
}
}
}
function isAuthorized(team, authId){
logger.debug('Checking if the user is authorized by the teams module.')
let authorized = false
if(isDefined(team)){
for (var i = 0; i < team.members.length; i++) {
if(team.members[i].member.authId === authId){
authorized = true
break
}
}
}
return authorized
}
export default cloneDetails
@@ -3,7 +3,7 @@ import { CloneType } from '../types';
import { Clone } from '../../models';
import { CloneModeEnum } from '../../enums/CloneMode';
import { BotTypesEnum } from '../../enums/BotTypes';
import teams_FbByTeamMember from '../../graphQLCalls/teams_FbByTeamMember';
import teamQuery from '../../graphQLCalls/teamQuery'
import cloneDetails from '../cloneDetails'
import {
@@ -14,7 +14,7 @@ import {
import logger from '../../config/logger'
import createKubernetesClone from '../../kubernetes/createClone'
import { isDefined, getSelectedBot } from '../../config/utils'
import { isDefined } from '../../config/utils'
const args = {
clone: {type: CloneInputType }
@@ -50,10 +50,8 @@ const resolve = async(parent, { clone }, context) => {
}
try{
// Authorization is handled by the teams module
let botsByUser = await teams_FbByTeamMember(context.authorization)
clone = await cloneDetails(context.authorization, botsByUser, clone)
let selectedBot = getSelectedBot(botsByUser.data.data.teams_FbByTeamMember, clone.botId)
let team = await teamQuery(context.authorization)
clone = await cloneDetails(context.userId, team.data.data.teams_TeamById, clone)
clone.createDatetime = new Date().valueOf() / 1000|0
clone.active = true
@@ -12,8 +12,8 @@ import {
import { Clone } from '../../models'
import logger from '../../config/logger'
import removeKuberneteClone from '../../kubernetes/removeClone'
import teams_FbByTeamMember from '../../graphQLCalls/teams_FbByTeamMember'
import { isDefined, getSelectedBot } from '../../config/utils'
import teamQuery from '../../graphQLCalls/teamQuery'
import { isDefined } from '../../config/utils'
import cloneDetails from '../cloneDetails'
const args = {
@@ -37,8 +37,8 @@ const resolve = async (parent, { id }, context) => {
throw new OperationsError('You are not authorized to remove this clone.')
}
let botsByUser = await teams_FbByTeamMember(context.authorization)
clone = await cloneDetails(context.authorization, botsByUser, clone)
let team = await teamQuery(context.authorization)
clone = await cloneDetails(context.userId, team.data.data.teams_TeamById, clone)
logger.debug('removeClone -> Removing Clone from Kubernates.')
await removeKuberneteClone(clone)
@@ -7,12 +7,12 @@ import {
} from 'graphql'
import {
OperationsError
} from '../../errors'
import { Clone } from '../../models'
import logger from '../../config/logger'
import teamQuery from '../../graphQLCalls/teamQuery'
const args = {
id: { type: new GraphQLNonNull(GraphQLID) },
@@ -29,34 +29,57 @@ const args = {
const resolve = async (parent,
{ id, summaryDate, buyAverage, sellAverage, marketRate, combinedProfitsA,
combinedProfitsB, assetA, assetB
}) => {
}, context) => {
logger.debug('UpdateExecutionSummary -> Entering Function.')
const query = { _id: id }
const options = { new: true }
const update = {
summaryDate: summaryDate,
buyAverage: buyAverage,
sellAverage: sellAverage,
marketRate: marketRate,
combinedProfitsA: combinedProfitsA,
combinedProfitsB: combinedProfitsB,
assetA: assetA,
assetB: assetB
if (!context.userId) {
throw new AuthentificationError()
}
let sucessful
await Clone.findOneAndUpdate(query, update, options, (err, doc) => {
if (err){
throw new OperationsError(err)
} else {
logger.debug('Execution summary updated')
sucessful = true
}
})
try{
let sucessful
if(sucessful){
return 'Execution summary updated.'
let clone = await Clone.findOne( {
_id: id,
active: true
})
let team = await teamQuery(context.authorization)
clone = await cloneDetails(context.userId, team.data.data.teams_TeamById, clone)
logger.debug('removeClone -> Removing Clone from Kubernates.')
await removeKuberneteClone(clone)
const query = { _id: id }
const options = { new: true }
const update = {
summaryDate: summaryDate,
buyAverage: buyAverage,
sellAverage: sellAverage,
marketRate: marketRate,
combinedProfitsA: combinedProfitsA,
combinedProfitsB: combinedProfitsB,
assetA: assetA,
assetB: assetB
}
await Clone.update(query, update, (err) => {
if (err){
logger.error('Error updating execution summary on the database. %s', err.stack)
throw new OperationsError(err.message)
} else {
logger.debug('Execution summary updated.')
sucessful = true
}
})
if(sucessful){
return 'Execution summary updated.'
}
} catch (error) {
logger.error('Error updating the execution summary. %s', error.stack)
throw new OperationsError(error.message)
}
}
+12 -10
View File
@@ -3,7 +3,8 @@ import {
} from 'graphql'
import {
AuthentificationError
AuthentificationError,
OperationsError
} from '../../errors'
import { CloneType } from '../types'
@@ -11,14 +12,14 @@ import { Clone } from '../../models'
import logger from '../../config/logger'
import getKuberneteClonePodStatus from '../../kubernetes/getClonePodStatus'
import getKuberneteClonePodLogs from '../../kubernetes/getClonePodLogs'
import teams_FbByTeamMember from '../../graphQLCalls/teams_FbByTeamMember'
import cloneDetails from '../cloneDetails'
import teamQuery from '../../graphQLCalls/teamQuery'
const args = {}
const resolve = async(parent, args, context) => {
logger.debug('History Clones -> Entering Fuction.')
logger.debug('Retrieving History Clones.')
try{
if (!context.userId) {
throw new AuthentificationError()
}
@@ -26,18 +27,19 @@ const resolve = async(parent, args, context) => {
let clones = await Clone.find({
authId: context.userId,
active: false
})
// TODO Refactor this code once financial beings api is ready
// Authorization is handled by the teams module
let botsByUser = await teams_FbByTeamMember(context.authorization)
}).sort({createDatetime: -1})
for (var i = 0; i < clones.length; i++) {
clones[i] = await cloneDetails(context.authorization, botsByUser, clones[i])
let team = await teamQuery(context.authorization, clones[i].teamId)
clones[i] = await cloneDetails(context.userId, team.data.data.teams_TeamById, clones[i])
clones[i].botType = clones[i].kind // Only for listing we show the teams value
}
return clones
} catch (err){
logger.error('Retrieving History Clones error: %s', err.stack)
throw new OperationsError('There has been an error retrieving history clones.')
}
}
const query = {
+3 -7
View File
@@ -12,7 +12,6 @@ import { Clone } from '../../models'
import logger from '../../config/logger'
import getCloneStatus from '../../kubernetes/getClonePodStatus'
import getCloneLogs from '../../kubernetes/getClonePodLogs'
import teams_FbByTeamMember from '../../graphQLCalls/teams_FbByTeamMember'
import cloneDetails from '../cloneDetails'
const args = {}
@@ -27,14 +26,11 @@ const resolve = async(parent, args, context) => {
let clones = await Clone.find({
authId: context.userId,
active: true
})
// TODO Refactor this code once financial beings api is ready
// Authorization is handled by the teams module
let botsByUser = await teams_FbByTeamMember(context.authorization)
}).sort({createDatetime: -1})
for (var i = 0; i < clones.length; i++) {
clones[i] = await cloneDetails(context.authorization, botsByUser, clones[i])
let team = await teamQuery(context.authorization, clones[i].teamId)
clones[i] = await cloneDetails(context.userId, team.data.data.teams_TeamById, clones[i])
let state = await getCloneStatus(clones[i].cloneName)
clones[i].state = state.substring(1, state.length-1)
let lastLogs = await getCloneLogs(clones[i].cloneName)