Moved existing version of sample application to jenkins repo
diff --git a/auto-scale/README.md b/auto-scale/README.md
new file mode 100644
index 0000000..cb11620
--- /dev/null
+++ b/auto-scale/README.md
@@ -0,0 +1,84 @@
+# Autoscaling Application
+The auto-scaling app uses monitoring data to decide when to scale a service up/down.
+
+It is treated as an application rather than yet another
+service because it offers only a GUI front-end; it is not
+modelled as a service that other services can build upon.
+
+#How to
+
+Ensure that the CORD config is installed and then run:
+
+`python xos_auto_scaling_app.py`
+
+This command will start the autoscaling application and start REST server on 9991 port.
+
+## To verify the autoscaling application:
+1) Login to cloudlab compute nodes <br/>
+2) On each compute node, open /etc/ceilometer/pipeline.yaml file<br/>
+3) Change the polling interval for "cpu_source" meters from 600 to poll interval period that u wish (eg. 60) as shown below.<br/>
+From:
+```
+    - name: cpu_source
+      interval: 600
+      meters:
+          - "cpu"
+      sinks:
+          - cpu_sink
+```
+
+To:
+```
+    - name: cpu_source
+      interval: 60
+      meters:
+          - "cpu"
+      sinks:
+          - cpu_sink
+```
+3b) Also ensure the publisher in "cpu_sink" contains the following URL "udp://"IP of Ceilometer PUB-SUB":5004" as shown below.<br/>
+```
+    - name: cpu_sink
+      transformers:
+          - name: "rate_of_change"
+            parameters:
+                target:
+                    name: "cpu_util"
+                    unit: "%"
+                    type: "gauge"
+                    scale: "100.0 / (10**9 * (resource_metadata.cpu_number or 1))"
+      publishers:
+          - notifier://
+```
+
+To:
+```
+    - name: cpu_sink
+      transformers:
+          - name: "rate_of_change"
+            parameters:
+                target:
+                    name: "cpu_util"
+                    unit: "%"
+                    type: "gauge"
+                    scale: "100.0 / (10**9 * (resource_metadata.cpu_number or 1))"
+      publishers:
+          - notifier://
+          - udp://10.11.10.1:5004
+```
+4) sudo service ceilometer-agent-compute restart<br/>
+5) With this change, the autoscaling application should start receiving the CPU utilization samples every 60 seconds<br/>
+6) The REST API to retrieve the cpu utilization samples from autoscaling application: http://<app_ip>:9991/autoscaledata 
+
+## GUI (early development stage)
+
+To run this sample you need to have `nodejs >= 4.0` installed on your local system. You can get it [here](https://nodejs.org/en/)
+
+- Clone the repository locally
+- Open `xos-apps/auto-scale/gui/env/default` and change it to:
+```
+module.exports = {
+  host: 'http://<your.cord.installation.ip>:9991'
+}
+```
+- From `xos-apps/auto-scale/gui` run `npm start`
diff --git a/auto-scale/gui/.bowerrc b/auto-scale/gui/.bowerrc
new file mode 100644
index 0000000..e491038
--- /dev/null
+++ b/auto-scale/gui/.bowerrc
@@ -0,0 +1,3 @@
+{
+  "directory": "src/vendor/"
+}
\ No newline at end of file
diff --git a/auto-scale/gui/.editorconfig b/auto-scale/gui/.editorconfig
new file mode 100644
index 0000000..e717f5e
--- /dev/null
+++ b/auto-scale/gui/.editorconfig
@@ -0,0 +1,13 @@
+# http://editorconfig.org
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/auto-scale/gui/.eslintrc b/auto-scale/gui/.eslintrc
new file mode 100644
index 0000000..868fd4b
--- /dev/null
+++ b/auto-scale/gui/.eslintrc
@@ -0,0 +1,44 @@
+{
+    "ecmaFeatures": {
+        "blockBindings": true,
+        "forOf": true,
+        "destructuring": true,
+        "arrowFunctions": true,
+        "templateStrings": true
+    },
+    "env": { 
+        "browser": true,
+        "node": true,
+        "es6": true
+    },
+    "plugins": [
+        //"angular"
+    ],
+    "rules": {
+        "quotes": [2, "single"],
+        "camelcase": [0, {"properties": "always"}],
+        "no-underscore-dangle": 1,
+        "eqeqeq": [2, "smart"],
+        "no-alert": 1,
+        "key-spacing": [1, { "beforeColon": false, "afterColon": true }],
+        "indent": [2, 2],
+        "no-irregular-whitespace": 1,
+        "eol-last": 0,
+        "max-nested-callbacks": [2, 4],
+        "comma-spacing": [1, {"before": false, "after": true}],
+        "no-trailing-spaces": [1, { skipBlankLines: true }],
+        "no-unused-vars": [1, {"vars": "all", "args": "after-used"}],
+        "new-cap": 0,
+        "no-undef": 2,
+
+        //"angular/ng_module_name": [2, '/^xos\.*[a-z]*$/'],
+        //"angular/ng_controller_name": [2, '/^[a-z].*Ctrl$/'],
+        //"angular/ng_service_name": [2, '/^[A-Z].*Service$/'],
+        //"angular/ng_directive_name": [2, '/^[a-z]+[[A-Z].*]*$/'],
+        //"angular/ng_di": [0, "function or array"]
+    },
+    "globals" :{
+        "angular": true,
+        "Chart": true
+    } 
+}
\ No newline at end of file
diff --git a/auto-scale/gui/.gitignore b/auto-scale/gui/.gitignore
new file mode 100644
index 0000000..429d79a
--- /dev/null
+++ b/auto-scale/gui/.gitignore
@@ -0,0 +1,9 @@
+node_modules/
+bower_components/
+coverage/
+.sass-cache/
+.idea/
+.tmp/
+dist/
+src/vendor
+src/.tmp
diff --git a/auto-scale/gui/bower.json b/auto-scale/gui/bower.json
new file mode 100644
index 0000000..3286dd3
--- /dev/null
+++ b/auto-scale/gui/bower.json
@@ -0,0 +1,43 @@
+{
+  "name": "xos-ceilometerDashboard",
+  "version": "0.0.0",
+  "authors": [
+    "Matteo Scandolo <teo@onlab.us>"
+  ],
+  "description": "The ceilometerDashboard view",
+  "license": "MIT",
+  "ignore": [
+    "**/.*",
+    "node_modules",
+    "bower_components",
+    "static/js/vendor/",
+    "test",
+    "tests"
+  ],
+  "dependencies": {
+    "angular-chart.js": "~0.10.2",
+    "angular-animate": "~1.4.8",
+    "ui.bootstrap": "~0.14.3",
+    "jquery": "~2.2.3",
+    "angular": "~1.4.7",
+    "angular-ui-router": "~0.2.15",
+    "ng-lodash": "~0.3.0",
+    "bootstrap-css": "3.3.4"
+  },
+  "overrides": {
+    "ui.bootstrap": {
+      "main": [
+        "src/accordion/accordion.js",
+        "src/collapse/collapse.js"
+      ]
+    }
+  },
+  "devDependencies": {
+    "angular-mocks": "~1.4.8"
+  },
+  "resolutions": {
+    "jquery": "~2.1.4",
+    "angular-chart.js": "~0.8.7",
+    "Chart.js": "~1.0.1"
+  }
+}
diff --git a/auto-scale/gui/env/default.js b/auto-scale/gui/env/default.js
new file mode 100644
index 0000000..2153a31
--- /dev/null
+++ b/auto-scale/gui/env/default.js
@@ -0,0 +1,3 @@
+module.exports = {
+  host: 'http://130.127.133.58:9991/'
+}
diff --git a/auto-scale/gui/env/srikanth.js b/auto-scale/gui/env/srikanth.js
new file mode 100644
index 0000000..0489fb9
--- /dev/null
+++ b/auto-scale/gui/env/srikanth.js
@@ -0,0 +1,3 @@
+module.exports = {
+  host: 'http://128.104.222.16:9991'
+}
\ No newline at end of file
diff --git a/auto-scale/gui/gulp/build.js b/auto-scale/gui/gulp/build.js
new file mode 100644
index 0000000..9f9bfb8
--- /dev/null
+++ b/auto-scale/gui/gulp/build.js
@@ -0,0 +1,149 @@
+'use strict';
+
+// BUILD
+//
+// The only purpose of this gulpfile is to build a XOS view and copy the correct files into
+// .html => dashboards
+// .js (minified and concat) => static/js
+//
+// The template are parsed and added to js with angular $templateCache
+
+var gulp = require('gulp');
+var ngAnnotate = require('gulp-ng-annotate');
+var uglify = require('gulp-uglify');
+var templateCache = require('gulp-angular-templatecache');
+var runSequence = require('run-sequence');
+var concat = require('gulp-concat');
+var del = require('del');
+var wiredep = require('wiredep');
+var angularFilesort = require('gulp-angular-filesort');
+var _ = require('lodash');
+var eslint = require('gulp-eslint');
+var inject = require('gulp-inject');
+var rename = require('gulp-rename');
+var replace = require('gulp-replace');
+var postcss = require('gulp-postcss');
+var autoprefixer = require('autoprefixer');
+var mqpacker = require('css-mqpacker');
+var csswring = require('csswring');
+
+var TEMPLATE_FOOTER = `}]);
+angular.module('xos.ceilometerDashboard').run(function($location){$location.path('/')});
+angular.bootstrap(angular.element('#xosCeilometerDashboard'), ['xos.ceilometerDashboard']);`;
+
+module.exports = function(options){
+  
+  // delete previous builded file
+  gulp.task('clean', function(){
+    return del(
+      [options.dashboards + 'xosCeilometerDashboard.html'],
+      {force: true}
+    );
+  });
+
+  // minify css
+  gulp.task('css', function () {
+    var processors = [
+      autoprefixer({browsers: ['last 1 version']}),
+      mqpacker,
+      csswring
+    ];
+    
+    gulp.src([
+      `${options.css}**/*.css`,
+      `!${options.css}dev.css`
+    ])
+    .pipe(postcss(processors))
+    .pipe(gulp.dest(options.tmp + '/css/'));
+  });
+
+  gulp.task('copyCss', ['css'], function(){
+    return gulp.src([`${options.tmp}/css/*.css`])
+    .pipe(concat('xosCeilometerDashboard.css'))
+    .pipe(gulp.dest(options.static + 'css/'))
+  });
+
+  // compile and minify scripts
+  gulp.task('scripts', function() {
+    return gulp.src([
+      options.tmp + '**/*.js'
+    ])
+    .pipe(ngAnnotate())
+    .pipe(angularFilesort())
+    .pipe(concat('xosCeilometerDashboard.js'))
+    .pipe(uglify())
+    .pipe(gulp.dest(options.static + 'js/'));
+  });
+
+  // set templates in cache
+  gulp.task('templates', function(){
+    return gulp.src('./src/templates/*.html')
+      .pipe(templateCache({
+        module: 'xos.ceilometerDashboard',
+        root: 'templates/',
+        templateFooter: TEMPLATE_FOOTER
+      }))
+      .pipe(gulp.dest(options.tmp));
+  });
+
+  // copy html index to Django Folder
+  gulp.task('copyHtml', ['clean'], function(){
+    return gulp.src(options.src + 'index.html')
+      // remove dev dependencies from html
+      .pipe(replace(/<!-- bower:css -->(\n.*)*\n<!-- endbower --><!-- endcss -->/, ''))
+      .pipe(replace(/<!-- bower:js -->(\n.*)*\n<!-- endbower --><!-- endjs -->/, ''))
+      .pipe(replace(/ng-app=".*"\s/, ''))
+      //rewriting css path
+      // .pipe(replace(/(<link.*">)/, ''))
+      // injecting minified files
+      .pipe(
+        inject(
+          gulp.src([
+            options.static + 'js/vendor/xosCeilometerDashboardVendor.js',
+            options.static + 'js/xosCeilometerDashboard.js',
+            options.static + 'css/xosCeilometerDashboard.css'
+          ])
+        )
+      )
+      .pipe(rename('xosCeilometerDashboard.html'))
+      .pipe(gulp.dest(options.dashboards));
+  });
+
+  // minify vendor js files
+  gulp.task('wiredep', function(){
+    var bowerDeps = wiredep().js;
+    if(!bowerDeps){
+      return;
+    }
+
+    // remove angular (it's already loaded)
+    _.remove(bowerDeps, function(dep){
+      return dep.indexOf('angular/angular.js') !== -1;
+    });
+
+    return gulp.src(bowerDeps)
+      .pipe(concat('xosCeilometerDashboardVendor.js'))
+      .pipe(uglify())
+      .pipe(gulp.dest(options.static + 'js/vendor/'));
+  });
+
+  gulp.task('lint', function () {
+    return gulp.src(['src/js/**/*.js'])
+      .pipe(eslint())
+      .pipe(eslint.format())
+      .pipe(eslint.failAfterError());
+  });
+
+  gulp.task('build', function() {
+    runSequence(
+      'lint',
+      'templates',
+      'babel',
+      'scripts',
+      'wiredep',
+      'copyHtml',
+      'copyCss',
+      'cleanTmp'
+    );
+  });
+};
\ No newline at end of file
diff --git a/auto-scale/gui/gulp/server.js b/auto-scale/gui/gulp/server.js
new file mode 100644
index 0000000..0f69064
--- /dev/null
+++ b/auto-scale/gui/gulp/server.js
@@ -0,0 +1,149 @@
+'use strict';
+
+var gulp = require('gulp');
+var browserSync = require('browser-sync').create();
+var inject = require('gulp-inject');
+var runSequence = require('run-sequence');
+var angularFilesort = require('gulp-angular-filesort');
+var babel = require('gulp-babel');
+var wiredep = require('wiredep').stream;
+var del = require('del');
+var httpProxy = require('http-proxy');
+
+const environment = process.env.NODE_ENV;
+
+if (environment){
+  var conf = require(`../env/${environment}.js`);
+}
+else{
+  var conf = require('../env/default.js')
+}
+
+console.log(conf);
+
+var proxy = httpProxy.createProxyServer({
+  target: conf.host || 'http://0.0.0.0:9999'
+});
+
+proxy.on('error', function(error, req, res) {
+  res.writeHead(500, {
+    'Content-Type': 'text/plain'
+  });
+
+  console.error('[Proxy]', error);
+});
+
+module.exports = function(options){
+
+  // open in browser with sync and proxy to 0.0.0.0
+  gulp.task('browser', function() {
+    browserSync.init({
+      // reloadDelay: 500,
+      // logLevel: 'debug',
+      // logConnections: true,
+      // directory: true,
+      startPath: '#/',
+      snippetOptions: {
+        rule: {
+          match: /<!-- browserSync -->/i
+        }
+      },
+      server: {
+        baseDir: options.src,
+        middleware: function(req, res, next){
+          if(
+            req.url.indexOf('autoscaledata') !== -1
+          ){
+            proxy.web(req, res);
+          }
+          else{
+            next();
+          }
+        }
+      }
+    });
+
+    gulp.watch(options.src + 'js/**/*.js', ['js-watch']);
+    
+    gulp.watch(options.src + 'vendor/**/*.js', ['bower'], function(){
+      browserSync.reload();
+    });
+    gulp.watch(options.src + '**/*.html', function(){
+      browserSync.reload();
+    });
+    gulp.watch(options.src + '**/*.css', function(){
+      browserSync.reload();
+    });
+  });
+
+  // transpile js with sourceMaps
+  gulp.task('babel', function(){
+    return gulp.src([options.scripts + '**/*.js'])
+      .pipe(babel({sourceMaps: true}))
+      .pipe(gulp.dest(options.tmp));
+  });
+
+  // inject scripts
+  gulp.task('injectScript', function(){
+    runSequence(
+       'cleanTmp',
+       'babel',
+        function() {
+          return gulp.src(options.src + 'index.html')
+          .pipe(
+            inject(
+              gulp.src([
+                options.tmp + '**/*.js',
+                options.api + '*.js',
+                options.helpers + '**/*.js'
+              ])
+              // .pipe(debug({title: 'unicorn:'}))
+              .pipe(angularFilesort()),
+              {
+                ignorePath: [options.src, '/../../ngXosLib']
+              }
+            )
+          )
+          .pipe(gulp.dest(options.src));
+        }
+      );
+  });
+
+  // inject CSS
+  gulp.task('injectCss', function(){
+    return gulp.src(options.src + 'index.html')
+      .pipe(
+        inject(
+          gulp.src(options.src + 'css/*.css'),
+          {
+            ignorePath: [options.src]
+          }
+          )
+        )
+      .pipe(gulp.dest(options.src));
+  });
+
+  // inject bower dependencies with wiredep
+  gulp.task('bower', function () {
+    return gulp.src(options.src + 'index.html')
+    .pipe(wiredep({devDependencies: true}))
+    .pipe(gulp.dest(options.src));
+  });
+
+  gulp.task('js-watch', ['injectScript'], function(){
+    browserSync.reload();
+  });
+
+  gulp.task('cleanTmp', function(){
+    return del([options.tmp + '**/*']);
+  });
+
+  gulp.task('serve', function() {
+    runSequence(
+      'bower',
+      'injectScript',
+      'injectCss',
+      ['browser']
+    );
+  });
+};
diff --git a/auto-scale/gui/gulpfile.js b/auto-scale/gui/gulpfile.js
new file mode 100644
index 0000000..de911e9
--- /dev/null
+++ b/auto-scale/gui/gulpfile.js
@@ -0,0 +1,25 @@
+'use strict';
+
+var gulp = require('gulp');
+var wrench = require('wrench');
+
+var options = {
+  src: 'src/',
+  css: 'src/css/',
+  scripts: 'src/js/',
+  tmp: 'src/.tmp',
+  dist: 'dist/',
+  api: '../../ngXosLib/api/',
+  helpers: '../../ngXosLib/xosHelpers/src/',
+  static: '../../static/', // this is the django static folder
+  dashboards: '../../dashboards/' // this is the django html folder
+};
+
+wrench.readdirSyncRecursive('./gulp')
+.map(function(file) {
+  require('./gulp/' + file)(options);
+});
+
+gulp.task('default', function () {
+  gulp.start('build');
+});
diff --git a/auto-scale/gui/karma.conf.js b/auto-scale/gui/karma.conf.js
new file mode 100644
index 0000000..b67c208
--- /dev/null
+++ b/auto-scale/gui/karma.conf.js
@@ -0,0 +1,94 @@
+// Karma configuration
+// Generated on Tue Oct 06 2015 09:27:10 GMT+0000 (UTC)
+
+/* eslint indent: [2,2], quotes: [2, "single"]*/
+
+/*eslint-disable*/
+var wiredep = require('wiredep');
+var path = require('path');
+
+var bowerComponents = wiredep( {devDependencies: true} )[ 'js' ].map(function( file ){
+  return path.relative(process.cwd(), file);
+});
+/*eslint-enable*/
+module.exports = function(config) {
+  config.set({
+
+    // base path that will be used to resolve all patterns (eg. files, exclude)
+    basePath: '',
+
+
+    // frameworks to use
+    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
+    frameworks: ['jasmine'],
+
+
+    // list of files / patterns to load in the browser
+    files: bowerComponents.concat([
+      'src/css/**/*.css',
+      'src/js/main.js',
+      'src/js/**/*.js',
+      'spec/**/*.mock.js',
+      'spec/**/*.test.js',
+      'src/**/*.html'
+    ]),
+
+
+    // list of files to exclude
+    exclude: [
+    ],
+
+
+    // preprocess matching files before serving them to the browser
+    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
+    preprocessors: {
+      'src/js/**/*.js': ['babel'],
+      'spec/**/*.js': ['babel'],
+      'src/**/*.html': ['ng-html2js']
+    },
+
+    babelPreprocessor: {
+      options: {
+        presets: ['es2015'],
+        sourceMap: 'inline'
+      }
+    },
+
+    ngHtml2JsPreprocessor: {
+      stripPrefix: 'src/', //strip the src path from template url (http://stackoverflow.com/questions/22869668/karma-unexpected-request-when-testing-angular-directive-even-with-ng-html2js)
+      moduleName: 'templates' // define the template module name
+    },
+
+    // test results reporter to use
+    // possible values: 'dots', 'progress'
+    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
+    reporters: ['mocha'],
+
+
+    // web server port
+    port: 9876,
+
+
+    // enable / disable colors in the output (reporters and logs)
+    colors: true,
+
+
+    // level of logging
+    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
+    logLevel: config.LOG_INFO,
+
+
+    // enable / disable watching file and executing tests whenever any file changes
+    autoWatch: true,
+
+
+    // start these browsers
+    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
+    browsers: ['PhantomJS'],
+
+
+    // Continuous Integration mode
+    // if true, Karma captures browsers, runs the tests and exits
+    singleRun: false
+  });
+};
diff --git a/auto-scale/gui/package.json b/auto-scale/gui/package.json
new file mode 100644
index 0000000..0a9ccae
--- /dev/null
+++ b/auto-scale/gui/package.json
@@ -0,0 +1,62 @@
+{
+  "name": "xos-ceilometerDashboard",
+  "version": "1.0.0",
+  "description": "Angular Application for XOS, created with generator-xos",
+  "scripts": {
+    "prestart": "npm install && bower install",
+    "start": "gulp serve",
+    "prebuild": "npm install && bower install",
+    "build": "gulp",
+    "pretest": "npm install",
+    "test": "karma start",
+    "lint": "eslint src/js/"
+  },
+  "keywords": [
+    "XOS",
+    "Angular",
+    "XOSlib"
+  ],
+  "author": "Matteo Scandolo",
+  "license": "MIT",
+  "dependencies": {},
+  "devDependencies": {
+    "autoprefixer": "^6.1.2",
+    "babel": "^6.3.13",
+    "babel-preset-es2015": "^6.3.13",
+    "browser-sync": "^2.9.11",
+    "css-mqpacker": "^4.0.0",
+    "csswring": "^4.1.1",
+    "del": "^2.0.2",
+    "eslint": "^1.8.0",
+    "eslint-plugin-angular": "linkmesrl/eslint-plugin-angular",
+    "gulp": "^3.9.0",
+    "gulp-angular-filesort": "^1.1.1",
+    "gulp-angular-templatecache": "^1.8.0",
+    "gulp-babel": "^5.3.0",
+    "gulp-concat": "^2.6.0",
+    "gulp-debug": "^2.1.2",
+    "gulp-eslint": "^1.0.0",
+    "gulp-inject": "^3.0.0",
+    "gulp-minify-html": "^1.0.4",
+    "gulp-ng-annotate": "^1.1.0",
+    "gulp-postcss": "^6.0.1",
+    "gulp-rename": "^1.2.2",
+    "gulp-replace": "^0.5.4",
+    "gulp-uglify": "^1.4.2",
+    "http-proxy": "^1.12.0",
+    "jasmine-core": "^2.4.1",
+    "karma": "^0.13.15",
+    "karma-babel-preprocessor": "^6.0.1",
+    "karma-jasmine": "^0.3.6",
+    "karma-mocha-reporter": "^1.1.3",
+    "karma-ng-html2js-preprocessor": "^0.2.0",
+    "karma-phantomjs-launcher": "^0.2.1",
+    "lodash": "^3.10.1",
+    "mocha": "^2.3.4",
+    "phantomjs": "^1.9.19",
+    "proxy-middleware": "^0.15.0",
+    "run-sequence": "^1.1.4",
+    "wiredep": "^3.0.0-beta",
+    "wrench": "^1.5.8"
+  }
+}
diff --git a/auto-scale/gui/spec/.eslintrc b/auto-scale/gui/spec/.eslintrc
new file mode 100644
index 0000000..ad4bc2d
--- /dev/null
+++ b/auto-scale/gui/spec/.eslintrc
@@ -0,0 +1,9 @@
+{
+    "globals" :{
+        "describe": true,
+        "beforeEach": true,
+        "it": true,
+        "inject": true,
+        "expect": true
+    } 
+}
diff --git a/auto-scale/gui/spec/autoscaling.test.js b/auto-scale/gui/spec/autoscaling.test.js
new file mode 100644
index 0000000..54caf0e
--- /dev/null
+++ b/auto-scale/gui/spec/autoscaling.test.js
@@ -0,0 +1,48 @@
+'use strict';
+
+describe('In autoscaling app', () => {
+  var scope, element, vm, httpBackend, Service;
+
+
+
+  beforeEach(module('autoscaling'));
+  beforeEach(module('templates'));
+
+  beforeEach(inject(($httpBackend, $rootScope, Autoscaling) => {
+    httpBackend = $httpBackend;
+    scope = $rootScope.$new();
+    Service = Autoscaling;
+  }));
+
+  describe('the serviceContainer', () => {
+    beforeEach(inject(function($httpBackend, $compile){
+      
+      httpBackend.whenGET('/autoscaledata').respond(200, autoscalingMock);
+
+      element = angular.element('<service-container></service-container>');
+      $compile(element)(scope);
+
+      scope.$digest();
+      vm = element.isolateScope().vm;
+      httpBackend.flush();
+    }));
+
+    it('should correctly format data', () => {
+      expect(vm.services['service1']).toBeDefined();
+      expect(vm.services['service1']['slice1']).toBeDefined();
+      expect(vm.services['service1']['slice1']['instance1']).toBeDefined();
+
+      expect(vm.services['service1']['slice1']['instance1'][0].counter_volume).toBe(10);
+      expect(vm.services['service1']['slice1']['instance1'][1].counter_volume).toBe(11);
+
+      // triggering the function with 2 resources
+      vm.printData(Service.formatData(autoscalingMock2instances));
+
+      const keys = Object.keys(vm.services['service1']['slice1']);
+
+      expect(vm.services['service1']['slice1'][keys[0]][0].counter_volume).toBe(10);
+      expect(vm.services['service1']['slice1'][keys[0]][1].counter_volume).toBe(11);
+
+    });
+  });
+});
\ No newline at end of file
diff --git a/auto-scale/gui/spec/autoscaling_data.mock.js b/auto-scale/gui/spec/autoscaling_data.mock.js
new file mode 100644
index 0000000..e9f637a
--- /dev/null
+++ b/auto-scale/gui/spec/autoscaling_data.mock.js
@@ -0,0 +1,64 @@
+var autoscalingMock =[
+  {
+    'slice': 'slice1',
+    'service': 'service1',
+    'project_id': 'project1',
+    'resources': {
+      'resource1': {
+        'queue': [
+          {
+            'timestamp': '2015-12-17T22:55:36Z',
+            'counter_volume': 10,
+          },
+          {
+            'timestamp': '2015-12-17T22:55:46Z',
+            'counter_volume': 11,
+          }
+        ],
+        'xos_instance_info': {
+          'instance_name': 'instance1'
+        }
+      }
+    }
+  }
+];
+
+var autoscalingMock2instances =[
+  {
+    'slice': 'slice1',
+    'service': 'service1',
+    'project_id': 'project1',
+    'resources': {
+      'resource2': {
+        'queue': [
+          {
+            'timestamp': '2015-12-17T22:55:36Z',
+            'counter_volume': 20,
+          },
+          {
+            'timestamp': '2015-12-17T22:55:46Z',
+            'counter_volume': 21,
+          }
+        ],
+        'xos_instance_info': {
+          'instance_name': 'instance2'
+        }
+      },
+      'resource1': {
+        'queue': [
+          {
+            'timestamp': '2015-12-17T22:55:36Z',
+            'counter_volume': 10,
+          },
+          {
+            'timestamp': '2015-12-17T22:55:46Z',
+            'counter_volume': 11,
+          }
+        ],
+        'xos_instance_info': {
+          'instance_name': 'instance1'
+        }
+      },
+    }
+  }
+];
\ No newline at end of file
diff --git a/auto-scale/gui/src/css/style.css b/auto-scale/gui/src/css/style.css
new file mode 100644
index 0000000..260b6df
--- /dev/null
+++ b/auto-scale/gui/src/css/style.css
@@ -0,0 +1,134 @@
+body {
+  padding-top: 50px;
+}
+
+.list-group-item.active > a {
+  color: white;
+}
+
+/* ANIMATION */
+.animate-repeat{
+  /*background: red;*/
+}
+
+.animate-repeat.ng-move,
+.animate-repeat.ng-enter,
+.animate-repeat.ng-leave {
+  transition:all linear 0.5s;
+}
+
+/* Element Exit */
+.animate-repeat.ng-leave.ng-leave-active,
+.animate-repeat.ng-move,
+.animate-repeat.ng-enter {
+  /*opacity:0;*/
+  /*animation:1.5s bounceOutDown ease;*/
+}
+
+/* Element Enter */
+.animate-repeat.ng-leave,
+.animate-repeat.ng-move.ng-move-active,
+.animate-repeat.ng-enter.ng-enter-active {
+  /*opacity:1;*/
+  /*animation:1.5s bounceOutUp ease;*/
+}
+
+@keyframes bounceInUp {
+  from, 60%, 75%, 90%, to {
+    animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+  }
+
+  from {
+    opacity: 0;
+    transform: translate3d(0, 3000px, 0);
+  }
+
+  60% {
+    opacity: 1;
+    transform: translate3d(0, -20px, 0);
+  }
+
+  75% {
+    transform: translate3d(0, 10px, 0);
+  }
+
+  90% {
+    transform: translate3d(0, -5px, 0);
+  }
+
+  to {
+    transform: translate3d(0, 0, 0);
+  }
+}
+
+@keyframes bounceOutUp {
+  20% {
+    transform: translate3d(0, -10px, 0);
+  }
+
+  40%, 45% {
+    opacity: 1;
+    transform: translate3d(0, 20px, 0);
+  }
+
+  to {
+    opacity: 0;
+    transform: translate3d(0, -2000px, 0);
+  }
+}
+
+/* LOADER */
+.loader {
+  font-size: 10px;
+  margin: 150px auto;
+  text-indent: -9999em;
+  width: 11em;
+  height: 11em;
+  border-radius: 50%;
+  background: #ffffff;
+  background: -moz-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%);
+  background: -webkit-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%);
+  background: -o-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%);
+  background: -ms-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%);
+  background: linear-gradient(to right, #ffffff 10%, rgba(255, 255, 255, 0) 42%);
+  position: relative;
+  -webkit-animation: load3 1.4s infinite linear;
+  animation: load3 1.4s infinite linear;
+  -webkit-transform: translateZ(0);
+  -ms-transform: translateZ(0);
+  transform: translateZ(0);
+}
+.loader:before {
+  width: 50%;
+  height: 50%;
+  background: #105E9E;
+  border-radius: 100% 0 0 0;
+  position: absolute;
+  top: 0;
+  left: 0;
+  content: '';
+}
+.loader:after {
+  background: #fff;
+  width: 75%;
+  height: 75%;
+  border-radius: 50%;
+  content: '';
+  margin: auto;
+  position: absolute;
+  top: 0;
+  left: 0;
+  bottom: 0;
+  right: 0;
+}
+
+@keyframes load3 {
+  0% {
+    -webkit-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  100% {
+    -webkit-transform: rotate(360deg);
+    transform: rotate(360deg);
+  }
+}
\ No newline at end of file
diff --git a/auto-scale/gui/src/index.html b/auto-scale/gui/src/index.html
new file mode 100644
index 0000000..51bad93
--- /dev/null
+++ b/auto-scale/gui/src/index.html
@@ -0,0 +1,72 @@
+<!-- browserSync -->
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <title>XOS - Autoscaling Framework</title>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="viewport" content="width=device-width, initial-scale=1, max-scale=1">
+  <!-- bower:css -->
+  <link rel="stylesheet" href="vendor/angular-chart.js/dist/angular-chart.css" />
+  <link rel="stylesheet" href="vendor/bootstrap-css/css/bootstrap.min.css" />
+  <!-- endbower --><!-- endcss -->
+  <!-- inject:css -->
+  <link rel="stylesheet" href="/css/style.css">
+  <!-- endinject -->
+</head>
+<body>
+  
+</body>
+</html>
+
+<div ng-app="autoscaling">
+
+  <nav class="navbar navbar-inverse navbar-fixed-top">
+    <div class="container">
+      <div class="navbar-header">
+        <!-- <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
+          <span class="sr-only">Toggle navigation</span>
+          <span class="icon-bar"></span>
+          <span class="icon-bar"></span>
+          <span class="icon-bar"></span>
+        </button> -->
+        <a class="navbar-brand" href="#">XOS - Autoscaling Framework</a>
+      </div>
+      <!-- <div id="navbar" class="collapse navbar-collapse">
+        <ul class="nav navbar-nav">
+          <li class="active"><a href="#">Home</a></li>
+          <li><a href="#about">About</a></li>
+          <li><a href="#contact">Contact</a></li>
+        </ul>
+      </div><!--/.nav-collapse --> -->
+    </div>
+  </nav>
+  
+  <div class="container">
+    <div class="row">
+      <div class="col-xs-12">
+        <div ui-view ng-class="stateName"></div>
+      </div>
+    </div>
+  </div>
+  <!-- bower:js -->
+  <script src="vendor/angular/angular.js"></script>
+  <script src="vendor/Chart.js/Chart.js"></script>
+  <script src="vendor/angular-chart.js/dist/angular-chart.js"></script>
+  <script src="vendor/angular-animate/angular-animate.js"></script>
+  <script src="vendor/ui.bootstrap/src/accordion/accordion.js"></script>
+  <script src="vendor/ui.bootstrap/src/collapse/collapse.js"></script>
+  <script src="vendor/jquery/dist/jquery.js"></script>
+  <script src="vendor/angular-ui-router/release/angular-ui-router.js"></script>
+  <script src="vendor/ng-lodash/build/ng-lodash.js"></script>
+  <script src="vendor/bootstrap-css/js/bootstrap.min.js"></script>
+  <script src="vendor/angular-mocks/angular-mocks.js"></script>
+  <!-- endbower --><!-- endjs -->
+
+  <!-- inject:js -->
+  <script src="/.tmp/main.js"></script>
+  <script src="/.tmp/autoscaling_details.directive.js"></script>
+  <script src="/.tmp/autoscaling.service.js"></script>
+  <!-- endinject -->
+</div>
+
diff --git a/auto-scale/gui/src/js/autoscaling.service.js b/auto-scale/gui/src/js/autoscaling.service.js
new file mode 100644
index 0000000..2762fe7
--- /dev/null
+++ b/auto-scale/gui/src/js/autoscaling.service.js
@@ -0,0 +1,71 @@
+'use strict';
+
+angular.module('autoscaling')
+.service('Autoscaling', function($http, $interval, $rootScope, lodash, $q){
+
+  const pollingFrequency = 10;
+  var pollinginterval;
+
+  /**
+  * Convert data to a flat array of resources
+  */
+
+  this.formatData = (data) => {
+    const list = [];
+    // cicle trough all slices
+    lodash.map(data, (item) => {
+      // cicle trough every resource
+      item.resources = lodash.forEach(
+        Object.keys(item.resources),
+        (resource) => {
+          const tmp = item.resources[resource];
+          tmp.service = item.service;
+          tmp.slice = item.slice;
+          tmp.project_id = item.project_id;
+          tmp.instance_name = tmp.xos_instance_info.instance_name;
+          delete tmp.xos_instance_info;
+          list.push(tmp);
+        }
+      )
+    });
+    return list;
+  };
+
+  function requestData(url){
+
+    const deferred = $q.defer();
+
+    $http.get(url)
+    .success((res) => {
+      deferred.resolve(res);
+    })
+    .error((e) => {
+      deferred.reject(e);
+    });
+
+    return deferred.promise;
+  };
+
+
+  // TODO Move to Websocket
+  this.getAutoscalingData = () => {
+
+    requestData('/autoscaledata')
+    .then((res) => {
+      $rootScope.$emit('autoscaling.update', this.formatData(res));
+    })
+    .catch((e) => {
+      $rootScope.$emit('autoscaling.error', this.formatData(e));
+    });
+
+    pollinginterval = $interval(() => {
+      requestData('/autoscaledata')
+      .then((res) => {
+        $rootScope.$emit('autoscaling.update', this.formatData(res));
+      })
+      .catch((e) => {
+        $rootScope.$emit('autoscaling.error', this.formatData(e));
+      });
+    }, pollingFrequency * 1000)
+  };
+});
\ No newline at end of file
diff --git a/auto-scale/gui/src/js/autoscaling_details.directive.js b/auto-scale/gui/src/js/autoscaling_details.directive.js
new file mode 100644
index 0000000..76cce2d
--- /dev/null
+++ b/auto-scale/gui/src/js/autoscaling_details.directive.js
@@ -0,0 +1,197 @@
+angular.module('autoscaling')
+.directive('serviceContainer', function(lodash, Autoscaling){
+  return {
+    restrict: 'E',
+    scope: {},
+    bindToController: true,
+    controllerAs: 'vm',
+    templateUrl: 'templates/service-container.tpl.html',
+    controller: function($rootScope) {
+
+      this.loader = true;
+
+      // set to true when a service is manually selected
+      this.manualSelect = false;
+
+      // start polling
+      Autoscaling.getAutoscalingData();
+
+      // list to polling events
+      $rootScope.$on('autoscaling.update', (evt, data) => {
+        
+        if (data.length > 0) {
+          this.loader = false;
+        };
+        this.printData(data);
+      });
+
+      // handle errors
+      $rootScope.$on('autoscaling.error', (evt, err) => {
+        this.loader = false;
+        this.error = err.data.message;
+      });
+
+      /**
+      * Group resources by service and slice
+      */
+      this.printData = (data) => {
+        this.services = lodash.groupBy(data, 'service');
+        lodash.forEach(Object.keys(this.services), (service) => {
+          this.services[service] = lodash.groupBy(this.services[service], 'slice');
+          lodash.forEach(Object.keys(this.services[service]), (slice) => {
+            // grouping instance by name
+            this.services[service][slice] = lodash.groupBy(this.services[service][slice], 'instance_name');
+            // instance can't have the same name,
+            // so take them out of an array
+            // and keep only the sample data
+            lodash.forEach(Object.keys(this.services[service][slice]), (instance) => {
+              // TODO maintain the instance order
+              this.services[service][slice][instance] = this.services[service][slice][instance][0].queue;
+            });
+            
+          })
+        });
+        // arbitrary set the first service in the list as the selected one
+        if(!this.manualSelect){
+          this.serviceName = Object.keys(this.services)[0];
+          this.selectedService = this.services[Object.keys(this.services)[0]];
+        }
+        else{
+          this.selectedService = this.services[this.serviceName]
+        }
+      };
+
+      /**
+      * Change the current selected service
+      */
+     
+      this.selectService = (serviceName) => {
+        this.serviceName = serviceName;
+        this.selectedService = this.services[serviceName];
+        this.manualSelect = true;
+      };
+    }
+  };
+})
+.directive('serviceDetail', function(lodash){
+  return {
+    restrict: 'E',
+    scope: {
+      service: '=service'
+    },
+    bindToController: true,
+    controllerAs: 'vm',
+    templateUrl: 'templates/service-detail.tpl.html',
+    controller: function($scope) {
+
+    }
+  };
+})
+.directive('sliceDetail', function(lodash){
+  return {
+    restrict: 'E',
+    scope: {
+      instances: '=instances'
+    },
+    bindToController: true,
+    controllerAs: 'vm',
+    templateUrl: 'templates/slice-detail.tpl.html',
+    controller: function($scope, $timeout) {
+
+      this.chart = {
+        options: {
+          datasetFill: false,
+          animation: true,
+          // animationEasing: 'easeInBack'
+        }
+      };
+
+      this.chartColors = [
+        '#286090',
+        '#F7464A',
+        '#46BFBD',
+        '#FDB45C',
+        '#97BBCD',
+        '#4D5360',
+        '#8c4f9f'
+      ];
+
+      Chart.defaults.global.colours = this.chartColors;
+
+      /**
+      * Goes trough the array and format date to be used as labels
+      *
+      * @param Array data
+      * @returns Array a list of labels
+      */
+
+      this.getLabels = (data) => {
+        // we should compare the  labels and get the last available
+        return this.prependValues(
+          data.reduce((list, item) => {
+            let date = new Date(item.timestamp);
+            list.push(`${date.getHours()}:${(date.getMinutes()<10?'0':'') + date.getMinutes()}:${date.getSeconds()}`);
+            return list;
+          }, [])
+        , '');
+      };
+
+      /**
+      * Prepend value if the array is less than 10 element
+      */
+      this.prependValues = (list, value) => {
+        if(list.length < 10){
+          list.unshift(value);
+          // call itself to check again
+          return this.prependValues(list, value);
+        }
+        return list;
+      }
+
+      /**
+      * Convert an object of array,
+      * in an array of arrays of values
+      */
+      this.getData = (data, instanceNames) => {
+        return lodash.map(instanceNames, (item) => {
+          return this.prependValues(lodash.reduce(data[item], (list, sample) => {
+            // console.log(data[item], sample);
+            list.push(sample.counter_volume);
+            return list;
+          }, []), null);
+        });
+      };
+
+      this.getMostRecentSeries = (instances) => {
+        // console.log(instances);
+        const newestValues = [];
+        instances = lodash.toArray(instances)
+        lodash.forEach(instances, (values) => {
+          newestValues.push(lodash.max(values, item => new Date(item.timestamp)));
+        });
+
+        var highestValue = 0;
+        var newestInstanceIndex = lodash.findIndex(newestValues, (val) => {
+          return new Date(val.timestamp) > highestValue;
+        });
+
+        return instances[newestInstanceIndex]
+      }
+
+      this.drawChart = (data) => {
+
+        const instanceNames = Object.keys(data);
+
+        this.chart.labels = this.getLabels(this.getMostRecentSeries(data));
+        this.chart.series = instanceNames;
+        this.chart.data = this.getData(data, instanceNames);
+      }
+
+      $scope.$watch(() => this.instances, (val) => {
+        $timeout(()=>{this.chart.options.animation = false}, 1000);
+        this.drawChart(val)
+      });
+
+    }
+  };
+});
\ No newline at end of file
diff --git a/auto-scale/gui/src/js/main.js b/auto-scale/gui/src/js/main.js
new file mode 100644
index 0000000..468f355
--- /dev/null
+++ b/auto-scale/gui/src/js/main.js
@@ -0,0 +1,17 @@
+'use strict';
+
+angular.module('autoscaling', [
+  'ngLodash',
+  'ui.router',
+  'ngAnimate',
+  'chart.js'
+])
+.config(($stateProvider, $urlRouterProvider) => {
+  $stateProvider
+  .state('ceilometerDashboard', {
+    url: '/',
+    template: '<service-container></service-container>'
+  });
+
+  $urlRouterProvider.otherwise('/');
+});
diff --git a/auto-scale/gui/src/mocks/mock.json b/auto-scale/gui/src/mocks/mock.json
new file mode 100644
index 0000000..aa91dd2
--- /dev/null
+++ b/auto-scale/gui/src/mocks/mock.json
@@ -0,0 +1 @@
+[{"slice": "mysite_onos_volt", "service": "service_ONOS_vOLT", "lthreadshold_count": 1, "alarm": "scale_down_eval", "uthreadshold_count": 0, "project_id": "bfef8341327245d682c7bada50aceecb", "resources": {"71863bc9-1840-4014-9a7c-fee8d94d3f77": {"queue": [{"counter_name": "cpu_util", "resource_id": "71863bc9-1840-4014-9a7c-fee8d94d3f77", "timestamp": "2015-12-16T23:44:02Z", "counter_unit": "%", "counter_volume": 10.6, "project_id": "bfef8341327245d682c7bada50aceecb"}, {"counter_name": "cpu_util", "resource_id": "71863bc9-1840-4014-9a7c-fee8d94d3f77", "timestamp": "2015-12-16T23:44:12Z", "counter_unit": "%", "counter_volume": 11.1, "project_id": "bfef8341327245d682c7bada50aceecb"}, {"counter_name": "cpu_util", "resource_id": "71863bc9-1840-4014-9a7c-fee8d94d3f77", "timestamp": "2015-12-16T23:44:22Z", "counter_unit": "%", "counter_volume": 10.799999999999999, "project_id": "bfef8341327245d682c7bada50aceecb"}, {"counter_name": "cpu_util", "resource_id": "71863bc9-1840-4014-9a7c-fee8d94d3f77", "timestamp": "2015-12-16T23:44:32Z", "counter_unit": "%", "counter_volume": 9.9, "project_id": "bfef8341327245d682c7bada50aceecb"}, {"counter_name": "cpu_util", "resource_id": "71863bc9-1840-4014-9a7c-fee8d94d3f77", "timestamp": "2015-12-16T23:44:42Z", "counter_unit": "%", "counter_volume": 11.2, "project_id": "bfef8341327245d682c7bada50aceecb"}, {"counter_name": "cpu_util", "resource_id": "71863bc9-1840-4014-9a7c-fee8d94d3f77", "timestamp": "2015-12-16T23:44:52Z", "counter_unit": "%", "counter_volume": 11.1, "project_id": "bfef8341327245d682c7bada50aceecb"}], "xos_instance_info": {"instance_name": "mysite_onos_volt-4"}}}}, {"slice": "mysite_onos_vbng", "service": "service_ONOS_vBNG", "lthreadshold_count": 1, "alarm": "scale_down_eval", "uthreadshold_count": 0, "project_id": "7c918e6765c24ee281f3ee8692fd102c", "resources": {"4065c7d0-62bc-486a-ad3e-87603d2ab33b": {"queue": [{"counter_name": "cpu_util", "resource_id": "4065c7d0-62bc-486a-ad3e-87603d2ab33b", "timestamp": "2015-12-16T23:44:02Z", "counter_unit": "%", "counter_volume": 9.7, "project_id": "7c918e6765c24ee281f3ee8692fd102c"}, {"counter_name": "cpu_util", "resource_id": "4065c7d0-62bc-486a-ad3e-87603d2ab33b", "timestamp": "2015-12-16T23:44:12Z", "counter_unit": "%", "counter_volume": 11.5, "project_id": "7c918e6765c24ee281f3ee8692fd102c"}, {"counter_name": "cpu_util", "resource_id": "4065c7d0-62bc-486a-ad3e-87603d2ab33b", "timestamp": "2015-12-16T23:44:22Z", "counter_unit": "%", "counter_volume": 12.399999999999999, "project_id": "7c918e6765c24ee281f3ee8692fd102c"}, {"counter_name": "cpu_util", "resource_id": "4065c7d0-62bc-486a-ad3e-87603d2ab33b", "timestamp": "2015-12-16T23:44:32Z", "counter_unit": "%", "counter_volume": 11.299999999999999, "project_id": "7c918e6765c24ee281f3ee8692fd102c"}, {"counter_name": "cpu_util", "resource_id": "4065c7d0-62bc-486a-ad3e-87603d2ab33b", "timestamp": "2015-12-16T23:44:42Z", "counter_unit": "%", "counter_volume": 11.799999999999999, "project_id": "7c918e6765c24ee281f3ee8692fd102c"}, {"counter_name": "cpu_util", "resource_id": "4065c7d0-62bc-486a-ad3e-87603d2ab33b", "timestamp": "2015-12-16T23:44:52Z", "counter_unit": "%", "counter_volume": 12.299999999999999, "project_id": "7c918e6765c24ee281f3ee8692fd102c"}], "xos_instance_info": {"instance_name": "mysite_onos_vbng-2"}}}}, {"slice": "mysite_vcpe", "service": "service_vcpe", "lthreadshold_count": 1, "alarm": "scale_down_eval", "uthreadshold_count": 0, "project_id": "61a5d4b37b5d43718854916079760c0d", "resources": {"41625531-8243-4471-b435-574618df0484": {"queue": [{"counter_name": "cpu_util", "resource_id": "41625531-8243-4471-b435-574618df0484", "timestamp": "2015-12-16T23:44:02Z", "counter_unit": "%", "counter_volume": 0.09999999999999999, "project_id": "61a5d4b37b5d43718854916079760c0d"}, {"counter_name": "cpu_util", "resource_id": "41625531-8243-4471-b435-574618df0484", "timestamp": "2015-12-16T23:44:12Z", "counter_unit": "%", "counter_volume": 0.0, "project_id": "61a5d4b37b5d43718854916079760c0d"}, {"counter_name": "cpu_util", "resource_id": "41625531-8243-4471-b435-574618df0484", "timestamp": "2015-12-16T23:44:22Z", "counter_unit": "%", "counter_volume": 0.09999999999999999, "project_id": "61a5d4b37b5d43718854916079760c0d"}, {"counter_name": "cpu_util", "resource_id": "41625531-8243-4471-b435-574618df0484", "timestamp": "2015-12-16T23:44:32Z", "counter_unit": "%", "counter_volume": 0.0, "project_id": "61a5d4b37b5d43718854916079760c0d"}, {"counter_name": "cpu_util", "resource_id": "41625531-8243-4471-b435-574618df0484", "timestamp": "2015-12-16T23:44:42Z", "counter_unit": "%", "counter_volume": 0.09999999999999999, "project_id": "61a5d4b37b5d43718854916079760c0d"}, {"counter_name": "cpu_util", "resource_id": "41625531-8243-4471-b435-574618df0484", "timestamp": "2015-12-16T23:44:52Z", "counter_unit": "%", "counter_volume": 0.09999999999999999, "project_id": "61a5d4b37b5d43718854916079760c0d"}], "xos_instance_info": {"instance_name": "mysite_vcpe-7"}}}}, {"slice": "mysite_volt", "service": null, "lthreadshold_count": 1, "alarm": "scale_down_eval", "uthreadshold_count": 0, "project_id": "f506380a49a24389ae0d8469274e3279", "resources": {"9452c9e2-e358-4302-ba79-0d19b7b9be84": {"queue": [{"counter_name": "cpu_util", "resource_id": "9452c9e2-e358-4302-ba79-0d19b7b9be84", "timestamp": "2015-12-16T23:44:02Z", "counter_unit": "%", "counter_volume": 0.09999999999999999, "project_id": "f506380a49a24389ae0d8469274e3279"}, {"counter_name": "cpu_util", "resource_id": "9452c9e2-e358-4302-ba79-0d19b7b9be84", "timestamp": "2015-12-16T23:44:12Z", "counter_unit": "%", "counter_volume": 0.09999999999999999, "project_id": "f506380a49a24389ae0d8469274e3279"}, {"counter_name": "cpu_util", "resource_id": "9452c9e2-e358-4302-ba79-0d19b7b9be84", "timestamp": "2015-12-16T23:44:22Z", "counter_unit": "%", "counter_volume": 0.09999999999999999, "project_id": "f506380a49a24389ae0d8469274e3279"}, {"counter_name": "cpu_util", "resource_id": "9452c9e2-e358-4302-ba79-0d19b7b9be84", "timestamp": "2015-12-16T23:44:32Z", "counter_unit": "%", "counter_volume": 0.09999999999999999, "project_id": "f506380a49a24389ae0d8469274e3279"}, {"counter_name": "cpu_util", "resource_id": "9452c9e2-e358-4302-ba79-0d19b7b9be84", "timestamp": "2015-12-16T23:44:42Z", "counter_unit": "%", "counter_volume": 0.09999999999999999, "project_id": "f506380a49a24389ae0d8469274e3279"}, {"counter_name": "cpu_util", "resource_id": "9452c9e2-e358-4302-ba79-0d19b7b9be84", "timestamp": "2015-12-16T23:44:52Z", "counter_unit": "%", "counter_volume": 0.0, "project_id": "f506380a49a24389ae0d8469274e3279"}], "xos_instance_info": {"instance_name": "mysite_volt-5"}}}}, {"slice": "mysite_vbng", "service": null, "lthreadshold_count": 1, "alarm": "scale_down_eval", "uthreadshold_count": 0, "project_id": "c92cf450df4640d6952c0276730e5048", "resources": {"40aec721-b7bc-49b2-9e1f-1f2a9005cb41": {"queue": [{"counter_name": "cpu_util", "resource_id": "40aec721-b7bc-49b2-9e1f-1f2a9005cb41", "timestamp": "2015-12-16T23:44:02Z", "counter_unit": "%", "counter_volume": 0.09999999999999999, "project_id": "c92cf450df4640d6952c0276730e5048"}, {"counter_name": "cpu_util", "resource_id": "40aec721-b7bc-49b2-9e1f-1f2a9005cb41", "timestamp": "2015-12-16T23:44:12Z", "counter_unit": "%", "counter_volume": 0.19999999999999998, "project_id": "c92cf450df4640d6952c0276730e5048"}, {"counter_name": "cpu_util", "resource_id": "40aec721-b7bc-49b2-9e1f-1f2a9005cb41", "timestamp": "2015-12-16T23:44:22Z", "counter_unit": "%", "counter_volume": 0.0, "project_id": "c92cf450df4640d6952c0276730e5048"}, {"counter_name": "cpu_util", "resource_id": "40aec721-b7bc-49b2-9e1f-1f2a9005cb41", "timestamp": "2015-12-16T23:44:32Z", "counter_unit": "%", "counter_volume": 0.09999999999999999, "project_id": "c92cf450df4640d6952c0276730e5048"}, {"counter_name": "cpu_util", "resource_id": "40aec721-b7bc-49b2-9e1f-1f2a9005cb41", "timestamp": "2015-12-16T23:44:42Z", "counter_unit": "%", "counter_volume": 0.0, "project_id": "c92cf450df4640d6952c0276730e5048"}, {"counter_name": "cpu_util", "resource_id": "40aec721-b7bc-49b2-9e1f-1f2a9005cb41", "timestamp": "2015-12-16T23:44:52Z", "counter_unit": "%", "counter_volume": 0.09999999999999999, "project_id": "c92cf450df4640d6952c0276730e5048"}], "xos_instance_info": {"instance_name": "mysite_vbng-6"}}}}, {"slice": "mysite_clients", "service": null, "lthreadshold_count": 1, "alarm": "scale_down_eval", "uthreadshold_count": 0, "project_id": "f884c440474b40808a8adcdece5f45ef", "resources": {"036742d1-ff67-4c5b-8bde-58d0fc752b1d": {"queue": [{"counter_name": "cpu_util", "resource_id": "036742d1-ff67-4c5b-8bde-58d0fc752b1d", "timestamp": "2015-12-16T23:44:02Z", "counter_unit": "%", "counter_volume": 0.19999999999999998, "project_id": "f884c440474b40808a8adcdece5f45ef"}, {"counter_name": "cpu_util", "resource_id": "036742d1-ff67-4c5b-8bde-58d0fc752b1d", "timestamp": "2015-12-16T23:44:12Z", "counter_unit": "%", "counter_volume": 0.0, "project_id": "f884c440474b40808a8adcdece5f45ef"}, {"counter_name": "cpu_util", "resource_id": "036742d1-ff67-4c5b-8bde-58d0fc752b1d", "timestamp": "2015-12-16T23:44:22Z", "counter_unit": "%", "counter_volume": 0.09999999999999999, "project_id": "f884c440474b40808a8adcdece5f45ef"}, {"counter_name": "cpu_util", "resource_id": "036742d1-ff67-4c5b-8bde-58d0fc752b1d", "timestamp": "2015-12-16T23:44:32Z", "counter_unit": "%", "counter_volume": 0.09999999999999999, "project_id": "f884c440474b40808a8adcdece5f45ef"}, {"counter_name": "cpu_util", "resource_id": "036742d1-ff67-4c5b-8bde-58d0fc752b1d", "timestamp": "2015-12-16T23:44:42Z", "counter_unit": "%", "counter_volume": 0.0, "project_id": "f884c440474b40808a8adcdece5f45ef"}, {"counter_name": "cpu_util", "resource_id": "036742d1-ff67-4c5b-8bde-58d0fc752b1d", "timestamp": "2015-12-16T23:44:52Z", "counter_unit": "%", "counter_volume": 0.09999999999999999, "project_id": "f884c440474b40808a8adcdece5f45ef"}], "xos_instance_info": {"instance_name": "mysite_clients-3"}}}}, {"slice": "mysite_ceilometer", "service": "service_ceilometer", "lthreadshold_count": 1, "alarm": "scale_down_eval", "uthreadshold_count": 0, "project_id": "920d70bc63574552bbb3c3fb262ee1bc", "resources": {"627f7de4-634a-4205-8eb4-93c40a34e862": {"queue": [{"counter_name": "cpu_util", "resource_id": "627f7de4-634a-4205-8eb4-93c40a34e862", "timestamp": "2015-12-16T23:44:02Z", "counter_unit": "%", "counter_volume": 0.19999999999999998, "project_id": "920d70bc63574552bbb3c3fb262ee1bc"}, {"counter_name": "cpu_util", "resource_id": "627f7de4-634a-4205-8eb4-93c40a34e862", "timestamp": "2015-12-16T23:44:12Z", "counter_unit": "%", "counter_volume": 0.19999999999999998, "project_id": "920d70bc63574552bbb3c3fb262ee1bc"}, {"counter_name": "cpu_util", "resource_id": "627f7de4-634a-4205-8eb4-93c40a34e862", "timestamp": "2015-12-16T23:44:22Z", "counter_unit": "%", "counter_volume": 0.19999999999999998, "project_id": "920d70bc63574552bbb3c3fb262ee1bc"}, {"counter_name": "cpu_util", "resource_id": "627f7de4-634a-4205-8eb4-93c40a34e862", "timestamp": "2015-12-16T23:44:32Z", "counter_unit": "%", "counter_volume": 0.09999999999999999, "project_id": "920d70bc63574552bbb3c3fb262ee1bc"}, {"counter_name": "cpu_util", "resource_id": "627f7de4-634a-4205-8eb4-93c40a34e862", "timestamp": "2015-12-16T23:44:42Z", "counter_unit": "%", "counter_volume": 0.09999999999999999, "project_id": "920d70bc63574552bbb3c3fb262ee1bc"}, {"counter_name": "cpu_util", "resource_id": "627f7de4-634a-4205-8eb4-93c40a34e862", "timestamp": "2015-12-16T23:44:52Z", "counter_unit": "%", "counter_volume": 0.19999999999999998, "project_id": "920d70bc63574552bbb3c3fb262ee1bc"}], "xos_instance_info": {"instance_name": "mysite_ceilometer-8"}}}}]
\ No newline at end of file
diff --git a/auto-scale/gui/src/templates/service-container.tpl.html b/auto-scale/gui/src/templates/service-container.tpl.html
new file mode 100644
index 0000000..34cdcca
--- /dev/null
+++ b/auto-scale/gui/src/templates/service-container.tpl.html
@@ -0,0 +1,26 @@
+<div class="row">
+  <div class="col-xs-12">
+    <h1>Service detail</h1>
+  </div>
+</div>
+<div class="row">
+  <div class="col-sm-12" ng-show="vm.loader">
+    <div class="loader"></div>
+  </div>
+  <div class="col-sm-3">
+    <ul class="list-group">
+      <li class="list-group-item" ng-class="{active: vm.serviceName == service}" ng-repeat="(service, slices) in vm.services">
+        <a href="" ng-click="vm.selectService(service)">{{service}}</a>
+      </li>
+    </ul>
+  </div>
+
+  <div class="col-sm-9 repeat-container" ng-show="!vm.error">
+    <service-detail service="vm.selectedService"></service-detail>
+  </div>
+  <div class="col-sm-9" ng-show="vm.error">
+    <div class="alert alert-danger">
+      {{vm.error}}
+    </div>
+  </div>
+</div>
\ No newline at end of file
diff --git a/auto-scale/gui/src/templates/service-detail.tpl.html b/auto-scale/gui/src/templates/service-detail.tpl.html
new file mode 100644
index 0000000..f0e3636
--- /dev/null
+++ b/auto-scale/gui/src/templates/service-detail.tpl.html
@@ -0,0 +1,8 @@
+<div class="animate-repeat panel panel-default" ng-repeat="(slice, instances) in vm.service">
+  <div class="panel-heading">
+    <h3 class="panel-title">{{slice}}</h3>
+  </div>
+  <div class="panel-body">
+    <slice-detail instances="instances"></slice-detail>
+  </div>
+</div>
\ No newline at end of file
diff --git a/auto-scale/gui/src/templates/slice-detail.tpl.html b/auto-scale/gui/src/templates/slice-detail.tpl.html
new file mode 100644
index 0000000..6e63d5b
--- /dev/null
+++ b/auto-scale/gui/src/templates/slice-detail.tpl.html
@@ -0,0 +1,4 @@
+<canvas id="line" class="chart chart-line" chart-data="vm.chart.data"
+  chart-labels="vm.chart.labels" chart-legend="true" chart-series="vm.chart.series" 
+  chart-options="vm.chart.options">
+</canvas>
\ No newline at end of file
diff --git a/auto-scale/xos_auto_scaling_app.py b/auto-scale/xos_auto_scaling_app.py
new file mode 100644
index 0000000..848ccc0
--- /dev/null
+++ b/auto-scale/xos_auto_scaling_app.py
@@ -0,0 +1,333 @@
+import socket
+import requests
+import urllib2
+import json
+import msgpack
+import collections
+import time, thread, threading
+
+from flask import request, Request, jsonify
+from flask import Flask
+from flask import make_response
+app = Flask(__name__)
+
+projects_map = {}
+xos_tenant_info_map = {}
+xos_instances_info_map = {}
+
+use_kafka = True
+
+if use_kafka:
+   import kafka
+   from kafka import TopicPartition
+else:
+   UDP_IP = "0.0.0.0"
+   UDP_PORT = 12346
+
+@app.route('/autoscaledata',methods=['GET'])
+def autoscaledata():
+    response = app.make_response(json.dumps(projects_map.values()))
+    response.mimetype="application/json"
+    return response
+
+def acquire_xos_monitoring_channel():
+    url = "http://ctl:9999/xoslib/monitoringchannel/"
+    admin_auth=("padmin@vicci.org", "letmein")   # use your XOS username and password
+    monitoring_channels = requests.get(url, auth=admin_auth).json()
+    ceilometer_url = None
+    if not monitoring_channels:
+        print 'SRIKANTH: No monitoring channels for this user...'
+        return None
+    else:
+        monitoring_channel = monitoring_channels[0]
+    while not monitoring_channel['ceilometer_url']:
+         print 'SRIKANTH: Waiting for monitoring channel create'
+         sleep(0.5)
+         monitoring_channel = requests.get(url, auth=admin_auth).json()[0]
+    #TODO: Wait until URL is completely UP
+    while True:
+        print 'SRIKANTH: Waiting for ceilometer proxy URL %s is available' % monitoring_channel['ceilometer_url']
+        try:
+            response = urllib2.urlopen(monitoring_channel['ceilometer_url'],timeout=1)
+            break
+        except urllib2.HTTPError, e:
+            print 'SRIKANTH: HTTP error %s' % e.reason
+            break
+        except urllib2.URLError, e:
+            print 'SRIKANTH: URL error %s' % e.reason
+            pass
+    return monitoring_channel
+
+def print_samples():
+   print ""
+   print ""
+   for project in projects_map.keys():
+        print "service=%s slice=%s, alarm_state=%s" % (projects_map[project]['service'], projects_map[project]['slice'] if projects_map[project]['slice'] else project, projects_map[project]['alarm'])
+        for resource in projects_map[project]['resources'].keys():
+             print "resource=%s" % (projects_map[project]['resources'][resource]['xos_instance_info']['instance_name'] if projects_map[project]['resources'][resource]['xos_instance_info'] else resource)
+             for i in projects_map[project]['resources'][resource]['queue']:
+                  print "    time=%s val=%s" % ( i['timestamp'],i['counter_volume'])
+
+def periodic_print():
+     print_samples()
+     #Print every 1minute
+     threading.Timer(20, periodic_print).start()
+
+
+CPU_UPPER_THRESHOLD = 80 #80%
+CPU_LOWER_THRESHOLD = 30 #30%
+CPU_THRESHOLD_REPEAT = 3
+INITIAL_STATE = 'normal_config'
+SCALE_UP_EVALUATION = 'scale_up_eval'
+SCALE_DOWN_EVALUATION = 'scale_down_eval'
+SCALE_UP_ALARM = 'scale_up'
+SCALE_DOWN_ALARM = 'scale_down'
+
+def loadAllXosTenantInfo():
+    print "SRIKANTH: Loading all XOS tenant info"
+    url = "http://ctl:9999/xos/controllerslices/"
+    admin_auth=("padmin@vicci.org", "letmein")   # use your XOS username and password
+    controller_slices = requests.get(url, auth=admin_auth).json()
+    for cslice in controller_slices:
+         slice = requests.get(cslice['slice'], auth=admin_auth).json()
+         slice_name = slice['humanReadableName']
+         if slice['service']:
+             service = requests.get(slice['service'], auth=admin_auth).json()
+             service_name = service['humanReadableName']
+         else:
+             service_name = None
+         xos_tenant_info_map[cslice['tenant_id']] = {'service':service_name, 'slice':slice_name}
+         print "SRIKANTH: Project: %s Service:%s Slice:%s" % (cslice['tenant_id'],service_name,slice_name)
+
+def loadAllXosInstanceInfo():
+    print "SRIKANTH: Loading all XOS instance info"
+    url = "http://ctl:9999/xos/instances/"
+    admin_auth=("padmin@vicci.org", "letmein")   # use your XOS username and password
+    xos_instances = requests.get(url, auth=admin_auth).json()
+    for instance in xos_instances:
+         xos_instances_info_map[instance['instance_uuid']] = {'instance_name':instance['instance_name']}
+
+def getXosTenantInfo(project):
+    xos_tenant_info = xos_tenant_info_map.get(project, None)
+    if xos_tenant_info:
+        return xos_tenant_info
+    else:
+        loadAllXosTenantInfo()
+        xos_tenant_info = xos_tenant_info_map.get(project, None)
+        if not xos_tenant_info:
+            print "SRIKANTH: Project %s has no associated XOS slice" % project
+        return xos_tenant_info
+
+def getXosInstanceInfo(resource):
+    xos_instance_info = xos_instances_info_map.get(resource, None)
+    if xos_instance_info:
+        return xos_instance_info
+    else:
+        loadAllXosInstanceInfo()
+        xos_instance_info = xos_instances_info_map.get(resource, None)
+        if not xos_instance_info:
+            print "SRIKANTH: Resource %s has no associated XOS instance" % project
+        return xos_instance_info
+
+def handle_adjust_scale(project, adjust):
+    if (adjust != 'up') and (adjust != 'down'):
+        print "SRIKANTH: Invalid adjust value %s " % adjust
+        return
+    current_instances = len(projects_map[project]['resources'].keys())
+    if (current_instances <=1 and adjust == 'down'):
+        print "SRIKANTH: %s is running with already minimum instances and can not scale down further " % project
+        return
+    if (current_instances >=2 and adjust == 'up'):
+        print "SRIKANTH: %s is running with already maximum instances and can not scale up further " % project
+        return
+    #xos_tenant = getXosTenantInfo(project)
+    xos_service = projects_map[project]['service']
+    xos_slice = projects_map[project]['slice']
+    if not xos_service or not xos_slice: 
+        print "SRIKANTH: Can not handle adjust_scale for Project %s because not associated with any service or slice" % project
+        return
+    print "SRIKANTH: SCALE %s for Project %s, Slice=%s, Service=%s from current=%d to new=%d" % (adjust, project, xos_slice, xos_service, current_instances, current_instances+1 if (adjust=='up') else current_instances-1)
+    query_params = {'service':xos_service, 'slice_hint':xos_slice, 'scale':current_instances+1 if (adjust=='up') else current_instances-1}
+    url = "http://ctl:9999/xoslib/serviceadjustscale/"
+    admin_auth=("padmin@vicci.org", "letmein")   # use your XOS username and password
+    response = requests.get(url, params=query_params, auth=admin_auth).json()
+    print "SRIKANTH: XOS adjust_scale response: %s" % response
+
+def periodic_cpu_threshold_evaluator():
+     for project in projects_map.keys():
+          aggregate_cpu_util = sum([resource['queue'][-1]['counter_volume'] \
+                                     for resource in projects_map[project]['resources'].values()]) \
+                                     /len(projects_map[project]['resources'].keys())
+
+          if (projects_map[project]['alarm'] == INITIAL_STATE or
+              projects_map[project]['alarm'] == SCALE_UP_ALARM or
+              projects_map[project]['alarm'] == SCALE_DOWN_ALARM):
+              if aggregate_cpu_util > CPU_UPPER_THRESHOLD:
+                  projects_map[project]['uthreadshold_count'] = 1
+                  projects_map[project]['alarm'] = SCALE_UP_EVALUATION
+                  if projects_map[project]['uthreadshold_count'] >= CPU_THRESHOLD_REPEAT:
+                      projects_map[project]['alarm'] = SCALE_UP_ALARM
+                      handle_adjust_scale(project, 'up')
+              elif aggregate_cpu_util < CPU_LOWER_THRESHOLD:
+                  projects_map[project]['lthreadshold_count'] = 1
+                  projects_map[project]['alarm'] = SCALE_DOWN_EVALUATION
+                  if projects_map[project]['lthreadshold_count'] >= CPU_THRESHOLD_REPEAT:
+                      projects_map[project]['alarm'] = SCALE_DOWN_ALARM
+                      handle_adjust_scale(project, 'down')
+              else:
+                  projects_map[project]['uthreadshold_count'] = 0
+                  projects_map[project]['lthreadshold_count'] = 0
+                  projects_map[project]['alarm'] = INITIAL_STATE
+          elif projects_map[project]['alarm'] == SCALE_UP_EVALUATION:
+              if aggregate_cpu_util > CPU_UPPER_THRESHOLD:
+                  projects_map[project]['uthreadshold_count'] += 1
+                  if projects_map[project]['uthreadshold_count'] >= CPU_THRESHOLD_REPEAT:
+                      projects_map[project]['alarm'] = SCALE_UP_ALARM
+                      handle_adjust_scale(project, 'up')
+              elif aggregate_cpu_util < CPU_LOWER_THRESHOLD:
+                  projects_map[project]['lthreadshold_count'] += 1
+                  projects_map[project]['alarm'] = SCALE_DOWN_EVALUATION
+              else:
+                  projects_map[project]['uthreadshold_count'] = 0
+                  projects_map[project]['alarm'] = INITIAL_STATE
+          elif projects_map[project]['alarm'] == SCALE_DOWN_EVALUATION:
+              if aggregate_cpu_util < CPU_LOWER_THRESHOLD:
+                  projects_map[project]['lthreadshold_count'] += 1
+                  if projects_map[project]['lthreadshold_count'] >= CPU_THRESHOLD_REPEAT:
+                      projects_map[project]['alarm'] = SCALE_DOWN_ALARM
+                      handle_adjust_scale(project, 'down')
+              elif aggregate_cpu_util > CPU_UPPER_THRESHOLD:
+                  projects_map[project]['uthreadshold_count'] += 1
+                  projects_map[project]['alarm'] = SCALE_UP_EVALUATION
+              else:
+                  projects_map[project]['lthreadshold_count'] = 0
+                  projects_map[project]['alarm'] = INITIAL_STATE
+     threading.Timer(20, periodic_cpu_threshold_evaluator).start()
+
+def read_notification_from_ceilometer_over_kafka(host,port,topic):
+    print "Kafka target" , host, port, topic
+    try :
+        consumer=kafka.KafkaConsumer(bootstrap_servers=["%s:%s" % (host,port)])
+        consumer.assign([TopicPartition(topic,0)])
+        consumer.seek_to_end()
+        for message in consumer:
+            #print message.value
+            #logging.debug("%s",message.value)
+            process_notification_from_ceilometer(json.loads(message.value))
+            #status = process_ceilometer_message(json.loads(message.value),message.value)
+            #print status
+    except Exception as e:
+        print "AUTO_SCALE Exception:",e
+
+def read_notification_from_ceilometer(host,port):
+   udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
+   udp.bind((host, port))
+
+   while True:
+      data, source = udp.recvfrom(64000)
+      try:
+         sample = msgpack.loads(data, encoding='utf-8')
+         process_notification_from_ceilometer(sample)
+      except Exception as e:
+         print e
+
+def process_notification_from_ceilometer(sample):
+         if sample['counter_name'] == 'instance':
+             if 'delete' in sample['resource_metadata']['event_type']:
+	          xosTenantInfo = getXosTenantInfo(sample['project_id'])
+                  xosResourceInfo = getXosInstanceInfo(sample['resource_id'])
+                  print "SRIKANTH: Project %s Instance %s is getting deleted" % (xosTenantInfo['slice'] if xosTenantInfo['slice'] else sample['project_id'],xosResourceInfo) 
+                  if sample['project_id'] not in projects_map.keys():
+                       return
+                  if sample['resource_id'] not in projects_map[sample['project_id']]['resources'].keys():
+                       return
+                  projects_map[sample['project_id']]['resources'].pop(sample['resource_id'], None)
+             return
+         elif sample['counter_name'] != 'cpu_util':
+              return
+         if sample['project_id'] not in projects_map.keys():
+              projects_map[sample['project_id']] = {}
+	      xosTenantInfo = getXosTenantInfo(sample['project_id'])
+              projects_map[sample['project_id']]['project_id'] = sample['project_id']
+              projects_map[sample['project_id']]['slice'] = xosTenantInfo['slice']
+              projects_map[sample['project_id']]['service'] = xosTenantInfo['service']
+              projects_map[sample['project_id']]['resources'] = {}
+              projects_map[sample['project_id']]['uthreadshold_count'] = 0
+              projects_map[sample['project_id']]['lthreadshold_count'] = 0
+              projects_map[sample['project_id']]['alarm'] = INITIAL_STATE
+         resource_map = projects_map[sample['project_id']]['resources']
+         if sample['resource_id'] not in resource_map.keys():
+              resource_map[sample['resource_id']] = {}
+              resource_map[sample['resource_id']]['xos_instance_info'] = getXosInstanceInfo(sample['resource_id'])
+              resource_map[sample['resource_id']]['queue'] = []
+         samples_queue = resource_map[sample['resource_id']]['queue']
+         sample = {'counter_name':sample['counter_name'],
+                   'project_id':sample['project_id'],
+                   'resource_id':sample['resource_id'],
+                   'timestamp':sample['timestamp'],
+                   'counter_unit':sample['counter_unit'],
+                   'counter_volume':sample['counter_volume']}
+         deque = collections.deque(samples_queue, maxlen=10)
+         deque.append(sample)
+         resource_map[sample['resource_id']]['queue'] = list(deque)
+
+def setup_webserver():
+    try:
+        #config = ConfigParser.ConfigParser()
+        #config.read('pub_sub.conf')
+        #webserver_host = config.get('WEB_SERVER','webserver_host')
+        #webserver_port = int (config.get('WEB_SERVER','webserver_port'))
+        #client_host    = config.get('CLIENT','client_host')
+        #client_port    = int (config.get('CLIENT','client_port'))
+ 
+        #log_level    = config.get('LOGGING','level')
+        #log_file       = config.get('LOGGING','filename')
+   
+        #level = LEVELS.get(log_level, logging.NOTSET) 
+        #logging.basicConfig(filename=log_file,format='%(asctime)s %(levelname)s %(message)s',\
+        #            datefmt=_DEFAULT_LOG_DATE_FORMAT,level=level) 
+        webserver_host = '0.0.0.0'
+        webserver_port = 9991
+   
+    except Exception as e:
+        print("* Error in config file:",e.__str__())
+        logging.error("* Error in confing file:%s",e.__str__())
+    else: 
+        app.run(host=webserver_host,port=webserver_port,debug=True, use_reloader=False)
+
+
+def main():
+   monitoring_channel = acquire_xos_monitoring_channel()
+   if not monitoring_channel:
+        print 'SRIKANTH: XOS monitoring_channel is not created... Create it before using this app'
+        return
+   loadAllXosTenantInfo()
+   loadAllXosInstanceInfo()
+   ceilometer_url = monitoring_channel['ceilometer_url']
+   if use_kafka:
+       thread.start_new(read_notification_from_ceilometer_over_kafka, ("10.11.10.1","9092","auto-scale",))
+       subscribe_data = {"sub_info":"cpu_util","app_id":"xos_auto_scale","target":"kafka://10.11.10.1:9092?topic=auto-scale"}
+   else:
+       thread.start_new(read_notification_from_ceilometer,(UDP_IP,UDP_PORT,))
+       subscribe_data = {"sub_info":"cpu_util","app_id":"xos_auto_scale","target":"udp://10.11.10.1:12346"}
+   subscribe_url = ceilometer_url + 'v2/subscribe'
+   response = requests.post(subscribe_url, data=json.dumps(subscribe_data))
+   print 'SRIKANTH: Ceilometer meter "cpu_util" Subscription status:%s' % response.text
+   #TODO: Fix the typo in 'sucess'
+   if (not 'sucess' in response.text) and (not 'already exists' in response.text):
+       print 'SRIKANTH: Ceilometer meter "cpu_util" Subscription unsuccessful...Exiting'
+       return
+   subscribe_data = {"sub_info":"instance","app_id":"xos_auto_scale2","target":"udp://10.11.10.1:12346"}
+   subscribe_url = ceilometer_url + 'v2/subscribe'
+   response = requests.post(subscribe_url, data=json.dumps(subscribe_data))
+   print 'SRIKANTH: Ceilometer meter "instance" Subscription status:%s' % response.text
+   #TODO: Fix the typo in 'sucess'
+   if (not 'sucess' in response.text) and (not 'already exists' in response.text):
+       print 'SRIKANTH: Ceilometer meter "instance"Subscription unsuccessful...Exiting'
+       return
+   periodic_cpu_threshold_evaluator()
+   periodic_print()
+   setup_webserver()
+
+if __name__ == "__main__":
+   main()