<commit_before>var express = require('express');
var router = express.Router();
var async = require('async');
var dateFormat = require('dateformat');

/*
 * GET /mf/deployments/ms2/t2.1/cluster
 */
router.get('/:workflow/:task/:platform', function(req, res, next) {
    var client = req.app.get('elastic'),
      workflow = req.params.workflow.toLowerCase(),
      task = req.params.task.toLowerCase(),
      platform = req.params.platform.toLowerCase(),
      deployment = req.params.deployment, // we keep the original case
      mf_server = req.app.get('mf_server'),
      dreamcloud_pwm_idx = req.app.get('pwm_idx'),
      expand = req.query.expand,
      experiments = [],
      predicted_execution_time = 0,
      json = [];

    client.search({
        index: 'deployment_on_' + platform,
        type: workflow + '_' + task,
        searchType: 'count'
    }, function(error, response) {
        if (error) {
            res.status(500);
            return next(error);
        }

        if (response.hits !== undefined) {
            size = response.hits.total;
        }

        client.search({
            index: 'deployment_on_' + platform,
            type: workflow + '_' + task,
            size: size,
        }, function(error, response) {
            if (error) {
                res.status(500);
                return next(error);
            }
            if (response.hits !== undefined) {
                var results = response.hits.hits;
                async.each(results, function(deployment, outer_callback) {
                    deployment = deployment._id;

                    /* (1) get deployment plan for the given hashvalue */
                    client.get({
                        index: 'deployment_on_' + platform,
                        type: workflow + '_' + task,
                        id: deployment
                    }, function(error, response) {
                        if (error) {
                            return next(error);
                        }
                        /* parse all experiments that use this deployment plan */
                        if (response.found) {
                            var source = response._source;
                            experiments = source.experiments;
                            predicted_execution_time = source.estimatedTime;
                        } else {
                            var message = {};
                            message.error = "Could not find deployment plan in the database";
                            res.json(message);
                            return;
                        }

                        var index = workflow + '_' + task;
                        async.forEachOf(experiments, function(value, experiment, callback) {
                            /* get start of experiment */
                            client.search({
                                index: index,
                                type: experiment,
                                size: 1,
                                sort: ['@timestamp:asc']
                            }, function(error, response) {
                                var data = {};
                                if (error) {
                                    callback(null);
                                    return;
                                }
                                var start, end;
                                if (response.hits !== undefined) {
                                    var only_results = response.hits.hits;
                                    var keys = Object.keys(only_results);
                                    keys.forEach(function(key) {
                                        var metric_data = only_results[key]._source;
                                        start = metric_data['@timestamp'];
                                        start = start.replace(/\s/g, '0');
                                    });
                                }

                                /* get end of experiment */
                                client.search({
                                    index: index,
                                    type: experiment,
                                    size: 1,
                                    sort: ['@timestamp:desc']
                                }, function(error, response) {
                                    if (error) {
                                        callback(null);
                                        return;
                                    }
                                    if (response.hits !== undefined) {
                                        var only_results = response.hits.hits;
                                        var keys = Object.keys(only_results);
                                        keys.forEach(function(key) {
                                            var metric_data = only_results[key]._source;
                                            end = metric_data['@timestamp'];
                                            end = end.replace(/\s/g, '0');
                                        });
                                    }

                                    if (!is_defined(start) || !is_defined(end)) {
                                        callback(null);
                                        return;
                                    }

                                    /* add runtime statistics to response object */
                                    data.experiment_id = experiment;
                                    data.workflow_id = workflow;
                                    data.task_id = task;
                                    data.deployment_id = deployment;
                                    data.runtime = {};
                                    data.runtime.start_time = start;
                                    data.runtime.end_time = end;
                                    data.runtime.actual_time = (new Date(end) - new Date(start)) / 1000;
                                    data.runtime.predicted_time = predicted_execution_time;
                                    if (!data.runtime.actual_time) {
                                        data.runtime.actual_time = 0;
                                    }

                                    /* get energy measurments */
                                    var body = compute_average_on("NODE01", "NODE02", "NODE03", start, end);
                                    client.search({
                                        index: dreamcloud_pwm_idx,
                                        searchType: 'count',
                                        body: body
                                    }, function(error, response) {
                                        if (error) {
                                            callback(null);
                                            return;
                                        }
                                        var answer = {},
                                            aggs = response.aggregations;

                                        data.energy = {};
                                        var power_data = {};
                                        var average = aggs.power_metrics.NODE01.value;
                                        data.energy.NODE01 = {};
                                        data.energy.NODE01.avg_watt_consumption = average;
                                        var duration = (new Date(end) - new Date(start)) / 1000;
                                        var joule = average * duration;
                                        data.energy.NODE01.total_energy_consumption = joule;

                                        average = aggs.power_metrics.NODE02.value;
                                        data.energy.NODE02 = {};
                                        data.energy.NODE02.avg_watt_consumption = average;
                                        joule = average * duration;
                                        data.energy.NODE02.total_energy_consumption = joule;

                                        average = aggs.power_metrics.NODE03.value;
                                        data.energy.NODE03 = {};
                                        data.energy.NODE03.avg_watt_consumption = average;
                                        joule = average * duration;
                                        data.energy.NODE03.total_energy_consumption = joule;

                                        /* no energy measurements available */
                                        if (!is_defined(average) || average === null) {
                                            data.energy = [];
                                        }

                                        /* retrieve all metric counters as a set */
                                        var index = workflow + '_' + task;
                                        var metric_keys = {};
                                        data.metrics = {};
                                        client.search({
                                            index: index,
                                            type: experiment,
                                            size: 20 /* should be enough results to capture all metrics */
                                        }, function(error, response) {
                                            if (error) {
                                                callback(null);
                                                return;
                                            }
                                            if (response.hits !== undefined) {
                                                var results = response.hits.hits,
                                                  keys = Object.keys(results),
                                                  items = {};
                                                /* filter keys like @timestamp, host, task, and type */
                                                keys.forEach(function(key) {
                                                    items = results[key]._source;
                                                    if (items.type == 'progress') {
                                                        return;
                                                    }
                                                    delete items['@timestamp'];
                                                    delete items.host;
                                                    delete items.task;
                                                    delete items.type;
                                                    for (var item in items) {
                                                        metric_keys[item] = item;
                                                    }
                                                });

                                                /* compute statistics for each identified metric */
                                                async.each(metric_keys, function(metric, inner_callback) {
                                                    client.search({
                                                        index: index,
                                                        type: experiment,
                                                        searchType: 'count',
                                                        body: aggregation_by(metric)
                                                    }, function(error, response) {
                                                        if (error) {
                                                            inner_callback(null);
                                                        }
                                                        var aggs = response.aggregations;
                                                        data.metrics[metric] = aggs[metric + '_Stats'];
                                                        inner_callback(null);
                                                    });
                                                }, function(error) {
                                                    json.push(data);
                                                    /* finished */
                                                    callback(null);
                                                });
                                            }
                                        });
                                    });
                                });
                            });
                        }, function(error) {
                            if (error) {
                                return next(error);
                            }

                            //json.push(plan);
                            outer_callback(null);
                        });
                    });
                }, function(error) {
                    res.json(json);
                });
            } else {
                var message = {};
                message = 'No deployment plans available';
                res.json(message);
            }
        });
    });
});

