- FIX: .gbapp files now correctly loaded before other package types so custom models can be used to sync DB.

- NEW: Removed Boot Package feature. Now every .gbot found on deploy folders are deployed on startup.
This commit is contained in:
Rodrigo Rodriguez 2018-05-06 19:25:47 -03:00
parent 3bb0b316a9
commit 51d244ce44
5 changed files with 125 additions and 104 deletions

View file

@ -70,10 +70,6 @@ export class GBConfigService {
value = undefined; value = undefined;
break; break;
case "BOOT_PACKAGE":
value = "none";
break;
case "DEFAULT_AI": case "DEFAULT_AI":
value = undefined; value = undefined;
break; break;
@ -81,6 +77,7 @@ export class GBConfigService {
case "DATABASE_SYNC": case "DATABASE_SYNC":
value = "false"; value = "false";
break; break;
default: default:
logger.trace( logger.trace(
`Guaribas General Error: Invalid key on .env file: '${key}'` `Guaribas General Error: Invalid key on .env file: '${key}'`

View file

@ -103,18 +103,9 @@ export class GBCoreService implements IGBCoreService {
acquire: 40000 acquire: 40000
} }
}); });
cb();
// TODO: Packages add model.
if (GBConfigService.get("DATABASE_SYNC") === "true") {
this.syncDatabaseStructure(cb);
} else {
cb();
}
} }
/** Calls ORM to sync storage. */
syncDatabaseStructure(cb) { syncDatabaseStructure(cb) {
logger.trace("Syncing database..."); logger.trace("Syncing database...");
this.sequelize.sync().then(value => { this.sequelize.sync().then(value => {

View file

@ -184,7 +184,7 @@ export class GBMinService {
// Prepares bot service. // Prepares bot service.
let inMemoryStorage = new MemoryBotStorage(); let inMemoryStorage = new MemoryBotStorage();
min.bot = new gBuilder.UniversalBot(connector, { min.bot = new gBuilder.UniversalBot(connector, {
storage: inMemoryStorage storage: inMemoryStorage
}); });
@ -199,22 +199,21 @@ export class GBMinService {
botbuilder: (session, next) => { botbuilder: (session, next) => {
if (!session.privateConversationData.loaded) { if (!session.privateConversationData.loaded) {
setTimeout( setTimeout(
() => { () => {
min.conversationalService.sendEvent( min.conversationalService.sendEvent(
session, session,
"loadInstance", "loadInstance",
min.instance // TODO: Send a new thiner object. min.instance // TODO: Send a new thiner object.
) )
}, },
500 500
); );
session.privateConversationData.loaded = true; session.privateConversationData.loaded = true;
session.userData.subjects = []; session.userData.subjects = [];
} }
appPackages.forEach(e => { appPackages.forEach(e => {
e.onNewSession(min, session) e.onNewSession(min, session)
}); });
@ -278,7 +277,7 @@ export class GBMinService {
generalPackages.forEach(e => { generalPackages.forEach(e => {
logger.trace(`Loading package: ${e.name}...`); logger.trace(`Loading package: ${e.name}...`);
let p = Object.create(e.prototype) as IGBPackage; let p = Object.create(e.prototype) as IGBPackage;
p.loadBot(min) p.loadBot(min);
}); });
// Specialized load for each min instance. // Specialized load for each min instance.
@ -301,6 +300,7 @@ export class GBMinService {
paths = paths.concat(additionalPath.toLowerCase().split(";")); paths = paths.concat(additionalPath.toLowerCase().split(";"));
} }
let botPackages = new Array<string>(); let botPackages = new Array<string>();
let gbappPackages = new Array<string>();
let generalPackages = new Array<string>(); let generalPackages = new Array<string>();
function doIt(path) { function doIt(path) {
@ -313,6 +313,9 @@ export class GBMinService {
if (element.endsWith('.gbot')) { if (element.endsWith('.gbot')) {
botPackages.push(element); botPackages.push(element);
} }
else if (element.endsWith('.gbapp')) {
gbappPackages.push(element);
}
else { else {
generalPackages.push(element); generalPackages.push(element);
} }
@ -326,89 +329,117 @@ export class GBMinService {
doIt(e); doIt(e);
}); });
/** Deploys all .gbot files first. */
botPackages.forEach(e => { /** Deploys all .gbapp files first. */
logger.trace(`Deploying bot: ${e}...`);
this.deployer.deployBot(e, (data, err) => { let appPackagesProcessed = 0;
botPackages.length++;
logger.trace(`Bot: ${e} deployed...`); gbappPackages.forEach(e => {
}); logger.trace(`Deploying app: ${e}...`);
// Skips .gbapp inside deploy folder.
if (!e.startsWith('deploy')) {
import(e).then(m => {
let p = new m.Package();
p.loadPackage(core, core.sequelize);
appPackages.push(p);
logger.trace(`App (.gbapp) deployed: ${e}.`);
appPackagesProcessed++;
}).catch(err => {
logger.trace(`Error deploying App (.gbapp): ${e}: ${err}`);
appPackagesProcessed++;
});
} else {
appPackagesProcessed++;
}
}); });
/** Then all remaining generalPackages are loaded. */
generalPackages.forEach(filename => {
let filenameOnly = Path.basename(filename);
logger.trace(`Deploying package: ${filename}...`);
/** Handles apps for general bots - .gbapp must stay out of deploy folder. */
if (Path.extname(filename) === ".gbapp" || Path.extname(filename) === ".gblib") {
// Skips .gbapp inside deploy folder.
if (!filename.startsWith('deploy')) {
import(filename).then(m => {
let p = new m.Package();
p.loadPackage(core);
appPackages.push(p);
logger.trace(`App (.gbapp) deployed: ${filenameOnly}.`);
});
}
/** Themes for bots. */
} else if (Path.extname(filename) === ".gbtheme") {
server.use("/themes/" + filenameOnly, express.static(filename));
logger.trace(`Theme (.gbtheme) assets acessible at: ${"/themes/" + filenameOnly}.`);
/** Knowledge base for bots. */
} else if (Path.extname(filename) === ".gbkb") {
server.use(
"/kb/" + filenameOnly + "/subjects",
express.static(UrlJoin(filename, "subjects"))
);
logger.trace(`KB (.gbkb) assets acessible at: ${"/kb/" + filenameOnly}.`);
}
else if (Path.extname(filename) === ".gbui" || filename.endsWith(".git")) {
// Already Handled
}
/** Unknown package format. */
else {
let err = new Error(`Package type not handled: ${filename}.`);
reject(err);
}
totalPackages++;
});
WaitUntil() WaitUntil()
.interval(1000) .interval(1000)
.times(5) .times(5)
.condition(function (cb) { .condition(function (cb) {
logger.trace(`Waiting for package deployment...`); logger.trace(`Waiting for app package deployment...`);
cb(totalPackages == (generalPackages.length + botPackages.length)); cb(appPackagesProcessed == gbappPackages.length);
}) })
.done(function (result) { .done(function (result) {
if (botPackages.length === 0){ logger.trace(`App Package deployment done.`);
logger.info(`The bot server is running empty: No bot instances have been found, at least one .gbot file must be deployed.`);
}
else{
logger.trace(`Package deployment done.`);
}
resolve();
});
core.syncDatabaseStructure(cb => {
/** Deploys all .gbot files first. */
botPackages.forEach(e => {
logger.trace(`Deploying bot: ${e}...`);
_this.deployer.deployBot(e, (data, err) => {
logger.trace(`Bot: ${e} deployed...`);
});
});
// TODO: Wait here.
/** Then all remaining generalPackages are loaded. */
generalPackages.forEach(filename => {
let filenameOnly = Path.basename(filename);
logger.trace(`Deploying package: ${filename}...`);
/** Handles apps for general bots - .gbapp must stay out of deploy folder. */
if (Path.extname(filename) === ".gbapp" || Path.extname(filename) === ".gblib") {
/** Themes for bots. */
} else if (Path.extname(filename) === ".gbtheme") {
server.use("/themes/" + filenameOnly, express.static(filename));
logger.trace(`Theme (.gbtheme) assets acessible at: ${"/themes/" + filenameOnly}.`);
/** Knowledge base for bots. */
} else if (Path.extname(filename) === ".gbkb") {
server.use(
"/kb/" + filenameOnly + "/subjects",
express.static(UrlJoin(filename, "subjects"))
);
logger.trace(`KB (.gbkb) assets acessible at: ${"/kb/" + filenameOnly}.`);
}
else if (Path.extname(filename) === ".gbui" || filename.endsWith(".git")) {
// Already Handled
}
/** Unknown package format. */
else {
let err = new Error(`Package type not handled: ${filename}.`);
reject(err);
}
totalPackages++;
});
WaitUntil()
.interval(1000)
.times(5)
.condition(function (cb) {
logger.trace(`Waiting for package deployment...`);
cb(totalPackages == (generalPackages.length));
})
.done(function (result) {
if (botPackages.length === 0) {
logger.info(`The bot server is running empty: No bot instances have been found, at least one .gbot file must be deployed.`);
}
else {
logger.trace(`Package deployment done.`);
}
resolve();
});
});
});
} catch (err) { } catch (err) {
reject(err) reject(err)
} }
}); });
} }
}
}

