e-ucm/rage-analytics-backend

View on GitHub
bin/upgrade/controllers/abstract-controller.js

Summary

Maintainability
A
2 hrs
Test Coverage
/*
 * Copyright 2016 e-UCM (http://www.e-ucm.es/)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * This project has received funding from the European Union’s Horizon
 * 2020 research and innovation programme under grant agreement No 644187.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0 (link is external)
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

var async = require('async');


function AbstractController(transformers) {
    this.appConfig = null;
    this.status = 1;
    this.nextTransformer = null;
    this.transformers = transformers;
    this.nextTransformer = null;
    this.existingModelVersion = 1;
}

AbstractController.prototype.connect = function (config, callback) {

    this.appConfig = config;
    var that = this;
    this.doConnect(config, function (err, result) {
        if (err) {
            that.status = 1;
            return callback(err, result);
        }
        callback(null, result);
    });
};

AbstractController.prototype.refresh = function (callback) {
    this.nextTransformer = null;
    this.getModelVersion(this.appConfig, function (err, modelVersion) {
        if (err) {
            console.log('Cannot retrieve the model version', err);
            return callback(err);
        }

        this.existingModelVersion = modelVersion;

        // STATUS == 0 -> OK no transition required
        //        == 1 -> PENDING, transform must be performed
        //        == 2 -> ERROR, an error has happened, no update
        this.status = 0;
        this.nextTransformer = null;

        if (this.existingModelVersion !== this.getTargetVersion(this.appConfig).toString()) {

            for (var i = 0; i < this.transformers.length; ++i) {
                var transformer = this.transformers[i];
                if (this.existingModelVersion === transformer.version.origin.toString()) {
                    this.nextTransformer = transformer;
                    break;
                }
            }

            if (!this.nextTransformer) {
                this.status = 2;
            } else {
                this.status = 1;
            }

            // TODO check if all the transformers required exist
            // and are implemented
        }

        if (!this.nextTransformer) {
            return callback(null, {
                status: this.status
            });
        }
        callback(null, {
            status: this.status,
            requirements: this.nextTransformer.requires,
            version: this.nextTransformer.version
        });

    }.bind(this));
};


AbstractController.prototype.transform = function (callback) {
    var that = this;
    async.waterfall([function (newCallback) {
            console.log('Starting executing transformer ' + JSON.stringify(that.nextTransformer.version, null, 4));
            newCallback(null, that.appConfig);
        },
            that.nextTransformer.backup.bind(that.nextTransformer),
            that.nextTransformer.upgrade.bind(that.nextTransformer),
            that.nextTransformer.check.bind(that.nextTransformer)],
        function (err, result) {
            if (err) {
                console.error('Check failed (upgrade error?)');
                console.error(err);
                console.log('Trying to restore...');
                return that.nextTransformer.restore(that.appConfig, function (restoreError, result) {
                    if (restoreError) {
                        console.error('Error on while restoring the database... sorry :)');
                        return callback(restoreError);
                    }

                    console.log('Restore OK.');
                    return callback(err);
                });
            }

            console.log('Cleaning...');
            that.nextTransformer.clean(that.appConfig, function (cleanError, result) {

                if (cleanError) {
                    console.error('Cleaned failed: database might contain unused information...');
                } else {
                    console.log('Clean OK.');
                }

                that.setModelVersion(that.nextTransformer.version.destination, that.appConfig, function (err, result) {
                    if (err) {
                        return callback(err, result);
                    }
                    console.log('Finished transform transformers phase!');
                    callback(null, result);
                });
            });
        });
};


AbstractController.prototype.doConnect = function (config, callback) {
    throw new Error('Connect not implemented');
};
AbstractController.prototype.getTargetVersion = function (config) {
    throw new Error('getTargetVersion not implemented');
};
AbstractController.prototype.getModelVersion = function (config, callback) {
    throw new Error('getModelVersion not implemented');
};
AbstractController.prototype.setModelVersion = function (version, config, callback) {
    throw new Error('setModelVersion not implemented');
};

module.exports = AbstractController;