/*
 * GET /mf/deployments/ms2/t2.1/cluster/asij122109klad
 */
router.get('/:workflow/:task/:platform/:deployment', function(req, res, next) {
    var client = req.app.get('elastic'),
      workflow = req.params.workflow.toLowerCase(),
      task = req.params.task.toLowerCase(),
      platform = req.params.platform.toLowerCase(),
      deployment = req.params.deployment, // we keep the original case
      mf_server = req.app.get('mf_server'),
      dreamcloud_pwm_idx = req.app.get('pwm_idx'),
      expand = req.query.expand,
      experiments = [],
      predicted_execution_time = 0,
      json = [];

    /* (1) get deployment plan for the given hashvalue */
    client.get({
        index: 'deployment_on_' + platform,
        type: workflow + '_' + task,
        id: deployment
    }, function(error, response) {
        if (error) {
            return next(error);
        }
        /* parse all experiments that use this deployment plan */
        if (response.found) {
            var source = response._source;
            experiments = source.experiments;
            predicted_execution_time = source.estimatedTime;
        } else {
            var message = {};
            message.error = "Could not find deployment plan in the database";
            res.json(message);
            return;
        }

        var index = workflow + '_' + task;
        async.forEachOf(experiments, function(value, experiment, callback) {
            /* get start of experiment */
            client.search({
                index: index,
                type: experiment,
                size: 1,
                sort: ['@timestamp:asc']
            }, function(error, response) {
                if (error) {
                    callback(null);
                    return;
                }
                var start, end;
                if (response.hits !== undefined) {
                    var only_results = response.hits.hits;
                    var keys = Object.keys(only_results);
                    keys.forEach(function(key) {
                        var metric_data = only_results[key]._source;
                        start = metric_data['@timestamp'];
                        start = start.replace(/\s/g, '0');
                    });
                }

                /* get end of experiment */
                client.search({
                    index: index,
                    type: experiment,
                    size: 1,
                    sort: ['@timestamp:desc']
                }, function(error, response) {
                    if (error) {
                        callback(null);
                        return;
                    }
                    if (response.hits !== undefined) {
                        var only_results = response.hits.hits;
                        var keys = Object.keys(only_results);
                        keys.forEach(function(key) {
                            var metric_data = only_results[key]._source;
                            end = metric_data['@timestamp'];
                            end = end.replace(/\s/g, '0');
                        });
                    }

                    var data = {};
                    data.experiment_id = experiment;
                    data.workflow_id = workflow;
                    data.task_id = task;
                    data.deployment_id = deployment;

                    if (!is_defined(start) || !is_defined(end)) {
                        json.push(data);
                        callback(null);
                        return;
                    }

                    /* add runtime statistics to response object */
                    data.runtime = {};
                    data.runtime.start_time = start;
                    data.runtime.end_time = end;
                    data.runtime.actual_time = (new Date(end) - new Date(start)) / 1000;
                    data.runtime.predicted_time = predicted_execution_time;
                    if (!data.runtime.actual_time) {
                        data.runtime.actual_time = 0;
                    }

                    /* get energy measurments */
                    var body = compute_average_on("NODE01", "NODE02", "NODE03", start, end);
                    client.search({
                        index: dreamcloud_pwm_idx,
                        searchType: 'count',
                        body: body
                    }, function(error, response) {
                        if (error) {
                            callback(null);
                            return;
                        }
                        var answer = {},
                            aggs = response.aggregations;

                        data.energy = {};
                        var power_data = {};
                        var average = aggs.power_metrics.NODE01.value;
                        data.energy.NODE01 = {};
                        data.energy.NODE01.avg_watt_consumption = average;
                        var duration = (new Date(end) - new Date(start)) / 1000;
                        var joule = average * duration;
                        data.energy.NODE01.total_energy_consumption = joule;

                        average = aggs.power_metrics.NODE02.value;
                        data.energy.NODE02 = {};
                        data.energy.NODE02.avg_watt_consumption = average;
                        joule = average * duration;
                        data.energy.NODE02.total_energy_consumption = joule;

                        average = aggs.power_metrics.NODE03.value;
                        data.energy.NODE03 = {};
                        data.energy.NODE03.avg_watt_consumption = average;
                        joule = average * duration;
                        data.energy.NODE03.total_energy_consumption = joule;

                        /* no energy measurements available */
                        if (!is_defined(average) || average === null) {
                            data.energy = [];
                        }

                        /* retrieve all metric counters as a set */
                        var index = workflow + '_' + task;
                        var metric_keys = {};
                        data.metrics = {};
                        client.search({
                            index: index,
                            type: experiment,
                            size: 20 /* should be enough results to capture all metrics */
                        }, function(error, response) {
                            if (error) {
                                callback(null);
                                return;
                            }
                            if (response.hits !== undefined) {
                                var results = response.hits.hits,
                                  keys = Object.keys(results),
                                  items = {};
                                /* filter keys like @timestamp, host, task, and type */
                                keys.forEach(function(key) {
                                    items = results[key]._source;
                                    if (items.type == 'progress') {
                                        return;
                                    }
                                    delete items['@timestamp'];
                                    delete items.host;
                                    delete items.task;
                                    delete items.type;
                                    for (var item in items) {
                                        metric_keys[item] = item;
                                    }
                                });

                                /* compute statistics for each identified metric */
                                async.each(metric_keys, function(metric, inner_callback) {
                                    client.search({
                                        index: index,
                                        type: experiment,
                                        searchType: 'count',
                                        body: aggregation_by(metric)
                                    }, function(error, response) {
                                        if (error) {
                                            inner_callback(null);
                                        }
                                        var aggs = response.aggregations;
                                        data.metrics[metric] = aggs[metric + '_Stats'];
                                        inner_callback(null);
                                    });
                                }, function(error) {
                                    json.push(data);
                                    /* finished */
                                    callback(null);
                                });
                            }
                        });
                    });
                });
            });
        }, function(error) {
            if (error) {
                return next(error);
            }

            res.json(json);
        });
    });
});