View file

@ -67,15 +67,14 @@ export class GBServer {
// the Marketplace until GB get serverless. // the Marketplace until GB get serverless.
let port = process.env.port || process.env.PORT || 4242; let port = process.env.port || process.env.PORT || 4242;
logger.info(`Starting GeneralBots HTTP server...`); logger.info(`Starting HTTP BotServer...`);
let server = express(); let server = express();
server.listen(port, () => { server.listen(port, () => {
logger.info(`General Bots Server - RUNNING on ${port}...`); logger.info(`General Bot - RUNNING on ${port}...`);
logger.info(`Starting instances...`); logger.info(`Starting instances...`);
// Reads basic configuration, initialize minimal services. // Reads basic configuration, initialize minimal services.
GBConfigService.init(); GBConfigService.init();
@ -93,7 +92,8 @@ export class GBServer {
let sysPackages = new Array<IGBPackage>(); let sysPackages = new Array<IGBPackage>();
[GBAdminPackage, GBAnalyticsPackage, GBCorePackage, GBSecurityPackage, GBKBPackage, GBCustomerSatisfactionPackage].forEach(e => { [GBAdminPackage, GBAnalyticsPackage, GBCorePackage, GBSecurityPackage,
GBKBPackage, GBCustomerSatisfactionPackage].forEach(e => {
logger.trace(`Loading sys package: ${e.name}...`); logger.trace(`Loading sys package: ${e.name}...`);
let p = Object.create(e.prototype) as IGBPackage; let p = Object.create(e.prototype) as IGBPackage;
p.loadPackage(core, core.sequelize); p.loadPackage(core, core.sequelize);
@ -104,9 +104,11 @@ export class GBServer {
try { try {
let appPackages = new Array<IGBPackage>(); let appPackages = new Array<IGBPackage>();
await minService.deployPackages(core, server, appPackages, sysPackages); await minService.deployPackages(core, server, appPackages, sysPackages);
minService.buildMin(instance => {
logger.info(`Instance loaded: ${instance.botId}...`); minService.buildMin(instance => {
}, server, appPackages); logger.info(`Instance loaded: ${instance.botId}...`);
}, server, appPackages);
} catch (err) { } catch (err) {
logger.log(err) logger.log(err)

View file

@ -60,7 +60,7 @@ var logger = new (winston.Logger)({
}); });
logger.add(winston.transports.Console, { logger.add(winston.transports.Console, {
label: 'General Bots Server', label: 'General Bot Server',
level: 'info', level: 'info',
prettyPrint: true, prettyPrint: true,
colorize: true, colorize: true,
@ -69,7 +69,7 @@ logger.add(winston.transports.Console, {
}); });
logger.add(winston.transports.File, { logger.add(winston.transports.File, {
label: 'General Bots Server', label: 'General Bot Server',
prettyPrint: true, prettyPrint: true,
level: 'info', level: 'info',
silent: false, silent: false,