function is_defined(variable) {
    return (typeof variable !== 'undefined');
}

function compute_average_on(metric_name_a, metric_name_b, metric_name_c, from, to) {
    var query = {
        "aggs": {
            "power_metrics": {
                "filter": {
                    "and": [{
                        "or": [{
                            "exists": {
                                "field": metric_name_a
                            }
                        }, {
                            "exists": {
                                "field": metric_name_b
                            }
                        }, {
                            "exists": {
                                "field": metric_name_c
                            }
                        }]
                    }, {
                        "range": {
                            "@timestamp": {
                                "gte": from.toString(),
                                "lte": to.toString()
                            }
                        }
                    }]
                },
                "aggs": {
                    "NODE01": {
                        "avg": {
                            "field": metric_name_a
                        }
                    },
                    "NODE02": {
                        "avg": {
                            "field": metric_name_b
                        }
                    },
                    "NODE03": {
                        "avg": {
                            "field": metric_name_c
                        }
                    }
                }
            }
        }
    };
    return query;
}

function aggregation_by(field_name) {
    return '{' +
        '"aggs": {' +
            '"' + field_name + '_Stats" : {' +
                '"stats" : {' +
                    '"field" : "' + field_name + '"' +
                '}' +
            '},' +
            '"Minimum_' + field_name + '": {' +
                '"top_hits": {' +
                    '"size": 1,' +
                    '"sort": [' +
                        '{' +
                            '"' + field_name + '": {' +
                                '"order": "asc"' +
                            '}' +
                        '}' +
                    ']' +
                '}' +
            '},' +
            '"Maximum_' + field_name + '": {' +
                '"top_hits": {' +
                    '"size": 1,' +
                    '"sort": [' +
                        '{' +
                            '"' + field_name + '": {' +
                                '"order": "desc"' +
                            '}' +
                        '}' +
                    ']' +
                '}' +
            '}' +
        '}' +
    '}';
}

module.exports = router;
<commit_msg>fixed issue when no power metric data is available; summary report was not produced<commit_after>var express = require('express');
var router = express.Router();
var async = require('async');
var dateFormat = require('dateformat');

/*
 * GET /mf/deployments/ms2/t2.1/cluster
 */
router.get('/:workflow/:task/:platform', function(req, res, next) {
    var client = req.app.get('elastic'),
      workflow = req.params.workflow.toLowerCase(),
      task = req.params.task.toLowerCase(),
      platform = req.params.platform.toLowerCase(),
      deployment = req.params.deployment, // we keep the original case
      mf_server = req.app.get('mf_server'),
      dreamcloud_pwm_idx = req.app.get('pwm_idx'),
      expand = req.query.expand,
      experiments = [],
      predicted_execution_time = 0,
      json = [];

    client.search({
        index: 'deployment_on_' + platform,
        type: workflow + '_' + task,
        searchType: 'count'
    }, function(error, response) {
        if (error) {
            res.status(500);
            return next(error);
        }

        if (response.hits !== undefined) {
            size = response.hits.total;
        }

        client.search({
            index: 'deployment_on_' + platform,
            type: workflow + '_' + task,
            size: size,
        }, function(error, response) {
            if (error) {
                res.status(500);
                return next(error);
            }
            if (response.hits !== undefined) {
                var results = response.hits.hits;
                async.each(results, function(deployment, outer_callback) {
                    deployment = deployment._id;

                    /* (1) get deployment plan for the given hashvalue */
                    client.get({
                        index: 'deployment_on_' + platform,
                        type: workflow + '_' + task,
                        id: deployment
                    }, function(error, response) {
                        if (error) {
                            return next(error);
                        }

                        /* parse all experiments that use this deployment plan */
                        if (response.found) {
                            var source = response._source;
                            experiments = source.experiments;
                            predicted_execution_time = source.estimatedTime;
                        } else {
                            var message = {};
                            message.error = "Could not find deployment plan in the database";
                            res.json(message);
                            return;
                        }

                        var index = workflow + '_' + task;
                        async.forEachOf(experiments, function(value, experiment, callback) {

                            /* get start of experiment */
                            client.search({
                                index: index,
                                type: experiment,
                                size: 1,
                                sort: ['@timestamp:asc']
                            }, function(error, response) {
                                var data = {};
                                if (error) {
                                    callback(null);
                                    return;
                                }
                                var start, end;
                                if (response.hits !== undefined) {
                                    var only_results = response.hits.hits;
                                    var keys = Object.keys(only_results);
                                    keys.forEach(function(key) {
                                        var metric_data = only_results[key]._source;
                                        start = metric_data['@timestamp'];
                                        start = start.replace(/\s/g, '0');
                                    });
                                }

                                /* get end of experiment */
                                client.search({
                                    index: index,
                                    type: experiment,
                                    size: 1,
                                    sort: ['@timestamp:desc']
                                }, function(error, response) {
                                    if (error) {
                                        callback(null);
                                        return;
                                    }
                                    if (response.hits !== undefined) {
                                        var only_results = response.hits.hits;
                                        var keys = Object.keys(only_results);
                                        keys.forEach(function(key) {
                                            var metric_data = only_results[key]._source;
                                            end = metric_data['@timestamp'];
                                            end = end.replace(/\s/g, '0');
                                        });
                                    }

                                    if (!is_defined(start) || !is_defined(end)) {
                                        callback(null);
                                        return;
                                    }

                                    /* add runtime statistics to response object */
                                    data.experiment_id = experiment;
                                    data.workflow_id = workflow;
                                    data.task_id = task;
                                    data.deployment_id = deployment;
                                    data.runtime = {};
                                    data.runtime.start_time = start;
                                    data.runtime.end_time = end;
                                    data.runtime.actual_time = (new Date(end) - new Date(start)) / 1000;
                                    data.runtime.predicted_time = predicted_execution_time;
                                    if (!data.runtime.actual_time) {
                                        data.runtime.actual_time = 0;
                                    }

                                    /* get energy measurments */
                                    var body = compute_average_on("NODE01", "NODE02", "NODE03", start, end);
                                    client.search({
                                        index: dreamcloud_pwm_idx,
                                        searchType: 'count',
                                        body: body
                                    }, function(error, response) {
                                        if (error) {
                                            // do nothing
                                        } else {
                                            var answer = {},
                                                aggs = response.aggregations;

                                            data.energy = {};
                                            var power_data = {};
                                            var average = aggs.power_metrics.NODE01.value;
                                            data.energy.NODE01 = {};
                                            data.energy.NODE01.avg_watt_consumption = average;
                                            var duration = (new Date(end) - new Date(start)) / 1000;
                                            var joule = average * duration;
                                            data.energy.NODE01.total_energy_consumption = joule;

                                            average = aggs.power_metrics.NODE02.value;
                                            data.energy.NODE02 = {};
                                            data.energy.NODE02.avg_watt_consumption = average;
                                            joule = average * duration;
                                            data.energy.NODE02.total_energy_consumption = joule;

                                            average = aggs.power_metrics.NODE03.value;
                                            data.energy.NODE03 = {};
                                            data.energy.NODE03.avg_watt_consumption = average;
                                            joule = average * duration;
                                            data.energy.NODE03.total_energy_consumption = joule;

                                            /* no energy measurements available */
                                            if (!is_defined(average) || average === null) {
                                                data.energy = [];
                                            }
                                        }

                                        /* retrieve all metric counters as a set */
                                        var index = workflow + '_' + task;
                                        var metric_keys = {};
                                        data.metrics = {};
                                        client.search({
                                            index: index,
                                            type: experiment,
                                            size: 20 /* should be enough results to capture all metrics */
                                        }, function(error, response) {
                                            if (error) {
                                                callback(null);
                                                return;
                                            }
                                            if (response.hits !== undefined) {
                                                var results = response.hits.hits,
                                                  keys = Object.keys(results),
                                                  items = {};
                                                /* filter keys like @timestamp, host, task, and type */
                                                keys.forEach(function(key) {
                                                    items = results[key]._source;
                                                    if (items.type == 'progress') {
                                                        return;
                                                    }
                                                    delete items['@timestamp'];
                                                    delete items.host;
                                                    delete items.task;
                                                    delete items.type;
                                                    delete items.platform;
                                                    for (var item in items) {
                                                        metric_keys[item] = item;
                                                    }
                                                });

                                                /* compute statistics for each identified metric */
                                                async.each(metric_keys, function(metric, inner_callback) {
                                                    client.search({
                                                        index: index,
                                                        type: experiment,
                                                        searchType: 'count',
                                                        body: aggregation_by(metric)
                                                    }, function(error, response) {
                                                        if (error) {
                                                            inner_callback(null);
                                                        }
                                                        var aggs = response.aggregations;
                                                        data.metrics[metric] = aggs[metric + '_Stats'];
                                                        inner_callback(null);
                                                    });
                                                }, function(error) {
                                                    json.push(data);
                                                    /* finished */
                                                    callback(null);
                                                });
                                            }
                                        });
                                    });
                                });
                            });
                        }, function(error) {
                            if (error) {
                                return next(error);
                            }

                            //json.push(plan);
                            outer_callback(null);
                        });
                    });
                }, function(error) {
                    res.json(json);
                });
            } else {
                var message = {};
                message = 'No deployment plans available';
                res.json(message);
            }
        });
    });
});

/*
 * GET /mf/deployments/ms2/t2.1/cluster/asij122109klad
 */
router.get('/:workflow/:task/:platform/:deployment', function(req, res, next) {
    var client = req.app.get('elastic'),
      workflow = req.params.workflow.toLowerCase(),
      task = req.params.task.toLowerCase(),
      platform = req.params.platform.toLowerCase(),
      deployment = req.params.deployment, // we keep the original case
      mf_server = req.app.get('mf_server'),
      dreamcloud_pwm_idx = req.app.get('pwm_idx'),
      expand = req.query.expand,
      experiments = [],
      predicted_execution_time = 0,
      json = [];

    /* (1) get deployment plan for the given hashvalue */
    client.get({
        index: 'deployment_on_' + platform,
        type: workflow + '_' + task,
        id: deployment
    }, function(error, response) {
        if (error) {
            return next(error);
        }
        /* parse all experiments that use this deployment plan */
        if (response.found) {
            var source = response._source;
            experiments = source.experiments;
            predicted_execution_time = source.estimatedTime;
        } else {
            var message = {};
            message.error = "Could not find deployment plan in the database";
            res.json(message);
            return;
        }

        var index = workflow + '_' + task;
        async.forEachOf(experiments, function(value, experiment, callback) {
            /* get start of experiment */
            client.search({
                index: index,
                type: experiment,
                size: 1,
                sort: ['@timestamp:asc']
            }, function(error, response) {
                if (error) {
                    callback(null);
                    return;
                }
                var start, end;
                if (response.hits !== undefined) {
                    var only_results = response.hits.hits;
                    var keys = Object.keys(only_results);
                    keys.forEach(function(key) {
                        var metric_data = only_results[key]._source;
                        start = metric_data['@timestamp'];
                        start = start.replace(/\s/g, '0');
                    });
                }

                /* get end of experiment */
                client.search({
                    index: index,
                    type: experiment,
                    size: 1,
                    sort: ['@timestamp:desc']
                }, function(error, response) {
                    if (error) {
                        callback(null);
                        return;
                    }
                    if (response.hits !== undefined) {
                        var only_results = response.hits.hits;
                        var keys = Object.keys(only_results);
                        keys.forEach(function(key) {
                            var metric_data = only_results[key]._source;
                            end = metric_data['@timestamp'];
                            end = end.replace(/\s/g, '0');
                        });
                    }

                    var data = {};
                    data.experiment_id = experiment;
                    data.workflow_id = workflow;
                    data.task_id = task;
                    data.deployment_id = deployment;

                    if (!is_defined(start) || !is_defined(end)) {
                        json.push(data);
                        callback(null);
                        return;
                    }

                    /* add runtime statistics to response object */
                    data.runtime = {};
                    data.runtime.start_time = start;
                    data.runtime.end_time = end;
                    data.runtime.actual_time = (new Date(end) - new Date(start)) / 1000;
                    data.runtime.predicted_time = predicted_execution_time;
                    if (!data.runtime.actual_time) {
                        data.runtime.actual_time = 0;
                    }

                    /* get energy measurments */
                    var body = compute_average_on("NODE01", "NODE02", "NODE03", start, end);
                    client.search({
                        index: dreamcloud_pwm_idx,
                        searchType: 'count',
                        body: body
                    }, function(error, response) {
                        if (error) {
                            callback(null);
                            return;
                        }
                        var answer = {},
                            aggs = response.aggregations;

                        data.energy = {};
                        var power_data = {};
                        var average = aggs.power_metrics.NODE01.value;
                        data.energy.NODE01 = {};
                        data.energy.NODE01.avg_watt_consumption = average;
                        var duration = (new Date(end) - new Date(start)) / 1000;
                        var joule = average * duration;
                        data.energy.NODE01.total_energy_consumption = joule;

                        average = aggs.power_metrics.NODE02.value;
                        data.energy.NODE02 = {};
                        data.energy.NODE02.avg_watt_consumption = average;
                        joule = average * duration;
                        data.energy.NODE02.total_energy_consumption = joule;

                        average = aggs.power_metrics.NODE03.value;
                        data.energy.NODE03 = {};
                        data.energy.NODE03.avg_watt_consumption = average;
                        joule = average * duration;
                        data.energy.NODE03.total_energy_consumption = joule;

                        /* no energy measurements available */
                        if (!is_defined(average) || average === null) {
                            data.energy = [];
                        }

                        /* retrieve all metric counters as a set */
                        var index = workflow + '_' + task;
                        var metric_keys = {};
                        data.metrics = {};
                        client.search({
                            index: index,
                            type: experiment,
                            size: 20 /* should be enough results to capture all metrics */
                        }, function(error, response) {
                            if (error) {
                                callback(null);
                                return;
                            }
                            if (response.hits !== undefined) {
                                var results = response.hits.hits,
                                  keys = Object.keys(results),
                                  items = {};
                                /* filter keys like @timestamp, host, task, and type */
                                keys.forEach(function(key) {
                                    items = results[key]._source;
                                    if (items.type == 'progress') {
                                        return;
                                    }
                                    delete items['@timestamp'];
                                    delete items.host;
                                    delete items.task;
                                    delete items.type;
                                    for (var item in items) {
                                        metric_keys[item] = item;
                                    }
                                });

                                /* compute statistics for each identified metric */
                                async.each(metric_keys, function(metric, inner_callback) {
                                    client.search({
                                        index: index,
                                        type: experiment,
                                        searchType: 'count',
                                        body: aggregation_by(metric)
                                    }, function(error, response) {
                                        if (error) {
                                            inner_callback(null);
                                        }
                                        var aggs = response.aggregations;
                                        data.metrics[metric] = aggs[metric + '_Stats'];
                                        inner_callback(null);
                                    });
                                }, function(error) {
                                    json.push(data);
                                    /* finished */
                                    callback(null);
                                });
                            }
                        });
                    });
                });
            });
        }, function(error) {
            if (error) {
                return next(error);
            }

            res.json(json);
        });
    });
});

function is_defined(variable) {
    return (typeof variable !== 'undefined');
}

function compute_average_on(metric_name_a, metric_name_b, metric_name_c, from, to) {
    var query = {
        "aggs": {
            "power_metrics": {
                "filter": {
                    "and": [{
                        "or": [{
                            "exists": {
                                "field": metric_name_a
                            }
                        }, {
                            "exists": {
                                "field": metric_name_b
                            }
                        }, {
                            "exists": {
                                "field": metric_name_c
                            }
                        }]
                    }, {
                        "range": {
                            "@timestamp": {
                                "gte": from.toString(),
                                "lte": to.toString()
                            }
                        }
                    }]
                },
                "aggs": {
                    "NODE01": {
                        "avg": {
                            "field": metric_name_a
                        }
                    },
                    "NODE02": {
                        "avg": {
                            "field": metric_name_b
                        }
                    },
                    "NODE03": {
                        "avg": {
                            "field": metric_name_c
                        }
                    }
                }
            }
        }
    };
    return query;
}

function aggregation_by(field_name) {
    return '{' +
        '"aggs": {' +
            '"' + field_name + '_Stats" : {' +
                '"stats" : {' +
                    '"field" : "' + field_name + '"' +
                '}' +
            '},' +
            '"Minimum_' + field_name + '": {' +
                '"top_hits": {' +
                    '"size": 1,' +
                    '"sort": [' +
                        '{' +
                            '"' + field_name + '": {' +
                                '"order": "asc"' +
                            '}' +
                        '}' +
                    ']' +
                '}' +
            '},' +
            '"Maximum_' + field_name + '": {' +
                '"top_hits": {' +
                    '"size": 1,' +
                    '"sort": [' +
                        '{' +
                            '"' + field_name + '": {' +
                                '"order": "desc"' +
                            '}' +
                        '}' +
                    ']' +
                '}' +
            '}' +
        '}' +
    '}';
}

module.exports = router;
<|endoftext|>


<commit_before>var SnapController = (function() {

  var local = {};

  function SnapController() {}

  SnapController.prototype.init = function() {
    local.eventListeners();
  }

  local.eventListeners = function() {
    $("#snapForm").on("submit", function(e) {

      // Prevents page reload
      e.preventDefault();
      var data = $(this).serializeArray();

      $.ajax({
        type: "POST",
        url: "/test",
        data: data
      }).done(function(res) {
        console.log("res: ", JSON.stringify(res));
      }).fail(function(e) {
        console.log("failure: ", JSON.stringify(e));
      });

    });
  }

  return SnapController;

})();<commit_msg>Attempting to call methods on Game<commit_after>var SnapController = (function() {

  var local = {};

  function SnapController() {}

  SnapController.prototype.init = function() {
    local.eventListeners();
  }

  local.eventListeners = function() {
    $("#snapForm").on("submit", function(e) {

      // Prevents page reload
      e.preventDefault();
      var data = $(this).serializeArray();
      Game.player.addWord(data[0].value);
      Game.sendWords();

    });
  }

  return SnapController;

})();<|endoftext|>


<commit_before>/*jslint browser: true, nomen: false, devel: true*/

/*
 Copyright (c) 2013 Georg Paul

 MIT License

 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to
 permit persons to whom the Software is furnished to do so, subject to
 the following conditions:

 The above copyright notice and this permission notice shall be
 included in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

function ElementQueries() {
	"use strict";

	var self = this;

	var megaponySelectorRegExp = new RegExp(/\.(megapony)\-(max|min)\-(width|height)\-(\d*)/);

	self.maxWSelector = '.megapony-max-width-';
	self.minWSelector = '.megapony-min-width-';
	self.maxHSelector = '.megapony-max-height-';
	self.minHSelector = '.megapony-min-height-';

	this.init = function () {
		self.parseStylesheets();
	};

	this.parseStylesheets = function () {
		var selectorTextString = '',
			megaponyStylesheets = self.getMegaponyStyleSheets(document.styleSheets),
			crossRules,
			crossRulesLength,
			rule = '';

		megaponyStylesheets.forEach(function (stylesheet) {
			crossRules = stylesheet.rules || stylesheet.cssRules;
			crossRulesLength = crossRules.length;

			for (var x = 0; x < crossRulesLength; x++) {
				rule = crossRules[x].selectorText;
				selectorTextString += rule + ';';
			}
			self.checkSelectorsForElementQuery(selectorTextString);
		});
	};

	this.getMegaponyStyleSheets = function (stylesheets) {
		var megaponyStylesheets = [],
			stylesheetsLength = stylesheets.length;

		for (var i = 0; i < stylesheetsLength; i++) {
			if (stylesheets[i].title === 'megapony') {
				megaponyStylesheets.push(stylesheets[i]);
			}
		}
		return megaponyStylesheets;
	};

	this.checkSelectorsForElementQuery = function (selectorTextString) {
		var elementsArray = selectorTextString.split(';'),
			selectorText = '';

		for (var i = 0; i < elementsArray.length; i++) {
			selectorText = (elementsArray[i] !== undefined) ? (elementsArray[i]) : '';

			if (megaponySelectorRegExp.test(selectorText)) {
				var values = {
						maxW: self.getLengthFromSelector(self.maxWSelector, selectorText),
						minW: self.getLengthFromSelector(self.minWSelector, selectorText),
						maxH: self.getLengthFromSelector(self.maxHSelector, selectorText),
						minH: self.getLengthFromSelector(self.minHSelector, selectorText)
					},
					targetSelectorArray = selectorText.split(','),
					targetSelectorArrayLength = targetSelectorArray.length,
					storedTargetSelector = '';

				if (targetSelectorArrayLength > 1) {
					// multiple expressions (.foo .bar, .foo2 .bar 2, .lorem-ipsum)
					for (var x = 0; x < targetSelectorArrayLength; x++) {
						if (storedTargetSelector !== self.getTargetSelector(targetSelectorArray[x])) {
							if (self.getTargetSelector(targetSelectorArray[x]) !== '') {
								self.applyElementQueries(document.querySelectorAll(self.getTargetSelector(targetSelectorArray[x])), values);
							}
						}
						storedTargetSelector = self.getTargetSelector(targetSelectorArray[x]);
					}
				} else {
					// single expression (.foo .bar)
					if (self.getTargetSelector(targetSelectorArray[0]) !== '') {
						self.applyElementQueries(document.querySelectorAll(self.getTargetSelector(targetSelectorArray[0])), values);
					}
				}
			}
		}
	};

	this.getTargetSelector = function (selectorText) {
		var selectorPosition = selectorText.match(megaponySelectorRegExp);

		selectorText = selectorText.replace(megaponySelectorRegExp, '');

		if (selectorText.indexOf(" ", selectorPosition.index) != -1) {
			return selectorText.substring(0, selectorText.indexOf(" ", selectorPosition.index));
		} else {
			return selectorText;
		}
	};

	this.getLengthFromSelector = function (selector, selectorText) {
		var indexOfText = selectorText.indexOf(selector),
			maxWidth = parseInt(selectorText.slice(indexOfText + selector.length, indexOfText + selector.length + 4), 10);

		return (maxWidth > 0) ? maxWidth : false;
	};

	this.applyElementQueries = function (elements, values) {
		var elementWidth,
			elementHeight,
			elementsLength = elements.length;

		if (elementsLength === 0) {
			return;
		}

		for (var i = 0; i < elementsLength; i++) {
			elementWidth = elements[i].offsetWidth;
			elementHeight = elements[i].offsetHeight;

			// max width
			if ((values.maxW > 0) && (elementWidth < values.maxW)) {
				elements[i].classList.add(self.maxWSelector.split('.')[1] + values.maxW);
			}
			// min width
			if ((values.minW > 0) && (elementWidth >= values.minW)) {
				elements[i].classList.add(self.minWSelector.split('.')[1] + values.minW);
			}
			// max height
			if ((values.maxH > 0) && (elementHeight < values.maxH)) {
				elements[i].classList.add(self.maxHSelector.split('.')[1] + values.maxH);
			}
			// min height
			if ((values.minH > 0) && (elementHeight > values.minH)) {
				elements[i].classList.add(self.minHSelector.split('.')[1] + values.minH);
			}
		}
	};

	this.hideLoadingView = function () {
		document.querySelector('html').classList.remove('megapony-loading');
	};
}<commit_msg>[TASK] Removes safety condition, getTargetSelector function has unit test coverage<commit_after>/*jslint browser: true, nomen: false, devel: true*/

/*
 Copyright (c) 2013 Georg Paul

 MIT License

 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to
 permit persons to whom the Software is furnished to do so, subject to
 the following conditions:

 The above copyright notice and this permission notice shall be
 included in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

function ElementQueries() {
	"use strict";

	var self = this;

	var megaponySelectorRegExp = new RegExp(/\.(megapony)\-(max|min)\-(width|height)\-(\d*)/);

	self.maxWSelector = '.megapony-max-width-';
	self.minWSelector = '.megapony-min-width-';
	self.maxHSelector = '.megapony-max-height-';
	self.minHSelector = '.megapony-min-height-';

	this.init = function () {
		self.parseStylesheets();
	};

	this.parseStylesheets = function () {
		var selectorTextString = '',
			megaponyStylesheets = self.getMegaponyStyleSheets(document.styleSheets),
			crossRules,
			crossRulesLength,
			rule = '';

		megaponyStylesheets.forEach(function (stylesheet) {
			crossRules = stylesheet.rules || stylesheet.cssRules;
			crossRulesLength = crossRules.length;

			for (var x = 0; x < crossRulesLength; x++) {
				rule = crossRules[x].selectorText;
				selectorTextString += rule + ';';
			}
			self.checkSelectorsForElementQuery(selectorTextString);
		});
	};

	this.getMegaponyStyleSheets = function (stylesheets) {
		var megaponyStylesheets = [],
			stylesheetsLength = stylesheets.length;

		for (var i = 0; i < stylesheetsLength; i++) {
			if (stylesheets[i].title === 'megapony') {
				megaponyStylesheets.push(stylesheets[i]);
			}
		}
		return megaponyStylesheets;
	};

	this.checkSelectorsForElementQuery = function (selectorTextString) {
		var elementsArray = selectorTextString.split(';'),
			selectorText = '';

		for (var i = 0; i < elementsArray.length; i++) {
			selectorText = (elementsArray[i] !== undefined) ? (elementsArray[i]) : '';

			if (megaponySelectorRegExp.test(selectorText)) {
				var values = {
						maxW: self.getLengthFromSelector(self.maxWSelector, selectorText),
						minW: self.getLengthFromSelector(self.minWSelector, selectorText),
						maxH: self.getLengthFromSelector(self.maxHSelector, selectorText),
						minH: self.getLengthFromSelector(self.minHSelector, selectorText)
					},
					targetSelectorArray = selectorText.split(','),
					targetSelectorArrayLength = targetSelectorArray.length,
					storedTargetSelector = '';

				if (targetSelectorArrayLength > 1) {
					// multiple expressions (.foo .bar, .foo2 .bar 2, .lorem-ipsum)
					for (var x = 0; x < targetSelectorArrayLength; x++) {
						if (storedTargetSelector !== self.getTargetSelector(targetSelectorArray[x])) {
							self.applyElementQueries(document.querySelectorAll(self.getTargetSelector(targetSelectorArray[x])), values);
						}
						storedTargetSelector = self.getTargetSelector(targetSelectorArray[x]);
					}
				} else {
					// single expression (.foo .bar)
					self.applyElementQueries(document.querySelectorAll(self.getTargetSelector(targetSelectorArray[0])), values);
				}
			}
		}
	};

	this.getTargetSelector = function (selectorText) {
		var selectorPosition = selectorText.match(megaponySelectorRegExp);

		selectorText = selectorText.replace(megaponySelectorRegExp, '');

		if (selectorText.indexOf(" ", selectorPosition.index) != -1) {
			return selectorText.substring(0, selectorText.indexOf(" ", selectorPosition.index));
		} else {
			return selectorText;
		}
	};

	this.getLengthFromSelector = function (selector, selectorText) {
		var indexOfText = selectorText.indexOf(selector),
			maxWidth = parseInt(selectorText.slice(indexOfText + selector.length, indexOfText + selector.length + 4), 10);

		return (maxWidth > 0) ? maxWidth : false;
	};

	this.applyElementQueries = function (elements, values) {
		var elementWidth,
			elementHeight,
			elementsLength = elements.length;

		if (elementsLength === 0) {
			return;
		}

		for (var i = 0; i < elementsLength; i++) {
			elementWidth = elements[i].offsetWidth;
			elementHeight = elements[i].offsetHeight;

			// max width
			if ((values.maxW > 0) && (elementWidth < values.maxW)) {
				elements[i].classList.add(self.maxWSelector.split('.')[1] + values.maxW);
			}
			// min width
			if ((values.minW > 0) && (elementWidth >= values.minW)) {
				elements[i].classList.add(self.minWSelector.split('.')[1] + values.minW);
			}
			// max height
			if ((values.maxH > 0) && (elementHeight < values.maxH)) {
				elements[i].classList.add(self.maxHSelector.split('.')[1] + values.maxH);
			}
			// min height
			if ((values.minH > 0) && (elementHeight > values.minH)) {
				elements[i].classList.add(self.minHSelector.split('.')[1] + values.minH);
			}
		}
	};

	this.hideLoadingView = function () {
		document.querySelector('html').classList.remove('megapony-loading');
	};
}<|endoftext|>